xpath / Потомок-или-Сам - Поиск узла в определенном дереве
Я читаю о сокращении "//", которое, по-видимому, является сокращением для:
"/ Потомок или-я"
ясно, что ожидать, скажем, от простого примера такого выражения, например,
// MyNode
Он вернет список узлов всех экземпляров в документе, найденных из корня, элементов с именем "myNode".
Однако в чем смысл более сложного выражения, такого как:
// аноде // MyNode
?
Поскольку // (являясь сокращением для "/ Потомок-или-Сам") дважды совпадает с корневым узлом, означает ли это, что первая часть выражения "// aNode" является избыточной и только увеличивает время, необходимое для завершения выполнение выражения (после того, как все еще только найдены все выражения во всем документе "myNode")?
"// myNode" и "// aNode // myNode" приведут к тому же результату?
Наконец, если бы я искал в документе экземпляр узла "myNode", который был косвенным потомком узла "интересного дерева ". Но я не хочу, чтобы экземпляр узла '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>
Спасибо!
2 ответа
"//myNode" и "//aNode//myNode" приведут к тому же результату?
Да, в этом случае, потому что все myNodes
также являются потомками anode
, Однако в общем смысле //aNode//myNode
очевидно, не будет соответствовать узлам, которые не имеют anode
родитель в их дереве предка.
Xpath:
//aNode//myNode
будет игнорировать любую промежуточную иерархию между aNode
а также myNode
будет соответствовать /aNode/myNode
, /anyNodes/anode/myNode
, а также /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
Вы спрашиваете: "//myNode" и "//aNode//myNode" в результате получат одно и то же?"
Не обязательно. Первый вернет все элементы с именем myNode
в документе; вторая вернет все элементы с именем myNode
которые происходят как потомки элементов с именем aNode
, В вашем примере XML эти два описания определяют один и тот же набор, но в некоторых документах XML они не будут.
Выражения //aNode//myNode
а также //myNode[ancestor::aNode]
с другой стороны, всегда будет возвращать один и тот же набор узлов.