Martin Eve
Martin Eve

Reputation: 2751

XPath: return nodes with specific children but no text of their own

In the following XML:

<document>
<p rend="Default Style"><hi rend="bold italic">This one</hi></p>
<p rend="Default Style"><hi rend="bold italic">Not this one</hi> please</p>
<p rend="Default Style"><hi rend="italic">Not this one either</hi></p>
<p rend="Default Style"><hi rend="bold">Not this one either</hi><hi rend="italic">Not this one either because it has others</hi></p>
<p rend="Default Style"><hi rend="bold italic">This one</hi> <hi rend="bold italic">because it is all bold</hi></p>
</document>

I would like to select P elements that contain:

  1. hi sub-elements whose rend attribute contains the word "bold"
  2. no text of their own
  3. nothing else

This should mean that I am only getting paragraphs whose concatenated content is hi tags with the rend attribute containing "bold".

I have tried a variety of approaches. The closest seems to be:

//p[hi[contains(@rend, "bold")] and not(text()) and not(*[not(self::hi[contains(@rend, "bold")])])]

However, the not(text()) aspect is not working as I would like. The line that has text within the P tag itself (condition #2 above) is not fulfilled.

I have tried, as other conditions:

and several others.

Any help would be much appreciated. I am using XSLT 1.0.

Upvotes: 1

Views: 272

Answers (1)

Erlock
Erlock

Reputation: 1968

Spaces between hi elements are valid text nodes. Use normalize-space() for filtering them.

p[count(hi) = count(hi[contains(@rend, 'bold')]) and not(text()[normalize-space()!=''])]

Upvotes: 3

Related Questions