Xpath查询以根据条件选择忽略后代的所有元素 [英] Xpath query to select all elements ignoring descendants based on criteria
问题描述
我正在尝试选择所有
元素,以便如果两个或多个元素具有
code> 在层次结构中(例如: 和
都有
)然后只需要选择父节点名称中的元素(即 在这种情况下).
I am trying to select all the <set>erase</set>
elements such that if two or more elements have the <set>erase</set>
in hierarchy (Ex: <b>
and <d>
both have <set>erase</set>
) then only the element in parent node name has to be selected(ie <b>
in this case).
下面的示例xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a>
<b>
<set>erase</set>
<d>
<set>erase</set>
</d>
</b>
<c>
<x></x>
</c>
<e>
<y>
<set>erase</set>
<q></q>
</y>
<z>
<p>
<set>erase</set>
</p>
</z>
</e>
</a>
当我使用 query =//set[contains(.,'erase')]
我得到所有 <set>erase</set>
的节点列表b,d,y,p
在结果集中.
When I use the query = //set[contains(.,'erase')]
I get all <set>erase</set>
of nodesList b,d,y,p
in result set.
我需要帮助构建查询以选择 <set>erase</set>
的 b
、y
和 p
.
I need help in framing the query to select <set>erase</set>
of b
, y
and p
.
推荐答案
这里是相同的解决方案:
Here is the same solution:
一个准确选择所需元素的 XPath 表达式是:
//*[set[. = 'erase' and not(node()[2])]
and
not(ancestor::*
[set
[. = 'erase' and not(node()[2])]
]
)
]
基于 XSLT 的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:for-each select=
"//*[set[. = 'erase' and not(node()[2])]
and
not(ancestor::*
[set
[. = 'erase' and not(node()[2])]
]
)
]">
<xsl:value-of select="name()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<a>
<b>
<set>erase</set>
<d>
<set>erase</set>
</d>
</b>
<c>
<x></x>
</c>
<e>
<y>
<set>erase</set>
<q></q>
</y>
<z>
<p>
<set>erase</set>
</p>
</z>
</e>
</a>
计算包含的 XPath 表达式并输出所选元素的名称 - 正确且符合预期:
b
y
p
如果您需要选择上述所选元素的 set
子元素,只需在上面的 XPath 表达式中附加 /set
:
If you need to select the set
children of the selected above elements, just append the above XPath expression with /set
:
//*[set[. = 'erase' and not(node()[2])]
and
not(ancestor::*
[set
[. = 'erase' and not(node()[2])]
]
)
]
/set
同样,基于 XSLT 的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"//*[set[. = 'erase' and not(node()[2])]
and
not(ancestor::*
[set
[. = 'erase' and not(node()[2])]
]
)
]
/set
"/>
</xsl:template>
</xsl:stylesheet>
这个转换只是计算上面的 XPath 表达式并将正确选择的三个 set
元素复制到输出中:
This transformation just evaluates the above XPath expression and copies to the output the correctly selected three set
elements:
<set>erase</set>
<set>erase</set>
<set>erase</set>
这篇关于Xpath查询以根据条件选择忽略后代的所有元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!