我尝试匹配包含特定文本字符串的任何元素的祖先或自身:
在第 1 步中,包含文本的元素匹配有效:
//*[contains(text(),"ABC")]
。
但是我对添加祖先的语法感到困惑。我尝试了
//*ancestor-or-self::[contains(text(),"ABC")]
和//*[contains(text(),"ABC")]/ancestor-or-self
但没有成功。
正确的语法是什么?
我想要匹配的代码和字符串如下所示:
<p><strong>Vertreten durch:</strong><br>Max Mustermann</p>
所以我寻找字符串
Vertreten durch
来捕获父元素<p>...</p>
我创建了一个示例 xml,并将其命名为
test.xml
:
<root>
<line1>
<line11>A</line11>
<line12>B</line12>
</line1>
<line2>
<line21>C</line21>
<line22>D</line22>
</line2>
</root>
使用xmlstarlet,你可以:
D:\TEMP>xml sel -t -m "//*[contains(text(),'D')]/ancestor-or-self::*" -v "name()" -n test.xml
root
line2
line22
D:\TEMP>xml sel -t -m "//*[contains(text(),'A')]/ancestor-or-self::*" -v "name()" -n test.xml
root
line1
line11
D:\TEMP>xml sel -C -t -m "//*[contains(text(),'A')]/ancestor-or-self::*" -v "name()" -n test.xml
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//*[contains(text(),'A')]/ancestor-or-self::*">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="name()"/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
D:\TEMP>