【问题标题】:XSL 2.0 Transform XML files while preserving folder structureXSL 2.0 在保留文件夹结构的同时转换 XML 文件
【发布时间】:2013-06-20 18:54:18
【问题描述】:

我有以下 XSL 将一堆 XML 文件从一种格式转换为另一种格式。 尽管到目前为止我有两个问题尚未解决,但转换工作正常:

1) 首先在转换文件时,我需要调整样式表中的参数以仅针对名称超过 7 个字符的文件;

2) 其次,我需要能够转换所有文件,同时保留源文件的文件夹结构。我想知道是否有办法保留与源文件夹相同的文件夹结构。 所有文件都位于基于字母命名的文件夹中,例如:A、B、C、D、F .... 所以我需要转换文件夹 A 中的所有文件并将它们放在一个名为 A 的新文件夹中。文件是也按字母顺序命名。

这是我的样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/">

<!-- This adds DOCTYPE declaration -->
<xsl:output method="xml" doctype-public="-//OASIS//DTD DITA Glossary//EN"
doctype-system="glossary.dtd" omit-xml-declaration="no" indent="yes"/>

<!-- The below line ensures that all empty space and carriage returns are removed from the title element producing proper file names -->
<xsl:strip-space elements="title"/>

<xsl:param name="files" select="collection('../DITA/B/?select=*.dita;recurse=yes')"/>

<!-- <xsl:variable name="filename" select="concat($files,position(),'topic')" />-->

<xsl:template match="node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">

<xsl:for-each select="$files//topic">
<xsl:if test="string-length(files) &gt; 10">
<!-- not working, the purpose is to drop all the files whose name length is less than two letters -->

<xsl:value-of select="text()" disable-output-escaping="yes"/>
</xsl:if>
<xsl:result-document href="outputDITANEW/B/{title/text()|title/b/text()}.dita">
<glossentry id="{concat('test', generate-id())}">
<glossterm id="{concat('test_title', generate-id())}">
<xsl:value-of select="title"/>
</glossterm>
<glossdef>
<xsl:for-each select="body">
<xsl:apply-templates/>
</xsl:for-each>
</glossdef>
</glossentry>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

谢谢。

【问题讨论】:

    标签: xml xslt dita


    【解决方案1】:

    (a) select=*.dita 实际上是一个伪装成 glob 的正则表达式,您应该可以使用 select=[A-Za-z0-9]{7,}.dita 之类的东西来提高选择性。

    (b) 应用于文件的函数document-uri() 返回输入文件的 URI(如果已知),您应该能够由此构造所需的输出文件名。

    【讨论】:

    • 感谢 Michael,当我尝试上述建议的 select= 时,我收到以下错误:FODC0004: Invalid relative URI "../DITA/A/?select=[A-Z]{7,}.di ...”传递给 collection() 函数。你知道为什么吗?我还没有尝试过 document-uri(),一旦问题 1 得到解决,我会尝试。我正在使用 Saxon-PE 9.5.02 和 oXygen XML v15.0。再次感谢。
    • 抱歉,有像 []{} 这样的特殊字符可能需要进行百分比编码才能将它们包含在 URI 中。您可以使用 encode-for-uri() 来做到这一点。我不知道 Saxon 是否会在另一端成功解码它们,但值得一试。
    • 感谢 Michael,百分比编码对文件名起到了作用。现在我需要解决问题 2,仍然试图弄清楚如何使用关于 document-uri() 的第二个建议。
    【解决方案2】:

    如果您使用的是 Oxygen 并且安装了 DITA 框架,那么您有库 frameworks/dita/DITA/plugins/net.sourceforge.dita4publishers.common.xslt/xsl/lib/relpath_util.xsl

    这个库提供了处理 URL 的函数,并且可以很容易地做一些事情,比如获取输入文档的父路径,计算相对路径等等。所以应该正是您构建结果 URL 所需要的。

    【讨论】:

    • 感谢 DrMacro,任何使用 DITA4Publishers relpath_utility 的实际示例都会有帮助。
    • 如果您查看 relpath_util.xsl 文件中的函数,您会发现它们的名称都很清楚。此外,还有 relpath_util_test.xsl 演示了如何使用各种功能。对于构建新的结果 URL,关键函数是 getParent() 和 newFile()
    猜你喜欢
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多