Использование XPath для сравнения двух объектов XML на точное равенство - PullRequest
9 голосов
/ 28 августа 2011

Когда у меня есть два объекта XML, как я могу сравнить их для точного равенства (все те же узлы, атрибуты и значения), используя XPath?

Ответы [ 3 ]

7 голосов
/ 28 августа 2011

В XPath 2.0 используется стандартная функция deep-equal () .

Xpath 1.0 не имеет такой функции, поэтому сравнение должно бытьвыполняется на языке хостинга XPath.

. Это решение можно использовать в случае, если необходимо использовать XPath 1.0 : Создать / получить xpath из узла XML java , чтобы получить коллекцию выражений XPath для каждого узла Document1 и другую коллекцию выражений XPath для каждого узла Document2.Затем сравните две коллекции - у них должно быть одинаковое количество выражений в каждой, и выражения должны быть эквивалентны.

В качестве альтернативы , вы можете просто сгенерировать, что две коллекции содержат одинаковое числовыражения и применять каждое из выражений для Document1 на Document2.

5 голосов
/ 28 августа 2011

XPath 2.0 имеет функцию, глубоко равную для этого: http://www.w3.org/TR/xpath-functions/#func-deep-equal. XPath 1.0 не имеет ничего похожего, вам нужно будет свернуть свой собственный, на любом языке хоста, с которым вы используете XPath 1.0.

0 голосов
/ 17 апреля 2015

Я использовал комбинацию XSLT 1.0 и Bash для сравнения определенных узлов друг с другом на основе их значений md5.

Использование 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

И часть 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...