嘿,我正在尝试找出节点内容文本的父节点。
示例:
<div>
<h1>Node to find</h1>
<p>another node</p>
</div>
我的所有代码都知道节点中的文本是什么,我的脚本需要找出文本包含的节点。
我尝试过以下xpath:
1. //*[. = "'. $text .'"]
2. //*[contains(., "'. $text .'")]
第一个给我一个空的nodeList 第二个给了我很多节点,但它给了我所有包含文本的父节点,我只想要第一个节点。
感谢您的帮助。
答案 0 :(得分:3)
我不确定我理解你的答案的"'. $text .'"
部分...我想这意味着一些示例文本,而不是对名为text的变量的预期引用?
无论如何,当你使用contains(., "foo")
时,你会问当前节点的字符串值是否包含“foo”。当前节点的字符串值是所有后代文本节点的字符串值的串联。这就是//*[contains(., "foo")]
返回节点列表的原因:它匹配包含“foo”的每个文本节点的每个祖先。 (并且它可能非常低效,因为您正在树中的每个节点上执行该连接功能。)
你的starts-with()
答案工作(有时)的原因是你很幸运:文本节点的父节点有其他前面的兄弟节点有自己的文本,所以祖父节点的文本值以其他东西开始。效率也非常低......
如果您要查找的文本只在一个文本节点中 - 即它不会被分割为多个元素/注释等 - 那么您可以高效准确地匹配包含文本的元素节点,使用 [已编辑] :
//*[text()[contains(., "foo")]]
(类似于@biziclop所说的)。
如果您正在寻找的文字可能会被拆分为多个元素/评论/等等 - 那么您可以使用 [已编辑,两次] :
//*[contains(., "foo") and not(*[contains(., "foo")])]
但那效率很低。以下不保证可以正常工作:
//*[contains(., "foo")][1]
它将为您提供 [已编辑,两次] 每个元素,它是其父级的第一个子级(是其中一个的祖先)包含文本。 (或者是一个空的节点集,如果找不到“foo”。)我相信@Alejandro就此...我还没有内化如何判断[position()= x]何时适用于最近的位置步骤只要。无论如何,这个XPath表达式无法保证为您提供正确的结果。
答案 1 :(得分:1)
我正试图找出父节点 节点内容文本。
[...]但它给了我所有的父母 包含文本,我只想要 第一个父母。
经典的答案是:
//*[text()[contains(.,$pText)]]
含义:具有至少一个文本节点子元素的任何元素包含$pText
变量/参数字符串值作为其字符串值的一部分
有人提到了混合内容模型。我怀疑这是一个真正的考虑,但无论如何,这是答案:
//*[contains(.,$pText)][not(*[contains(.,$pText)])]
含义:任何包含$pText
的元素作为其字符串值的一部分,没有任何子元素$pText
作为其字符串值的一部分。换句话说,最里面的元素包含$pText
字符串值。