Reputation: 1060
Say I have this XML:
<root>
<A></A>
<B></B>
<C>one</C>
<C>two</C>
<C>three</C>
<D></D>
</root>
Now I want to get all nodes, except for The C nodes 'two' and 'three'. Now I want to choose which C node can stay by index.
So this is the xpath that I already have:
//*[not(ancestor-or-self::C)]
But this removes all C nodes, so now I have to add an index to which C node I want to stay
//*[not(ancestor-or-self::C)] exept for C[1]
How can I accomplsh this so my output would be if I select index 1:
<root>
<A></A>
<B></B>
<C>one</C>
<D></D>
</root>
Or if I select index 2:
<root>
<A></A>
<B></B>
<C>two</C>
<D></D>
</root>
Hope I made myself clear enough :p thx
Upvotes: 1
Views: 230
Reputation: 243459
Use:
//*[not(self::c and not(count(preceding-sibling::c) = $ind - 1))]
where $ind is the wanted position (1-based) of the c
element you want to select.
Upvotes: 0
Reputation:
Why except? You have any element but those, then you add some of those:
//*[not(ancestor-or-self::C)]|//C[1]/descendant-or-self::*
Upvotes: 1
Reputation: 6269
i think it depends on what you define as "index". If you define "index" as the C that has n-1 C siblings then you can just do:
to display one the first (get rid of all afterwards
/root/*[not(name() = 'C' and count(preceding::C) >= 1)]
to display only the second
/root/*[not(name() = 'C' and (count(preceding::C) < 1 or count(preceding::C) > 1))]
(I tested this with: http://www.xmlme.com/XpathTool.aspx just fyi )
Upvotes: 1