Reputation: 3446
On the following 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>
I'm trying to get the Total value (1.57%). If I XPath query with //tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]
I get the desired XML block:
<td class="right-align">
<b>
<span class="summary-line">
1.57%
</span>
</b>
</td>
And if I query for //*[not(*)]/text()
against that block in isolation I get the desired result ("1.57%").
However, if I append try to concatenate the two queries (i.e., //tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]/*[not(*)]/text()
) and run against the full XML I get an empty result. Why?
Upvotes: 0
Views: 34
Reputation: 167676
Your path //tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]
selects a td
element node in your sample which has a b
child element and span
grandchild and your attempt to add a step with *[not(*)]
to that path would select a child element of the td
not having any further child. There is no such child, a step with *
would select the b
element, a further step with *
the span
element so you would need //tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]/*/*
to select the span
grandchild or //tr[preceding::h1[1][contains(text(), "Expense")]]/td[preceding-sibling::td/descendant-or-self::*[contains(text() , "Total")]]//*[not(*)]
to select any descendant element not having element content.
Upvotes: 1