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

发布于 2024-10-21 08:45:33 字数 1294 浏览 7 评论 0原文

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

请考虑

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

文档 1。

观察的元素是“value”(属性 type=1),其中位于入口/入口1/入口2。因此,在这种意义上的比较

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

应被视为成功,而

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

则不成功,因为“值”(属性类型=1)位于条目/条目1。还 与 的比较

<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 似乎不起作用。

也许您知道如何解决这个问题?

马特

I would like to compare two XML-files via XSLT. The comparison should be considered to be successful if all elements of a specific type in document 1 are located at the same XPath position in document 2.

Consider

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

as document 1.

The element under observation is "value" (with attribute type=1) which is located at entry/entry1/entry2. Therefore a comparison in this sense to

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

should be considered as successful, while

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

is not successful, since "value" (with attribute type=1) is located at entry/entry1. Also
the comparison to

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

should be considered as not successful since the attribute of value is type=2.

My naive trial to fulfill this task in XSLT was something like:

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

This approach wasn't successful because the selection of the desired XPath within the 2nd document seems not to work.

Maybe you have an idea on how to address this question?

Matt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长安忆 2024-10-28 08:45:33

你的问题实在是太不明确了。例如,除了要求 doc1 中的每个元素在 doc2 中都有对应的元素之外,是否还要求 doc2 中的每个元素在 doc1 中都有对应的元素?

然而,接近的情况可能是条件“对于 D1 中的每个元素 V1,使得 name(V1)=N,存在D2 中的元素 V2,使得 name(V2)=N 且 deep-equal(V1, V2) 且 path(V1) = path(V2)< /code>,其中 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())  

Your question is hopelessly underspecified. For example, as well as requiring every element in doc1 to have a corresponding element in doc2, do you also require every element in doc2 to have a corresponding element in doc1?

However, something close might be the condition "for every element V1 in D1 such that name(V1)=N, there exists an element V2 in D2 such that name(V2)=N and deep-equal(V1, V2) and path(V1) = path(V2), where path($V) is defined as string-join($V/ancestor-or-self::*/name())", Which translates into the following XPath 2.0 expression:

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())  
在你怀里撒娇 2024-10-28 08:45:33

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

Just for fun, an XSLT 1.0 translation of Dr. Kay's answer:

    <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>

Then $vTest1 = '' would be the boolean value of the test.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文