2012-12-02 4 views
2

En utilisant XPath ou un XQuery, comment sélectionner le nœud ayant le plus d'occurrences d'un autre nœud?Comment trouver le noeud avec le plus grand nombre?

Par exemple, comment puis-je trouver le panier qui a le plus d'oeufs?

<basket name="1"> 
     <egg></egg> 
     <egg></egg> 
</basket> 
<basket name="2"> 
     <egg></egg> 
</basket> 
<basket name="3"> 
     <egg></egg> 
     <egg></egg> 
     <egg></egg> 
     <egg></egg> 
</basket> 

Répondre

3

C'est une solution (TIMTOWTDI):

let $nodes := <xml> 
    <basket name="1"> 
      <egg></egg> 
      <egg></egg> 
    </basket> 
    <basket name="2"> 
      <egg></egg> 
    </basket> 
    <basket name="3"> 
      <egg></egg> 
      <egg></egg> 
      <egg></egg> 
      <egg></egg> 
    </basket> 
</xml> 
let $max := max(for $c in $nodes//basket return count($c/egg)) 
return $nodes/basket[count(egg) = $max] 
+0

grand travail avec XQuery, +1 –

+0

Merci pour cela! L'exemple de code que j'ai posté était moins complexe que le problème que je devais résoudre. Cette solution était celle que je pouvais le plus facilement adapter. Merci également à @dimitri et Roman – Jack

0
<xml> 
    <basket name="1"> 
     <egg></egg> 
     <egg></egg> 
    </basket> 
    <basket name="2"> 
     <egg></egg> 
    </basket> 
    <basket name="3"> 
     <egg></egg> 
     <egg></egg> 
     <egg></egg> 
     <egg></egg> 
    </basket> 
</xml> 

vous pouvez essayer XPath comme ça

xml/basket[ 
    count(egg) > count(following-sibling::*/egg) and 
    count(egg) > count(preceding-sibling::*/egg) 
] 

ou si vous voulez compter non seulement des éléments d'œufs

xml/basket[ 
    count(child::*) > count(following-sibling::*/child::*) and 
    count(child::*) > count(preceding-sibling::*/child::*) 
] 
1

Ceci est à la fois un XPath 2.0 expression et un XQuery, qui sélectionne l'élément recherché (s):

/*/basket[egg[max(/*/basket/count(egg))]] 

XSLT 2.0 - vérification basée:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:sequence select="/*/basket[egg[max(/*/basket/count(egg))]]"/> 
</xsl:template> 
</xsl:stylesheet> 

Lorsque cette transformation est appliqué sur le document XML suivant (votre fragment XML fourni, enveloppé dans un seul élément supérieur pour devenir un document XML bien formé):

<t> 
    <basket name="1"> 
     <egg></egg> 
     <egg></egg> 
    </basket> 
    <basket name="2"> 
     <egg></egg> 
    </basket> 
    <basket name="3"> 
     <egg></egg> 
     <egg></egg> 
     <egg></egg> 
     <egg></egg> 
    </basket> 
</t> 

L'expression XPath est évaluée et le résultat de l'évaluation est copiée à la sortie:

<basket name="3"> 
     <egg/> 
     <egg/> 
     <egg/> 
     <egg/> 
    </basket> 

Prenez note:

Il n'y a pas une telle chose comme "la noeud avec le plus grand nombre d'occurrences d'un autre noeud ". En fait, selon le document XML réel, il peut y avoir de nombreux éléments qui contiennent le même nombre maximal d'autres éléments.

Si vous souhaitez obtenir juste un tel élément, dire le premier dans l'ordre du document, puis utilisez:

/*/basket[egg[max(/*/basket/count(egg))]][1] 
Questions connexes