我正在尝试选择所有<set>erase</set>
元素,以便两个或多个元素在层次结构中具有<set>erase</set>
时(例如:<b>
和<d>
都有{{} 1}})然后只需要选择父节点名中的元素(在这种情况下为<set>erase</set>
)。
以下示例xml:
<b>
当我使用<?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')]
nodesList <set>erase</set>
。
我需要帮助构建查询以选择b,d,y,p
,<set>erase</set>
和b
的{{1}}。
答案 0 :(得分:2)
以下是相同的解决方案:
一个精确选择所需元素的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
:
//*[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
元素复制到输出中:
<set>erase</set>
<set>erase</set>
<set>erase</set>