微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Saxon 和 xslt 样式表合并两个 xml 文件并获得一个 xml 输出

如何解决使用 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 文件

<?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 举报,一经查实,本站将立刻删除。