XSLT 转换子目录中的多个文件
我创建了一个可以转换单个 XML 文件的 XSLT 文件。但是,我有数百个包含多个 xml 文件的目录。 XSLT 有没有办法转换所有这些文件。我正在使用集合功能来获取所有文件的列表。但是,现在不确定如何应用转换。
这是我的示例 XSLT 文件。基本上,我想循环遍历所有 xml 文件并将模板表应用于单个文件。所有这些转换的输出都需要位于一个平面文本文件中。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://whatever">
<xsl:output method="text" encoding="ISO-8859-1"/>
<xsl:template name="process">
<xsl:variable name="files" select="collection('file:///C:/files/testResults?select=*.xml;recurse=yes')"/>
<xsl:for-each select="$files">
<xsl:if test="(not(contains(document-uri(.), 'SuiteSetUp'))) and (not(contains(document-uri(.), 'SuiteTearDown')))">
<xsl:value-of select="tokenize(document-uri(.), '/')[last()]"></xsl:value-of>
<xsl:apply-templates select="/testResults/result/tables/table[14]">
<xsl:with-param name="title" select="/testResults/rootPath"></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="/testResults/result/tables/table[15]"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="table">
<xsl:param name="testName"></xsl:param>
<xsl:for-each select="row">
<xsl:if test="position() > 2">
<xsl:variable name="choices" select="col[2]"></xsl:variable>
<xsl:if test="contains($choices, 'fail')">
<xsl:value-of select="$testName"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:value-of select="col[1]"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:value-of select="foo:getCorrectChoices(col[2])"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:value-of select="foo:getExpectedChoices(col[2])"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:call-template name="NewLine"/>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="NewLine">
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:function name="foo:getCorrectChoices">
<xsl:param name="content"></xsl:param>
<xsl:analyze-string select="$content" regex="\[(\[.+?\])\] fail">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"></xsl:value-of>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:function name="foo:getExpectedChoices">
<xsl:param name="content"></xsl:param>
<xsl:analyze-string select="$content" regex="fail\(expected \[(\[.+?\])\]">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"></xsl:value-of>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
</xsl:stylesheet>
I have created a XSLT file that can transform a single XML file. However, I have several hundred directories with multiple xml files. Is there a way in XSLT to transform all these files. I am using the collection function to get a list of all files. But, not sure how to apply the transform now.
Here is my example XSLT file. Basically, I want to loop through all the xml files and apply the template table on the individual file. The output of all these transforms needs to be in one single flat text file.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://whatever">
<xsl:output method="text" encoding="ISO-8859-1"/>
<xsl:template name="process">
<xsl:variable name="files" select="collection('file:///C:/files/testResults?select=*.xml;recurse=yes')"/>
<xsl:for-each select="$files">
<xsl:if test="(not(contains(document-uri(.), 'SuiteSetUp'))) and (not(contains(document-uri(.), 'SuiteTearDown')))">
<xsl:value-of select="tokenize(document-uri(.), '/')[last()]"></xsl:value-of>
<xsl:apply-templates select="/testResults/result/tables/table[14]">
<xsl:with-param name="title" select="/testResults/rootPath"></xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="/testResults/result/tables/table[15]"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="table">
<xsl:param name="testName"></xsl:param>
<xsl:for-each select="row">
<xsl:if test="position() > 2">
<xsl:variable name="choices" select="col[2]"></xsl:variable>
<xsl:if test="contains($choices, 'fail')">
<xsl:value-of select="$testName"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:value-of select="col[1]"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:value-of select="foo:getCorrectChoices(col[2])"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:value-of select="foo:getExpectedChoices(col[2])"></xsl:value-of>
<xsl:text>|</xsl:text>
<xsl:call-template name="NewLine"/>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="NewLine">
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:function name="foo:getCorrectChoices">
<xsl:param name="content"></xsl:param>
<xsl:analyze-string select="$content" regex="\[(\[.+?\])\] fail">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"></xsl:value-of>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:function name="foo:getExpectedChoices">
<xsl:param name="content"></xsl:param>
<xsl:analyze-string select="$content" regex="fail\(expected \[(\[.+?\])\]">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"></xsl:value-of>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
</xsl:stylesheet>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这可能是如何处理文件系统子树中的所有 xml 文件的最简单示例(使用 Saxon 中实现的
collection()
函数):当应用于任何 XML 文档时(未使用,忽略) ,此转换将身份规则应用于包含在
C:/Temp
子树中的任何*.xml
文件中的每个 XML 文档。文件系统。要进行更有意义的处理,需要在
inFile
模式下覆盖身份模板。在您的具体情况下,我相信您可以简单地替换:
为
,这会将所需的模板应用于从当前(文档)节点中选择的节点上。
Here is probably the simplest example how to process all the xml files in a file system subtree (using the
collection()
function as implemented in Saxon):When applied on any XML document (not used, ignored), this transformation applies the identity rule to every XML document contained in any of the
*.xml
files in theC:/Temp
subtree of the file system.To do more neaningful processing, one needs to override the identity template -- in the
inFile
mode.In your specific case I believe you can simply replace:
with
and this applies the desired templates on the nodes selected off the current (document) node.
我只是想添加 Dimitre 优秀答案的轻量级版本。如果您的目录中有
文档(根节点),以及
的有效 XSLT 程序,只需将您的顶级模板设置为: this:假设您希望将 URL 作为参数
,在命令行上指定。I just wanted to add a lightweight version of Dimitre's excellent answer. If you have
<foo>
documents (root node) sitting in a directory, and a working XSLT program for<foo>
, simply make your top-level template like this:That's assuming you want the URL as a parameter,
<xsl:param name="my_url"/>
, specified on the command line.