【问题标题】:how can i merge these two xml files using xslt如何使用 xslt 合并这两个 xml 文件
【发布时间】:2012-09-14 11:33:50
【问题描述】:

我想知道如何使用 xslt 将两个 xml 文件合并为一个 xml 文件。 我有这两个 xml 文件,我想合并到一个 xml 文件中,如预期的输出所示。我想将第二个文件中的每个节点 Hn 包含到具有相同编号的相应块中文件 1。

文件1:

<Test>
  <R1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>
</Test>

文件 2:

<test1>
  <H1>
    here are some instruction.
  </H1>

  <H2>
    here are some instruction.
  </H2>

  <H3>
    here are some instruction.
  </H3>
</test1>    

这是预期的输出:

<test2>
  <R1>
    <H1>
        here are some instruction.
    </H1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
    <H2>
        here are some instruction.
    </H2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
    <H3>
        here are some instruction.
    </H3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>

</test2>

感谢您的帮助。

【问题讨论】:

  • 您好 Franky,您必须使用 document() 函数。尝试设置 XSLT,看看你能走多远。谢谢你,彼得
  • 你好,彼得,我不是 xslt 专家。我刚开始使用 xslt,对此我一无所知。但我会在谷歌上做一些关于这个功能的研究。谢谢你已经给了一个窍门。

标签: xslt xslt-1.0


【解决方案1】:

我。这个 XSLT 1.0 转换

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:variable name="vDigits" select="'0123456789'"/>
 <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/file2.xml')"/> 

 <xsl:template match="/*">
     <test2><xsl:apply-templates/></test2>
 </xsl:template>

 <xsl:template match="/*/*">
  <xsl:copy>
   <xsl:text>&#xA;</xsl:text>
   <xsl:copy-of select=
    "$vDoc2/*/*
      [translate(name(),translate(name(),$vDigits,''),'')
      =
       translate(name(current()),translate(name(current()),$vDigits,''),'')
      ]"/>
    <xsl:copy-of select="node()"/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

应用于第一个 XML 文档时(file1.xml):

<Test>
  <R1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>
</Test>

第二个 XML 文档位于 c:\temp\delete\file2.xml:

<test1>
  <H1>
    here are some instruction.
  </H1>

  <H2>
    here are some instruction.
  </H2>

  <H3>
    here are some instruction.
  </H3>
</test1>

产生想要的正确结果:

<test2>
  <R1>
<H1>
    here are some instruction.
  </H1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
<H2>
    here are some instruction.
  </H2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
<H3>
    here are some instruction.
  </H3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>
</test2>

解释

正确使用由 Michael Kay 首次演示的“双重翻译”方法。


二。 XSLT 2.0 解决方案

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:variable name="vDigits" select="'0123456789'"/>
 <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/file2.xml')"/> 

 <xsl:template match="/*">
     <test2><xsl:apply-templates/></test2>
 </xsl:template>

 <xsl:template match="/*/*">
  <xsl:if test="not(matches(name(), '^.+\d+$'))">
    <xsl:message terminate="yes">
     Element Name doesn't end with number: <xsl:sequence select="name()"/>
    </xsl:message>
  </xsl:if>
  <xsl:copy>
   <xsl:text>&#xA;</xsl:text>
   <xsl:copy-of select=
    "$vDoc2/*/*
      [replace(name(),'^.+(\d+)$', '$1')
      =
       replace(name(current()),'^.+(\d+)$', '$1')
      ]"/>
    <xsl:copy-of select="node()"/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

解释

正确使用标准 XPath 2.0 函数 matches()replace()

【讨论】:

  • 你好 Dimitre,感谢您的解决方案。它走得很好。但我想知道变量名 vDigits 的用途和用途。是否有可能自动获取 file2.xml 的路径,这样我就不需要总是将此文件存储在 c:\temp\delete\... 中?谢谢
  • @FrankyN.,是的,您可以为此指定一个全局/外部(xsl:stylesheet 的子级)xsl:param。这样的参数可以从 XSLT 转换的调用者外部设置——因为这是依赖于实现的,您需要阅读您正在使用的特定 XSLT 处理器的文档。
  • @FrankyN.,$vDigits 的作用——它用于查找元素名称中使用的所有数字。首先我们找到所有非数字(在内部translate()),然后我们从名称中剥离所有非数字——在外部翻译中。剩下的只是名称中包含的所有数字。
  • 感谢 Dimitre 的解释。
猜你喜欢
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多