我想通过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似乎不起作用。
也许您对如何解决这个问题有所了解?
马特
答案 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 = ''
将是测试的布尔值。