比较2 xml文件的数据并输出差异

时间:2014-01-30 19:56:35

标签: xslt xslt-2.0

我有两个具有相同架构的xml文件,我想比较两个文件,只获取第一个文档中存在但不存在于第二个文档中的节点,反之亦然。

案例1:

所以我的第一个xml是a.xml

<cases>
    <no sort="1">1</no>
    <no sort="2">2</no>
    <no sort="3">3</no>
    <no sort="4">4</no>
    <no sort="5">5</no>
    <no sort="6">6</no> 
</cases>

第二个xml是b.xml

<cases>
    <no sort="1">1</no>
    <no sort="2">2</no>
    <no sort="3">3</no>
    <no sort="4">4</no>
    <no sort="5">5</no>
    <no sort="6">6</no>
     <no sort="7">9</no>
 </cases>

比较后的预期结果应为

<cases>
       <no sort="7">9</no>
 </cases>

如果<no sort="7">9</no>在a.xml中而不在b.xml中,则它应该输出相同的结果。所以基本上合并文档并删除两个文档中存在的节点。

我正在考虑逐个遍历文档并使用xpath检查节点是否存在是否是其他文档,如果发现它在输出中丢弃它。在xslt 1.0或xslt 2.0中实现它的任何更好的解决方案?

3 个答案:

答案 0 :(得分:3)

如果您使用websearch“xml diff”,您将找到比较XML文档并将其差异作为XML文档输出的过去版本的工具。另请参阅https://stackoverflow.com/questions/1871076/are-there-any-free-xml-diff-merge-tools-available

答案 1 :(得分:2)

这种方式(XSLT 1.0):

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:variable name="file2" select="document('b.xml')" />

<xsl:variable name="IDs1" select="/cases/no/@sort" />
<xsl:variable name="IDs2" select="$file2/cases/no/@sort" />

<xsl:template match="/cases">
<cases>
    <xsl:apply-templates select="no[not(@sort=$IDs2)]"/>
    <xsl:apply-templates select="$file2/cases/no[not(@sort=$IDs1)]"/>
</cases>
</xsl:template>

<xsl:template match="no">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

您需要将样式表应用于“a.xml”文件,并确保“b.xml”位于同一目录中。

答案 2 :(得分:0)

如果我需要比较2个XML文件并快速查看它们之间的差异,我使用XSLT对文件进行排序,然后使用WinMerge手动比较两个xml文件(简单的unix diff也可以完成这项工作)。如果要输出差异,可以按照@keshlam

给出的方法

以下是对我的XML文件进行排序的XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes" encoding="UTF-8"/>

<xsl:template match="node()|@*">
    <xsl:copy>
            <xsl:apply-templates select="node()|@*">
                    <xsl:sort select="name()" />
                    <xsl:sort select="@*" />
                    <xsl:sort select="*" />
                    <xsl:sort select="text()" />
            </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
相关问题