Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT:两个文件之间的XPath比较_Xslt_File Comparison - Fatal编程技术网

XSLT:两个文件之间的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

我想通过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>

未成功,因为“值”(属性类型为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>