使用 XSLT 和 Saxon 转换多个 XML 文件
Transform Multiple XML file using XSLT and Saxon
我想使用 Saxon 创建从多个 xml 文件到一个 xml(输出。xml)的转换。 xml 文件将由我的测试工具生成,因此对可用的 xml 数量没有限制。假设在一个文件夹中我有几个文件:
Summaryfile001.xml
Summaryfile002.xml
Detailsfile001.xml
Detailsfile002.xml
SummaryandDetailsAllFiles.html
我只想获取摘要文件。 SummaryFiles001.xml里面:
<SummaryFile>
<testname>file001</testname>
<Error>1</Error>
<test>1</test>
<skipped>1</skipped>
<failures>0</failures>
<dateAndTime>15082015093021</dateAndtime>
</SummaryFile>
我使用 saxon 将 Junit 格式报告转换为一个输出匹配,因此模板:
JUnitFormat.xslt
<xsl:output indent="yes" method="xml"/>
<xsl:param name="fileName" select="'output.xml'" />
<xsl:template match="/">
<xsl:apply-templates mode="inFile" select="collection('file:///C:/Users/Documents/Resultfiles?select=*.xml;recurse=yes')"/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SummaryFile">
<xsl:variable name="testName" select="//SummaryFile/testname"/>
<xsl:variable name="test" select="//SummaryFile/test"/>
<xsl:variable name="Error" select="//SummaryFile/Error"/>
<xsl:variable name="skipped" select="//SummaryFile/skipped"/>
<xsl:variable name="dateAndtime" select="//SummaryResultsFile/dateAndtime"/>
<xsl:variable name="failures" select="//SummaryFile/failures"/>
<testsuites>
<testsuite name="{$testName}"
tests="{$test}"
time="{$dateAndTime}"
failures="{$failures}"
errors="{$Error}"
skipped="{$skipped}">
</testsuite>
</testsuites>
</xsl:template>
但是,当我尝试使用以下命令执行 saxon 时:
java -jar saxon9he.jar -xslt:JUnitTemplate.xslt -s:C:/Users/Documents/Resultfiles -o:Output.xml
我无法进行转换。它说转换失败。我只能对单个 xml 进行转换,但不能对多个 xml 进行转换。所以 xslt 的想法:
1. Look for only Summary Files
2. Get all the data from Summary file.xml
3. Create one output xml contain all summary result file in JUnit format
有人知道我该如何解决这个问题吗?
你是对的。我会在命名模板上调用转换,例如使用 -it:main,而不是提供虚拟源文档,但我认为这不是问题的原因。
我很关心你的说法:"It says transformation failed"。撒克逊人永远不会在不输出有关失败的方式和原因的信息的情况下说出那句话。要么您没有看到该信息,在这种情况下您需要找出原因,要么您没有将其传递给我们,这对您毫无帮助。
我怀疑问题出在您的调用参数 -s:C:/Users/Documents/Resultfiles
上。我认为那是目录的名称,而不是 XML 文件的名称。 Saxon 实际上有能力从命令行处理整个目录(将整个样式表应用到每个文件),但这不是您在这里尝试做的。请改用 -it:main
调用方式。
运行 撒克逊 java -jar saxon9he.jar -xslt:JUnitTemplate.xslt -it:main -o:Output.xml
并将您的代码更改为
<xsl:output indent="yes" method="xml"/>
<xsl:template name="main">
<testsuites>
<xsl:apply-templates select="collection('file:///C:/Users/Documents/Resultfiles?select=Summary*.xml;recurse=yes')/SummaryFile"/>
</testsuites>
</xsl:template>
<xsl:template match="SummaryFile">
<testsuite name="{testname}"
tests="{testname}"
time="{dateAndtime}"
failures="{failures}"
errors="{Error}"
skipped="{skipped}">
</testsuite>
</xsl:template>
我想使用 Saxon 创建从多个 xml 文件到一个 xml(输出。xml)的转换。 xml 文件将由我的测试工具生成,因此对可用的 xml 数量没有限制。假设在一个文件夹中我有几个文件:
Summaryfile001.xml
Summaryfile002.xml
Detailsfile001.xml
Detailsfile002.xml
SummaryandDetailsAllFiles.html
我只想获取摘要文件。 SummaryFiles001.xml里面:
<SummaryFile>
<testname>file001</testname>
<Error>1</Error>
<test>1</test>
<skipped>1</skipped>
<failures>0</failures>
<dateAndTime>15082015093021</dateAndtime>
</SummaryFile>
我使用 saxon 将 Junit 格式报告转换为一个输出匹配,因此模板:
JUnitFormat.xslt
<xsl:output indent="yes" method="xml"/>
<xsl:param name="fileName" select="'output.xml'" />
<xsl:template match="/">
<xsl:apply-templates mode="inFile" select="collection('file:///C:/Users/Documents/Resultfiles?select=*.xml;recurse=yes')"/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SummaryFile">
<xsl:variable name="testName" select="//SummaryFile/testname"/>
<xsl:variable name="test" select="//SummaryFile/test"/>
<xsl:variable name="Error" select="//SummaryFile/Error"/>
<xsl:variable name="skipped" select="//SummaryFile/skipped"/>
<xsl:variable name="dateAndtime" select="//SummaryResultsFile/dateAndtime"/>
<xsl:variable name="failures" select="//SummaryFile/failures"/>
<testsuites>
<testsuite name="{$testName}"
tests="{$test}"
time="{$dateAndTime}"
failures="{$failures}"
errors="{$Error}"
skipped="{$skipped}">
</testsuite>
</testsuites>
</xsl:template>
但是,当我尝试使用以下命令执行 saxon 时:
java -jar saxon9he.jar -xslt:JUnitTemplate.xslt -s:C:/Users/Documents/Resultfiles -o:Output.xml
我无法进行转换。它说转换失败。我只能对单个 xml 进行转换,但不能对多个 xml 进行转换。所以 xslt 的想法:
1. Look for only Summary Files
2. Get all the data from Summary file.xml
3. Create one output xml contain all summary result file in JUnit format
有人知道我该如何解决这个问题吗?
你是对的。我会在命名模板上调用转换,例如使用 -it:main,而不是提供虚拟源文档,但我认为这不是问题的原因。
我很关心你的说法:"It says transformation failed"。撒克逊人永远不会在不输出有关失败的方式和原因的信息的情况下说出那句话。要么您没有看到该信息,在这种情况下您需要找出原因,要么您没有将其传递给我们,这对您毫无帮助。
我怀疑问题出在您的调用参数 -s:C:/Users/Documents/Resultfiles
上。我认为那是目录的名称,而不是 XML 文件的名称。 Saxon 实际上有能力从命令行处理整个目录(将整个样式表应用到每个文件),但这不是您在这里尝试做的。请改用 -it:main
调用方式。
运行 撒克逊 java -jar saxon9he.jar -xslt:JUnitTemplate.xslt -it:main -o:Output.xml
并将您的代码更改为
<xsl:output indent="yes" method="xml"/>
<xsl:template name="main">
<testsuites>
<xsl:apply-templates select="collection('file:///C:/Users/Documents/Resultfiles?select=Summary*.xml;recurse=yes')/SummaryFile"/>
</testsuites>
</xsl:template>
<xsl:template match="SummaryFile">
<testsuite name="{testname}"
tests="{testname}"
time="{dateAndtime}"
failures="{failures}"
errors="{Error}"
skipped="{skipped}">
</testsuite>
</xsl:template>