我有两个具有相同架构的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中实现它的任何更好的解决方案?
答案 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>