XSLT:两个文件之间的XPath比较

时间:2011-03-10 13:00:08

标签: xslt file-comparison

我想通过XSLT比较两个XML文件。如果文档1中特定类型的所有元素都位于文档2中的相同XPath位置,则应认为该比较是成功的。

考虑

<entry>
    <entry1>
        <entry2>
            <value type="1"/>
        </entry2>
    </entry1>
</entry>

作为文件1.

观察中的元素是“value”(属性类型= 1),它位于entry / entry1 / entry2。因此,在这个意义上的比较

<entry>
    <entry0/>
    <entry0/>
    <entry1>
        <entry2>
            <value type="1"/>
        </entry2>
    </entry1>
</entry>

应该被认为是成功的,而

<entry>
    <entry1>
        <value type="1"/>
    </entry1>
</entry>

不成功,因为“value”(属性类型= 1)位于entry / entry1。也 与

的比较
<entry>
    <entry1>
        <entry2>
            <value type="2"/>
        </entry2>
    </entry1>
</entry>

应该被视为不成功,因为value的属性是type = 2。

我在XSLT中完成此任务的天真试验类似于:

<xsl:template match="value">
   <xsl:if test="not(document($doc2)/.[@type=@type])">
      <xsl:text>something is missing</xsl:text>
   </xsl:if>
</xsl:template>

这种方法不成功,因为在第二个文档中选择所需的XPath似乎不起作用。

也许您对如何解决这个问题有所了解?

马特

2 个答案:

答案 0 :(得分:3)

你的问题毫无疑问是毫无疑问的。例如,除了要求doc1中的每个元素在doc2中都有一个对应的元素之外,你是否还要求doc2中的每个元素在doc1中都有一个对应的元素?

但是,对于V1中的每个元素D1而言,某些条件可能是“,因此name(V1)=N V2中存在元素D2这样name(V2)=N and deep-equal(V1, V2) and path(V1) = path(V2),其中path($ V)定义为string-join($V/ancestor-or-self::*/name()),转换为以下XPath 2.0表达式:

every $V1 in $D1//N satisfies
some $V2 in $D2//N satisfies
deep-equal($V1, $V2) and
string-join($V1/ancestor-or-self::*/name())
 = string-join($V2/ancestor-or-self::*/name())  

答案 1 :(得分:0)

只是为了好玩,是Kay博士answer的XSLT 1.0翻译:

    <xsl:variable name="vTest1">
        <xsl:for-each select="$D1//value[@type]">
            <xsl:variable name="vPath1">
                <xsl:for-each select="ancestor-or-self::*">
                    <xsl:value-of select="concat('/',name())"/>
                </xsl:for-each>
            </xsl:variable>
            <xsl:variable name="vTest2">
                <xsl:for-each select="$D2//value[@type=current()/@type]">
                    <xsl:variable name="vPath2">
                        <xsl:for-each select="ancestor-or-self::*">
                            <xsl:value-of select="concat('/',name())"/>
                        </xsl:for-each>
                    </xsl:variable>
                    <xsl:if test="$vPath1=$vPath2">True</xsl:if>
                </xsl:for-each>
            </xsl:variable>
            <xsl:if test="$vTest2=''">False</xsl:if>
        </xsl:for-each>
    </xsl:variable>

然后$vTest1 = ''将是测试的布尔值。