XSLT:两个文件之间的XPath比较
我想通过XSLT比较两个XML文件。如果文档1中特定类型的所有元素都位于文档2中相同的XPath位置,则认为比较成功 考虑XSLT:两个文件之间的XPath比较,xslt,file-comparison,Xslt,File Comparison,我想通过XSLT比较两个XML文件。如果文档1中特定类型的所有元素都位于文档2中相同的XPath位置,则认为比较成功 考虑 <entry> <entry1> <entry2> <value type="1"/> </entry2> </entry1> </entry> 如文件1所示 被观察的元素是“value”(属性类型为1),位于en
<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>
未成功,因为“值”(属性类型为1)位于条目/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似乎不起作用
也许你有办法解决这个问题
马特你的问题没有具体说明。例如,除了要求doc1中的每个元素在doc2中都有一个对应的元素外,您是否也要求doc2中的每个元素在doc1中都有一个对应的元素 然而,接近的条件可能是“对于
D1
中的每个元素V1
,例如name(V1)=N
,在D2
中存在一个元素V2
,例如name(V2)=N和深度相等(V1,V2)以及路径(V1)=path(V2
,其中路径($V)定义为字符串连接($V/祖先或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())
只是为了好玩,Kay博士的XSLT 1.0翻译:
真的
假的
然后,
$vTest1='
将是测试的布尔值。如果您只需要测试少数元素,最好的方法可能是手动编写测试XPath,对不同的文件执行它们并比较结果。否则我不知道这个问题的简单解决方案。我不理解您的比较。
非常复杂与条目>
不同。为什么它们之间的比较要成功?好的,不要称之为“比较”,而是“检查doc1中观察到的每个元素是否在doc2中以相同的XPath出现”。我将尝试以下答案中提出的深度相等。抱歉,如果您认为我的问题不够具体,我只是试图将重点放在主要方面。尤其是您的示例与此无关:doc2可能包含大量其他元素,在我的意义上不会影响比较(因此可能“比较”一词具有误导性-抱歉!)无论如何,谢谢你的想法,这确实是有帮助的。非常感谢,解决方案几乎是1:1适用于我的问题。
<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>