4

我正在阅读捷径“//”,这显然是以下方面的捷径:

'/后代或自我'

从这种表达的一个简单例子中可以很清楚地看到什么,例如,

//我的节点

它将返回文档中所有实例的节点列表,从根中找到,称为“myNode”的元素。

但是,更复杂的表达是什么意思,比如:

//aNode//myNode

?

由于 //(是 '/descendant-or-self' 的快捷方式)两次匹配根节点,这是否意味着表达式 '//aNode' 的第一部分是多余的,只会增加完成所需的时间表达式的执行(在整个文档中仍然只找到'myNode'的所有表达式之后)?

'//myNode' 和 '//aNode//myNode' 会产生完全相同的结果吗?

最后,如果我在文档中搜索节点“myNode”的实例,它是节点“interestingTree”的间接后代。但是我不想要节点“myNode”的实例,它是节点“nonInterestingTree”的间接后代,我应该怎么做?

例如,在文档中搜索:

<root>
    <anode>
        <interestingTree>
            <unknownTree>
                <myNode/><!-- I want to find this one, not the other, where I don't know the path indicated by 'unknownTree' -->
            </unknownTree>
        </interestingTree>
        <nonInterestingTree>
            <unknownTree>
                <myNode/>
            </unknownTree>
        </nonInterestingTree>
    </anode>
    <anode>
        <someOtherNode/>
    </anode>
</root>

谢谢!

4

2 回答 2

4

'//myNode' 和 '//aNode//myNode' 会产生完全相同的结果吗?

是的,在这种情况下,因为 allmyNodes也是anode. 然而,在一般意义上,//aNode//myNode显然不会匹配在其祖先树中没有anode父节点的节点。

xpath:

//aNode//myNode

aNode将忽略and之间的任何中间层次结构myNode,即它将匹配/aNode/myNode, /anyNodes/anode/myNode, and/anyNodes/anode/xyzNode/myNode

这回答了您的最后一个问题,您可以像这样在有趣的子路径中找到节点:(同样,忽略层次结构中的任何中间元素)

//anode//interestingTree//myNode

当然,理想情况下,您应该尽可能明确地使用路径,因为//可能会由于需要搜索大量元素而导致性能开销。

编辑这可能有帮助吗?

为了清楚起见,我已将您的 xml 输入调整为:

<root>
    <anode>
        <interestingTree>
            <unknownTree>
                <myNode>
                    MyNode In Interesting Tree
                </myNode>
            </unknownTree>
        </interestingTree>
        <nonInterestingTree>
            <unknownTree>
                <myNode>
                    MyNode In Non-Interesting Tree
                </myNode>
            </unknownTree>
        </nonInterestingTree>
    </anode>
    <anode>
        <someOtherNode/>
    </anode>
    <bnode>
        <myNode>
            MyNode in BNode
        </myNode>
    </bnode>
</root>

通过样式表解析时:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        Matched by `//myNode`
        <xsl:apply-templates select="//myNode">
        </xsl:apply-templates>

        Matched by `//aNode//myNode`
        <xsl:apply-templates select="//anode//myNode">
        </xsl:apply-templates>

        Matched by `//aNode//interestingTree//myNode`
        <xsl:apply-templates select="//anode//interestingTree//myNode">
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="myNode">
        <xsl:value-of select="text()"/>
    </xsl:template>
</xsl:stylesheet>

返回以下内容:

Matched by `//myNode`
        MyNode In Interesting Tree
        MyNode In Non-Interesting Tree
    MyNode in BNode

Matched by `//aNode//myNode`
        MyNode In Interesting Tree
        MyNode In Non-Interesting Tree

Matched by `//aNode//interestingTree//myNode`
        MyNode In Interesting Tree
于 2012-09-21T12:34:09.143 回答
1

你问“'//myNode' 和 '//aNode//myNode' 会产生完全相同的结果吗?”

不必要。第一个将返回myNode文档中命名的所有元素;第二个将返回myNode作为元素命名的后代出现的所有命名元素aNode。在您的示例 XML 中,这两个描述碰巧定义了相同的集合,但在某些 XML 文档中它们不会。

另一方面,表达式//aNode//myNodeand将始终返回相同的节点集。//myNode[ancestor::aNode]

于 2012-09-21T17:08:22.173 回答