views:

183

answers:

3

Hi,

If I have some xml like:

    <root>
   <customers>
        <customer firstname="Joe" lastname="Bloggs" description="Member of the Bloggs family"/>
        <customer firstname="Joe" lastname="Soap" description="Member of the Soap family"/>
        <customer firstname="Fred" lastname="Bloggs" description="Member of the Bloggs family"/>
        <customer firstname="Jane" lastname="Bloggs" description="Is a member of the Bloggs family"/>
   </customers>
 </root>

How do I get, in pure XPath - not XSLT - an xpath expression that detects rows where lastname is the same, but has a different description? So it would pull the last node above?

Thanks a mill if you can help, been scratching at it for ages, and I can't find it by searching (apologies if it is)

Cheers, J

A: 

How do I get, in pure XPath - not XSLT - an xpath expression that detects rows where lastname is the same, but has a different description?

Here's how to do this with a single XPath expression:

   "/*/*/customer
        [@lastname='Bloggs'
       and
        not(@description
           = preceding-sibling::*[@lastname='Bloggs']/@description
            )
        ]"

This expression selects all <customer> elements with attribute lastname equal to "Bloggs" and different value of the attribute description.

The selected nodes are:

<customer firstname="Joe" lastname="Bloggs" description="Member of the Bloggs family"/>
<customer firstname="Jane" lastname="Bloggs" description="Is a member of the Bloggs family"/>
Dimitre Novatchev
So it's not possible to do this for all lastnames at once?
svick
A: 
/root/customers/customer[@lastname='Bloggs'
  and not(@description = preceding-sibling::*[@lastname='Bloggs']/@description)
  and not(@description = following-sibling::*[@lastname='Bloggs']/@description)]

It would perform better doing it in steps, though.

k_b
A: 

Hey guys, thanks, thats genius!

However, that works fine if I'm only targetting the Bloggs family, but is it possible to generalise this, so that it works for any nodes who have lastname the same, but description different?

Also, is it possible to have this work on nodes referenced further up the tree, say how about the following:

<root>
   <customers index="1">
        <customer firstname="Joe" lastname="Bloggs" description="Member of the Bloggs family"/>
        <customer firstname="Joe" lastname="Soap" description="Member of the Soap family"/>
        <customer firstname="Fred" lastname="Bloggs" description="Member of the Bloggs family"/>
        <customer firstname="Jane" lastname="Bloggs" description="Is a member of the Bloggs family"/>
   </customers>
   <customers index="2">
        <customer firstname="J" lastname="Bloggs" description="Member of the Bloggs family"/>
        <customer firstname="J" lastname="Soap" description="Is a member of the Soap family"/>
        <customer firstname="J" lastname="Smith" description="Member of the Smith family"/>
   </customers>
   <customers index="2">
        <customer firstname="J" lastname="Smith" description=""/>
        <customer firstname="A" lastname="Soap" description="Member of the Smith family"/>
   </customers>
</root>

So I want to pull the following nodes:

Jane Bloggs in index=1
J Soap in index=2
J Smith in index=3

Cheers again if you can help, hope I'm not pushing it ;)

Justin