1

I'm having serious issues trying to understand the magic that is XPath.

Basically, I have some XML like so:

<a>
    <b>
        <c/>
    </b>
</a>

Now, I want to count how many B's we have, without C's. This can be done easily with the following XPath:

count(*/b[not(descendant::c)])

Now the question is this simple: How do I do the same thing, while ignoring any namespaces?

I'd imagine it was something like this?

count(*/[local-name()='b']/[not(descendant::[local-name()='c'])])

But this is not correct. What would be the equivalent XPath as I have above but that ignores namespaces?

Kahn
  • 1,630
  • 1
  • 13
  • 23
  • 1
    If you're asking specifically about XPath 1.0, do please make this clear in your question. In XPath 2.0 and 3.0 you can write *:c to select elements with local name c in any namespace. – Michael Kay Oct 04 '16 at 16:09
  • 1
    OP did tag the question explicitly as xpath-1.0, but I probably should have represented that in the title edit I made. Fixed now. – kjhughes Oct 04 '16 at 20:31
  • Ok my bad. I assumed it was enough to tag the topic as xpath-1.0. I'll be sure to add that to the subject next time. – Kahn Oct 05 '16 at 06:17

1 Answers1

3

The given XPath,

count(*/b[not(descendant::c)])

can be re-written to ignore namespaces as follows:

count(*[local-name()='b' and not(descendant::*[local-name()='c'])])

Note that it generally is better not to defeat namespaces but to work with them properly by assigning namespace prefixes and using them in your XPath expression.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Sweet, thank you! Had to spend a little more time wondering when the real scenario has multiple elements before this decision, but I got there in the end. And I hear you about the namespaces, but in this case we've validated the XML way before this part. This is basically just a code-behind check that we specifically do NOT want to be namespace dependant. – Kahn Oct 05 '16 at 07:22