2011-02-01 143 views
0

嘿,我试图找出节点内容文本的父节点。找到节点内容文本上的父节点

例如:

<div> 
    <h1>Node to find</h1> 
    <p>another node</p> 
</div> 

所有我的代码知道什么是在节点的文字是和我的脚本需要找出在文本中包含哪些节点。

我曾尝试以下的XPath:

1. //*[. = "'. $text .'"] 
2. //*[contains(., "'. $text .'")] 

第一给了我一个空的节点列表 第二给了我很多的节点,但它给了我所有的家长包含文本,我只是想第一父母。

感谢您的任何帮助。

+1

[PHP/XPath:查找“以特定字符串开头的文本节点”可能的重复项](http://stackoverflow.com/questions/4822469/php-xpath-find-text-node-that-starts -with-a-special-string) – Gordon 2011-02-01 10:53:41

+0

`// * [包含(。,“'。$ text。'”)] [1]`或根据您的需要,`// * [contains(text ),''。$ text。'“)]` – biziclop 2011-02-01 11:11:29

+1

得到了我需要的以下内容:`// * [开头 - (。,''。$ text。'”)]` – Henriksjodahl 2011-02-01 11:23:07

回答

3

我不确定我是否理解你的答案的"'. $text .'"部分...我想这意味着一些示例文本,而不是对名为文本的变量的预期引用?

无论如何,当你使用contains(., "foo")你问当前节点的字符串值是否包含“foo”。当前节点的字符串值是所有后代文本节点的字符串值的拼接。这就是为什么//*[contains(., "foo")]返回一个节点列表:它匹配每个包含“foo”的文本节点的每个祖先。 (因为你在树中的每个节点上都要执行该级联功能,所以效率可能非常低)。

你的starts-with()答案有效的原因是你运气好:文本节点的父节点有其他前面的兄弟姐妹都有自己的文本,所以祖父节点的文本值是以别的东西开始的。也非常低效...

如果您正在寻找的文本将只在一个文本节点 - 即它不会被分成多个元素/评论/等 - 然后你可以高效,准确地匹配仅包含文本节点的元素,使用[编辑]

//*[text()[contains(., "foo")]] 

(类似于@biziclop所述)。

如果你正在寻找的文本可能跨多个元素被分拆/评论/等 - 那么你可以使用这个[编辑,两次]

//*[contains(., "foo") and not(*[contains(., "foo")])] 

但是,这是非常低效的。以下是不能保证工作:

//*[contains(., "foo")][1] 

它会给你[编辑,两次]每一个元素是其父的第一个孩子是(是的祖先),包含文本 。 (或者是一个空的nodeset,如果没有找到“foo”)。我相信@Alejandro在这一个...我还没有内化如何判断[position()= x]何时适用于最近的位置步骤只要。无论如何,这个XPath表达式并不能保证给你正确的结果。

1

我试图找出节点内容文本的父节点 。
[...]但它给我所有的父母 包含文字,我只想要 第一父母。

经典的答案将是:

//*[text()[contains(.,$pText)]] 

含义:具有含有$pText变量/参数的参考字符串值作为它的字符串值的一部分的至少一个文本子节点的任何元素

它提到了可能的混合内容模型。我怀疑这是一个真正的考虑因素,但无论如何,这里就是答案:

//*[contains(.,$pText)][not(*[contains(.,$pText)])] 

含义:$pText为字符串值的一部分的任何元素,而不是具有$pText任何子元素作为其字符串的一部分值。换句话说,最里面的元素包含$pText字符串值。