Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find element which has specific child element, but no text nodes

Tags:

xslt

xpath

For an XSLT template, I need an XPath expression targeting elements which have a specific child element, but no text nodes.

<!-- 1: matches -->
<a><b/></a>

<!-- 2: does not match -->
<a>foo bar quux<b/></a>

<!-- 3: does not match -->
<a>whatever <b/> further text</a>

<!-- 4: does not match -->
<a>whatever <b/> further text <b/></a>

 <!-- 5: does not match -->
<a><x/><b/></a>

<!-- 6: does not match -->
<a>foo bar quux</a>

I came up with a[*[1 = last() and name() = 'b']], but then case 2 or 3 are matched when they should not. The reason, of course, is that the * selects elements and does not care about text nodes. So how do I do this instead?

like image 388
Jens Bannmann Avatar asked Apr 10 '12 08:04

Jens Bannmann


2 Answers

You could just use

a[count(*)=1 and b and not(text())]

If you are only looking for one b, no other elements and no text. Bear in mind that if you have a carriage return in your xml, some processors will take that as text.

like image 174
Woody Avatar answered Oct 18 '22 20:10

Woody


a[b and not(text() or *[2])]

This selects every a child of the current node (context node) that has a b child, and doesn't have any text node children or a second element child.

If you also don't want to have any PI or comment children, you can use a shorter version:

a[b and not(node()[2])]
like image 41
Dimitre Novatchev Avatar answered Oct 18 '22 19:10

Dimitre Novatchev