2010-06-09 6 views
1

Si j'ai quelques xml comme:XPath: Comment vérifier plusieurs attributs entre les nœuds similaires

<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> 

Comment puis-je obtenir, en XPath pur - pas XSLT - une expression XPath qui détecte les lignes où lastname est le même , mais a une description différente? Donc, il tirerait le dernier nœud ci-dessus?

+1

Vous devez définir les exigences de sortie d'une manière plus formelle. Dites, il y a 4 nœuds avec le même nom, mais 2 d'entre eux partagent la description X, et 2 autres partagent une description différente Y. Qui devrait être dans la sortie? En outre, que se passe-t-il si l'entrée a des nœuds avec des noms de famille différents? Que se passe-t-il si un groupe particulier de nœuds (défini par le nom de famille) ne contient qu'un seul nœud - l'afficher ou non? –

+0

Bonne question (+1). Voir ma réponse pour une expression XPath qui sélectionne les nœuds désirés. :) –

Répondre

1

Comment puis-je obtenir, dans XPath pur - pas XSLT - une expression XPath qui détecte les lignes où est le même nom, mais a une description différente?

Voici comment faire avec une seule expression XPath:

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

Cette expression sélectionne tous <customer> éléments avec attribut lastname égal à "Bloggs" et valeur différente de l'attribut description.

Les noeuds sélectionnés sont:

<customer firstname="Joe" lastname="Bloggs" description="Member of the Bloggs family"/> 
<customer firstname="Jane" lastname="Bloggs" description="Is a member of the Bloggs family"/> 
+0

Donc, il n'est pas possible de le faire pour tous les noms de famille à la fois? – svick

0
/root/customers/customer[@lastname='Bloggs' 
    and not(@description = preceding-sibling::*[@lastname='Bloggs']/@description) 
    and not(@description = following-sibling::*[@lastname='Bloggs']/@description)] 

Il serait mieux de le faire réaliser par étapes, cependant.

0

Hé les gars, merci, c'est génial!

Cependant, cela fonctionne bien si je ne fais que cibler la famille Bloggs, mais est-il possible de généraliser cela, de sorte qu'il fonctionne pour tous les nœuds qui ont le même nom, mais une description différente?

Aussi, est-il possible d'avoir ce travail sur les nœuds référencés plus haut de l'arbre, par exemple comment sur les points suivants:

<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> 

Je veux tirer les nœuds suivants:

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

Bravo encore si vous pouvez aider, j'espère que je ne le pousse pas;)

Questions connexes