2

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

考虑

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

如文件 1。

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

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

应该被认为是成功的,而

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

不成功,因为“值”(属性 type=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 似乎不起作用。

也许您对如何解决这个问题有想法?

马特

4

2 回答 2

3

你的问题是无可救药地低估了。例如,除了要求 doc1 中的每个元素在 doc2 中都有对应的元素之外,您是否还要求 doc2 中的每个元素在 doc1 中都有对应的元素?

但是,接近的条件可能是“对于这样的每个元素V1,都存在这样的元素,其中 path($V) 被定义为”D1name(V1)=NV2D2name(V2)=N and deep-equal(V1, V2) and path(V1) = path(V2)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())  
于 2011-03-10T14:15:32.860 回答
0

只是为了好玩,Kay 博士的答案的 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 = ''将是测试的布尔值。

于 2011-03-10T15:56:51.853 回答