XPath只获得嵌套HTML的第一个Parent

时间:2014-03-07 02:44:30

标签: xpath

我是XPath中的新手。有人可以解释如何解决这个问题:

<table>
   <tr>
       <td>
           <table>
                <tr>
                    <td>
                         <table>
                             <tr>
                                 <td>Label</td>
                                 <td>value</td>
                             </tr>
                         </table>
                    </td>
                </tr>
           </table>
       </td>
   </tr>
</table>

我尝试获取包含<tr>值的Label,但它对我不起作用,

这是我的代码:

//td[contains(.,'Label')]/ancestor::tr[1]

期望的结果:

<tr>
   <td>Label</td>
   <td>value</td>
</tr>

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:4)

此表达式与您想要的tr匹配:

//tr[contains(td/text(), 'Label')]

与您的一样,这首先是扫描文档中的所有tr元素,但此版本仅使用一个谓词。 td/text()将测试限制为实际的文本节点,这些节点是该行的孙子节点。如果您刚刚使用td,则会收集并连接所有td的后代文本节点,并且外部tr将匹配。

更新:另外,对于它的价值,你的表达式不起作用的原因是ancestor轴按文档顺序返回元素,而不是从文档顺序返回“向外”上下文节点。这是我遇到的事情,因为它有点不直观。为了使您的方法有效,您需要说

//td[contains(.,'Label')]/ancestor::tr[last()]

而不是

//td[contains(.,'Label')]/ancestor::tr[1]

答案 1 :(得分:0)

我遇到了同样的问题,除了文字&#39;标签&#39;有时在嵌套的范围内,甚至进一步嵌套在td中。例如:

app.js

之前的回答只能找到&#39;标签&#39;如果它在文本元素中是td的直接子元素。这个问题有点困难,因为我们需要搜索包含文本&#39;标签&#39;在任何一个孩子。由于tds是嵌套的,因此所有tds都有资格拥有包含文本&#39; Label&#39;的后代。因此,我发现克服此问题的唯一方法是添加一个检查,以确保我们选择的td不包含带搜索文本的td。

<td><span>Label</span></td>

这就是说给我所有带有包含&#39;标签&#39;的死亡文本的tds,但是排除所有包含td的tds,该td具有包含&#39;标签&#39; (筑巢祖先)。这将返回包含文本的最多孩子的td。然后你可以使用祖先回到包含这个td的tr。

另外,如果您只想要包含文本的最低表,请使用:

//td[contains(., 'Label') and not(.//td[contains(., 'Label')])]/ancestor::tr[1]

或者您可以直接选择tr:

//table[contains(., 'Label') and not(.//table[contains(., 'Label')])]

这似乎是一个常见的问题,但我没有在任何地方看到解决方案。因此,我决定发布这个未经回答的问题,希望能帮到某个人。