我有两个XML文件, a 和 b 。我想在某个子级别合并,某些节点具有属性。当节点名称和属性匹配时,我希望复制子节点。如果有不匹配的节点,我也想要那些。我在这里给出了一个示例,其中复制了 a 的所有节点,但我只获得 b 的匹配节点(它们被合并)。如何获得 b 的无法匹配的节点?
文件 a.xml :
<level0>
<level1>
<level2 value="21">
<level3 value="31">
<a>A31</a>
</level3>
<level3 value="32">
<a>A32</a>
</level3>
</level2>
<level2 value="22">
<level3 value="33">
<a>A33</a>
</level3>
</level2>
</level1>
</level0>
档案 b.xml :
<level0>
<level1>
<level2 value="21">
<level3 value="31">
<b>B31</b>
</level3>
</level2>
<level2 value="22">
<level3 value="33">
<b>B33</b>
</level3>
<level3 value="34">
<b>B34</b>
</level3>
</level2>
</level1>
</level0>
使用XSL(下方),我可以将 b 合并到 a ,但 b 中的此节点会被删除,因为没有匹配项在 a :
<level3 value="34">
<b>B34</b>
</level3>
我的输出如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<level0>
<level1>
<level2 value="21">
<level3 value="31">
<a>A31</a>
<b>B31</b></level3>
<level3 value="32">
<a>A32</a>
</level3>
</level2>
<level2 value="22">
<level3 value="33">
<a>A33</a>
<b>B33</b></level3>
</level2>
</level1>
</level0>
这是我目前的XSL。运行它: xsltproc ab.xsl b.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" />
<xsl:variable name="with" select="'b.xml'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="level3">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:variable name="info" select="document($with)//*/level2[@value=current()/../@value]/level3[@value=current()/@value]/." />
<xsl:for-each select="$info/*">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:transform>
我敢打赌这很容易,但XSL不是我的事,我很少需要使用它。 谢谢你的帮助。
答案 0 :(得分:2)
据我所知,没有必要编写自己的合并样式表。使用由Oliver Becker开发的合并算法。您可以在线找到代码here。
运行样式表的最简单方法是创建一个XML文件,汇总应合并的文件:
摘要输入XML
<?xml version="1.0"?>
<merge xmlns="http://informatik.hu-berlin.de/merge">
<file1>a.xml</file1>
<file2>b.xml</file2>
</merge>
当应用于两个输入文件时,这是我得到的输出:
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?><level0>
<level1>
<level2 value="21">
<level3 value="31">
<a>A31</a>
<b>B31</b>
</level3>
<level3 value="32">
<a>A32</a>
</level3>
</level2>
<level2 value="22">
<level3 value="33">
<a>A33</a>
<b>B33</b>
</level3>
<level3 value="34">
<b>B34</b>
</level3>
</level2>
</level1>
</level0>
输出在一个方面与预期输出不同:<level3 value="34">
在预期输出中不存在,正如@LegoStormtroopr已经指出的那样。
请注意,XSLT(或一般XML)中的“intersection”和“union”不一定与SQL中的概念相同。