如何解决使用 Saxon 和 xslt 样式表合并两个 xml 文件并获得一个 xml 输出
我想使用 Saxon 创建从多个 xml 文件到仅一个 xml (Output.xml) 的转换。 xml 文件将由我的软件(Vector CANoe)提供的特定 merge.xslt 文件生成。假设在一个文件夹中我有几个文件:
test_InitStartOP_report0001.xml
test_InitStartOP_report0002.xml
test_InitStartOP_report0003.xml
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Merge list of XML reports to one single report -->
<!-- merge.xslt -->
<!-- Version 1.2 -->
<!-- (c) 2005 Vector informatik GmbH,Stuttgart -->
<xsl:output method="xml" version="1.0" encoding="utf-8" standalone="yes"/>
<xsl:template match="/">
<testmodule starttime="-" timestamp="-">
<xsl:apply-templates select="//testmodule" />
<xsl:variable name="testmoduleresult">
<xsl:choose>
<xsl:when test="//testmodule/verdict/@result='fail'">fail</xsl:when>
<xsl:otherwise>pass</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<verdict time="-" timestamp="-" endtime="-" endtimestamp="-" result='{$testmoduleresult}' />
<title>Test Report</title>
<xsl:apply-templates select="//testmodule[1]/engineer|//testmodule[1]/testsetup|//testmodule[1]/sut|//testmodule[1]/hardware" />
<xsl:apply-templates select="//testmodule/miscinfo|//testmodule/extendedinfo" />
</testmodule>
</xsl:template>
<xsl:template match="testmodule">
<testgroup>
<xsl:apply-templates select="preparation|completion|testgroup|testcase|skipped|violation|moduledetails|externalref" />
<xsl:copy-of select="title" />
<xsl:copy-of select="description" />
<!-- Write test module information -->
<xsl:if test="testsetup">
<xsl:for-each select="testsetup/xinfo|testsetup/info">
<xsl:if test="local-name(.) != 'xinfo' or (name != 'Version' and name != 'Configuration' and name != 'Konfiguration' and name != 'Configuration Comment' and name != 'Konfigurationskommentar' and name != 'Windows Computer Name' and name != 'Windows Computer-Name' and not(starts-with(name,'Nodelayer Module')) and not(starts-with(name,'Nodelayer-Modul')))">
<xsl:apply-templates select="." mode="tminfo" />
</xsl:if>
</xsl:for-each>
</xsl:if>
</testgroup>
</xsl:template>
<xsl:template match="info" mode="tminfo">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="xinfo" mode="tminfo">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="preparation">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="completion">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="testgroup">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="testcase">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="skipped">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="violation">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="moduledetails">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="miscinfo">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="extendedinfo">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="engineer">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="hardware">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="externalref">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="testsetup">
<testsetup>
<xsl:for-each select="xinfo">
<xsl:if test="name = 'Version' or name = 'Configuration' or name = 'Konfiguration' or name = 'Configuration Comment' or name = 'Konfigurationskommentar' or name = 'Windows Computer Name' or name = 'Windows Computer-Name' or starts-with(name,'Nodelayer Module') or starts-with(name,'Nodelayer-Modul')">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</testsetup>
</xsl:template>
<xsl:template match="sut">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
我尝试使用此 cmd 行在 Cmd 中使用 Saxon :
java -jar saxon-he-10.5.jar -xsl:merge.xslt -s:"test_InitStartOP_report0001.xml;test_InitStartOP_report0002.xml" -o:Output.xml
但它不起作用,有人知道我如何解决问题吗?
解决方法
我可能没有清楚地理解要求,但我猜你写的时候
<xsl:apply-templates select="//testmodule[1]/engineer|//testmodule[1]/testsetup|//testmodule[1]/sut|//testmodule[1]/hardware" />
<xsl:apply-templates select="//testmodule/miscinfo|//testmodule/extendedinfo" />
您实际上想要在所有输入文档中选择 testModule
元素。如果是这种情况,那么首先要做的是有一个变量$allInputs
,其值是输入文档的集合,然后将这些表达式更改为,例如
<xsl:apply-templates select="$allInputs//testModule/....."/>
接下来的问题是如何将变量 $allInputs
绑定到这组文档。有几种方法可以做到这一点:
-
使用 collection() 函数
-
使用带有 URI 列表的 document() 函数
-
将所有文档作为单个样式表参数传入
由于您从命令行运行,因此最简单的方法可能是更改命令行以提供包含以分号分隔的 URI 列表的样式表参数:
inputFiles="test_InitStartOP_report0001.xml;test_InitStartOP_report0002.xml"
然后在样式表中你可以做
<xsl:param name="inputFiles" as="xs:string" required="yes"/>
<xsl:variable name="allInputs" select="tokenize($inputFiles,';')!document(.)" as="document-node()*"/>
请注意,您不需要“主要输入文档” - 在命令行上删除 -s 选项,改用 -it,并将 <xsl:template match="/">
更改为 <xsl:template name="xsl:initial-template">
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。