在以下XML上:
<root>
<h1">Annual Expense</h1>
<div class="table-wrapper">
<table>
<tr>
<td>Fees</td>
<td>1.06%</td>
</tr><tr>
<td><b>Total:</b></td>
<td class="right-align"><b>
<span class="summary-line">
1.57%
</span>
</b></td>
</tr>
</table>
</div>
</root>
我试图获得总价值(1.57%)。如果我使用//tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]
查询XPath,我会得到所需的XML块:
<td class="right-align">
<b>
<span class="summary-line">
1.57%
</span>
</b>
</td>
如果我孤立地查询//*[not(*)]/text()
该块,我会得到所需的结果(&#34; 1.57%&#34;)。
但是,如果我追加尝试连接两个查询(即//tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]/*[not(*)]/text()
)并针对完整XML运行,我得到一个空结果。为什么呢?
答案 0 :(得分:1)
您的路径//tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]
会在您的示例中选择一个td
元素节点,该节点具有b
子元素和span
孙子,并尝试使用{{1该路径将选择*[not(*)]
的子元素,而不再有任何子元素。没有这样的孩子,td
的一个步骤会选择*
元素,b
*
元素的另一个步骤,因此您需要span
来选择//tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]/*/*
孙子或span
以选择任何不具有元素内容的后代元素。