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?
This selects every
achild of the current node (context node) that has abchild, 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: