<root>
<div>
<p>this text</p>
<p><span>fo</span><span>ob</span><span>ar</span></p>
</div>
<div>
<p>this text</p>
<p><span>fo</span><span>b</span><span>ar</span></p>
</div>
<div>
<p>this text</p>
<p><span>fooba</span><span>r</span></p>
</div>
<div>
<p><span>foo</span>this text<span>bar</span></p>
</div>
<div>
<p><span>foo</span><img/><span>bar</span></p>
</div>
<div>
<p><span>foo</span><span>bar</span><span>baz</span></p>
</div>
<div>
<p>foobar</p>
</div>
</root>
鉴于上述XML,XPath 1.0查询会根据<div>
中出现的foobar
或多个连续<span>
中的<span>
来选择<div>
?我只想选择第一个和第三个<div>
。第二个fobar
包含foobar
,而不是<div>
。在第四个<span>
中,<div>
不是连续的。第五个<img>
在<span>
之间有一个foobarbaz
,因此它们不再是连续的,第六个的文本是foobar
,而不是<span>
。第七个文本具有正确的文本,但不在concat()
s内。
我尝试使用concat(//*, //*)
,但这不起作用,因为我需要先知道参数的数量。另外,说concat(//*[1], //*[1])
等同于http://localhost:8080/github-webhook
,这不是我想要的。
这是在PHP中,所以我只有XPath 1.0。
答案 0 :(得分:2)
你可以尝试这个XPath:
/root/div[contains(normalize-space(.), 'foobar')]
请注意.
返回当前上下文节点中所有文本节点的连接。
xpath tester中的输出:
Element='<div>
<p>this text</p>
<p>
<span>fo</span>
<span>ob</span>
<span>ar</span>
</p>
</div>'
Element='<div>
<p>this text</p>
<p>
<span>fooba</span>
<span>r</span>
</p>
</div>'
答案 1 :(得分:0)
我有一个文档,其中的段落(
)的字符串值(。)包含前缀(问题:)。我需要删除前缀和所有祖先元素,但保留段落(
)以及前缀之后的所有元素。前缀可能已经分布在XML中不同深度的多个元素上。此解决方案仅限于XSLT 1.0。我发现通过遍历子孙:: text()并跟踪文本节点字符串长度的总和,可以确定我何时在包含前缀末尾的文本节点处。请注意,应用模板选择仅选择以前缀开头的段落,因此仅允许使用文本节点长度的总和来检测在哪里停止。您也可以累积实际的字符串,并使用其他测试(包含)确定何时停止。
示例XML(请注意测试所需的复杂性)
<?xml version="1.0" encoding="utf-8" ?>
<root>
<p><d1><d2>q<a>u<b>e<c>s</c><d>t</d>i</b><e>o</e></a><f>n</f>:</d2></d1> text</p>
</root>
样本XSL(注意
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root/p[substring(.,1,9)='question:']">
<trace info="{concat('ML descendant::text()[1]:',' name=',name(),', .=',.)}"/>
<xsl:apply-templates select="descendant::text()[1]" mode="m1"/>
</xsl:template>
<xsl:template mode="m1" match="text()">
<xsl:param name="length" select="0"/>
<xsl:variable name="temp" select="$length+string-length()"/>
<trace info="{concat('m1:',' name=',name(),', length=',$temp,', .=',.)}"/>
<xsl:choose>
<xsl:when test="$temp<9">
<xsl:apply-templates select="following::text()[1]" mode="m1">
<xsl:with-param name="length" select="$temp"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<trace info="m1: prefix match"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
输出
<?xml version="1.0" encoding="UTF-8"?>
<trace info="ML descendant::text()[1]: name=p, .=question: text"/>
<trace info="m1: name=, length=1, .=q"/>
<trace info="m1: name=, length=2, .=u"/>
<trace info="m1: name=, length=3, .=e"/>
<trace info="m1: name=, length=4, .=s"/>
<trace info="m1: name=, length=5, .=t"/>
<trace info="m1: name=, length=6, .=i"/>
<trace info="m1: name=, length=7, .=o"/>
<trace info="m1: name=, length=8, .=n"/>
<trace info="m1: name=, length=9, .=:"/>
<trace info="m1: prefix match"/>