使用XPath比较两个XML对象是否完全相等

时间:2022-03-04 22:59:32

When I have two XML objects, how can I compare them for exact equality (all the same nodes and attributes and values) using XPath?

当我有两个XML对象时,如何使用XPath将它们与完全相等(所有相同的节点,属性和值)进行比较?

3 个解决方案

#1


7  

In XPath 2.0 use the standard function deep-equal().

在XPath 2.0中使用标准函数deep-equal()。

Xpath 1.0 doesn't have such a function, therefore the comparison needs to be performed within the language hosting XPath.

Xpath 1.0没有这样的功能,因此需要在托管XPath的语言中执行比较。

You can use this solution in case you must use XPath 1.0: Generate/get xpath from XML node java to get a collection of XPath expressions for every node of Document1 and another collection of XPath expressions for every node of Document2. Then compare the two collections -- they should have the same number of expressions each and the expressions must be equivalent.

如果必须使用XPath 1.0,则可以使用此解决方案:从XML节点java生成/获取xpath,以获取Document1的每个节点的XPath表达式集合以及Document2的每个节点的另一个XPath表达式集合。然后比较两个集合 - 它们应该具有相同数量的表达式,并且表达式必须是等效的。

Alternatively, you can generate just verify that the two collections contain the same number of expressions and apply each of the expressions for Document1 on Document2.

或者,您可以生成只验证两个集合包含相同数量的表达式并应用Document2上的Document1的每个表达式。

#2


5  

XPath 2.0 has a function deep-equal for that: http://www.w3.org/TR/xpath-functions/#func-deep-equal. XPath 1.0 has nothing comparable, you would need to roll your own, in whatever host language you use XPath 1.0 with.

XPath 2.0具有与之相同的功能:http://www.w3.org/TR/xpath-functions/#func-deep-equal。 XPath 1.0没有任何可比性,你需要使用XPath 1.0使用的任何主机语言自己滚动。

#3


0  

I've used a combination of XSLT 1.0 and Bash to compare specific nodes with each other based on their md5sums.

我已经使用XSLT 1.0和Bash的组合来基于md5sums将特定节点相互比较。

Using the test="$index=$navigator", because I couldn't copy-of based on a node[$navigator] directly.

使用test =“$ index = $ navigator”,因为我无法直接根据节点[$ navigator]进行复制。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:ns="http://www.example.org">
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    <xsl:param name="navigator"/>
    <xsl:param name="part"/>

    <xsl:template match="/">
    <xsl:for-each select="/ns:mappings/ns:mapping">
        <xsl:variable name="index" select="position()" />
        <xsl:if test="$index=$navigator">
            <xsl:choose>
                <xsl:when test="$part='source'">
                    <xsl:copy-of select="ns:source/ns:taxonpath"/>
                </xsl:when>
                <xsl:when test="$part='target'">
                    <xsl:copy-of select="ns:target/ns:taxonpath"/>
                </xsl:when>
                <xsl:when test="$part='mapping'">
                    <xsl:copy-of select="."/>
                </xsl:when>
            </xsl:choose>
        </xsl:if>
    </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
mappingcount=$(cat mapping.xml | grep "<mapping>" | wc -l)
counter=1

while [  $counter -lt $mappingcount ]; do
    sourcehash=$(xsltproc --stringparam navigator $counter --stringparam part source compare.xslt mapping.xml | md5sum | cut -d " " -f1)
    targethash=$(xsltproc --stringparam navigator $counter --stringparam part target compare.xslt mapping.xml | md5sum | cut -d " " -f1)

    if [ "$sourcehash" == "$targethash" ]; then
        xsltproc --stringparam navigator $counter --stringparam part mapping compare.xslt mapping.xml
    fi
    let counter=counter+1
done

And a part of the mapping.xml

和mapping.xml的一部分

<mappings xmlns="http://www.example.org">
  <mapping>
    <source>
      <taxonpath>
        <taxon>
          <id>c001f86a-4f8f-4420-bd78-381c615ecedc</id>
          <entry>Aardrijkskunde</entry>
        </taxon>
        <taxon>
          <id>65c33fa0-420a-4399-a6f8-595294179df3</id>
          <entry>Weer en klimaat</entry>
        </taxon>
      </taxonpath>
    </source>
    <relationship>ter info</relationship>
    <target>
      <taxonpath>
        <taxon>
          <id>c001f86a-4f8f-4420-bd78-381c615ecedc</id>
          <entry>Aardrijkskunde</entry>
        </taxon>
        <taxon>
          <id>65c33fa0-420a-4399-a6f8-595294179df3</id>
          <entry>Systeem aarde</entry>
        </taxon>
      </taxonpath>
    </target>
  </mapping>
</mappings>

#1


7  

In XPath 2.0 use the standard function deep-equal().

在XPath 2.0中使用标准函数deep-equal()。

Xpath 1.0 doesn't have such a function, therefore the comparison needs to be performed within the language hosting XPath.

Xpath 1.0没有这样的功能,因此需要在托管XPath的语言中执行比较。

You can use this solution in case you must use XPath 1.0: Generate/get xpath from XML node java to get a collection of XPath expressions for every node of Document1 and another collection of XPath expressions for every node of Document2. Then compare the two collections -- they should have the same number of expressions each and the expressions must be equivalent.

如果必须使用XPath 1.0,则可以使用此解决方案:从XML节点java生成/获取xpath,以获取Document1的每个节点的XPath表达式集合以及Document2的每个节点的另一个XPath表达式集合。然后比较两个集合 - 它们应该具有相同数量的表达式,并且表达式必须是等效的。

Alternatively, you can generate just verify that the two collections contain the same number of expressions and apply each of the expressions for Document1 on Document2.

或者,您可以生成只验证两个集合包含相同数量的表达式并应用Document2上的Document1的每个表达式。

#2


5  

XPath 2.0 has a function deep-equal for that: http://www.w3.org/TR/xpath-functions/#func-deep-equal. XPath 1.0 has nothing comparable, you would need to roll your own, in whatever host language you use XPath 1.0 with.

XPath 2.0具有与之相同的功能:http://www.w3.org/TR/xpath-functions/#func-deep-equal。 XPath 1.0没有任何可比性,你需要使用XPath 1.0使用的任何主机语言自己滚动。

#3


0  

I've used a combination of XSLT 1.0 and Bash to compare specific nodes with each other based on their md5sums.

我已经使用XSLT 1.0和Bash的组合来基于md5sums将特定节点相互比较。

Using the test="$index=$navigator", because I couldn't copy-of based on a node[$navigator] directly.

使用test =“$ index = $ navigator”,因为我无法直接根据节点[$ navigator]进行复制。

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:ns="http://www.example.org">
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    <xsl:param name="navigator"/>
    <xsl:param name="part"/>

    <xsl:template match="/">
    <xsl:for-each select="/ns:mappings/ns:mapping">
        <xsl:variable name="index" select="position()" />
        <xsl:if test="$index=$navigator">
            <xsl:choose>
                <xsl:when test="$part='source'">
                    <xsl:copy-of select="ns:source/ns:taxonpath"/>
                </xsl:when>
                <xsl:when test="$part='target'">
                    <xsl:copy-of select="ns:target/ns:taxonpath"/>
                </xsl:when>
                <xsl:when test="$part='mapping'">
                    <xsl:copy-of select="."/>
                </xsl:when>
            </xsl:choose>
        </xsl:if>
    </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
mappingcount=$(cat mapping.xml | grep "<mapping>" | wc -l)
counter=1

while [  $counter -lt $mappingcount ]; do
    sourcehash=$(xsltproc --stringparam navigator $counter --stringparam part source compare.xslt mapping.xml | md5sum | cut -d " " -f1)
    targethash=$(xsltproc --stringparam navigator $counter --stringparam part target compare.xslt mapping.xml | md5sum | cut -d " " -f1)

    if [ "$sourcehash" == "$targethash" ]; then
        xsltproc --stringparam navigator $counter --stringparam part mapping compare.xslt mapping.xml
    fi
    let counter=counter+1
done

And a part of the mapping.xml

和mapping.xml的一部分

<mappings xmlns="http://www.example.org">
  <mapping>
    <source>
      <taxonpath>
        <taxon>
          <id>c001f86a-4f8f-4420-bd78-381c615ecedc</id>
          <entry>Aardrijkskunde</entry>
        </taxon>
        <taxon>
          <id>65c33fa0-420a-4399-a6f8-595294179df3</id>
          <entry>Weer en klimaat</entry>
        </taxon>
      </taxonpath>
    </source>
    <relationship>ter info</relationship>
    <target>
      <taxonpath>
        <taxon>
          <id>c001f86a-4f8f-4420-bd78-381c615ecedc</id>
          <entry>Aardrijkskunde</entry>
        </taxon>
        <taxon>
          <id>65c33fa0-420a-4399-a6f8-595294179df3</id>
          <entry>Systeem aarde</entry>
        </taxon>
      </taxonpath>
    </target>
  </mapping>
</mappings>