2012-01-13 4 views
2

Encore une fois sur les nœuds distincts (en se basant sur les valeurs d'attribut) dans l'ensemble de nœuds. Imagine u ont la structure suivante:Valeurs distinctes sur les jeux de nœuds XSLT

<struct> 
    <a> 
    <x id="1">a_1</x> 
    <x id="2">a_2</x> 
    <x id="3">a_3</x> 
    </a> 
    <b inherits="a"> 
    <x id="2">b_2</x> 
    </b> 
</struct> 

<struct/> peut contenir de multiples éléments comme <b/> qui héritent de la même <a/>. Dans le même temps, plusieurs éléments tels que <a/> sont autorisés. L'ordre de <a/> s et <b/> s est arbitraire. L'héritage est profond à un seul niveau.

Question: Comment créer un unique XPath qui sélectionne le nodeset suivant pour une donnée <b/>:

<x id="1">a_1</x> 
<x id="2">b_2</x> 
<x id="3">a_3</x> 

S'il vous plaît noter la valeur b_2 sur la deuxième ligne.

Des solutions à cela?

Mise à jour:

Le XPath resuting doit avoir la forme suivante: b[(magic_xpath)[@id=2]='b_2'], où magic_xpath sélectionne <x/> distinctes s de <a/> s et <b/> s.

La vraie vie <struct/> peut ressembler à ceci:

<struct> 
    <a> 
    <x id="1">a_1</x> 
    <x id="2">a_2</x> 
    <x id="3">a_3</x> 
    </a> 
    <b inherits="a"> 
    <x id="2">I don't match resulting XPath</x> 
    </b> 
    <b inherits="a"> 
    <x id="2">b_2</x> 
    </b> 
</struct> 
+0

Le sens de la mise à jour ne sont pas claires.Quel devrait être le résultat et pourquoi vous avez besoin de "' s distincts quand tous les éléments 'x' de votre mise à jour ont déjà des valeurs distinctes?> Veuillez mettre à jour la mise à jour pour qu'elle soit claire et non ambiguë –

Répondre

1

Utilisation:

$vB/x 
| 
    /*/*[name() = $vB/@inherits] 
       /x[not(@id = $vB/x/@id)] 

$vB est défini comme étant l'élément b.

Ce sélectionne l'union de tous les éléments et tous b/xx enfants (avec id attribut qui ne correspond pas à un b/x/@id attribut) des éléments struct/* (enfants de struct) dont le nom est la valeur de b/@inherits.

Ou, comme demandé par l'OP dans un commentaire - sans variables:

/*/b/x 
| 
    /*/*[name() = /*/b/@inherits] 
       /x[not(@id = /*/b/x/@id)] 

vérification complète basée XSLT:

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

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "/*/b/x 
    | 
     /*/*[name() = /*/b/@inherits] 
        /x[not(@id = /*/b/x/@id)] 

    "/> 
</xsl:template> 
</xsl:stylesheet> 

lorsque cette transformation est appliquée sur la condition (corrigé pour être bien formé) Document XML:

<struct> 
    <a> 
     <x id="1">a_1</x> 
     <x id="2">a_2</x> 
     <x id="3">a_3</x> 
    </a> 
    <b inherits="a"> 
     <x id="2">b_2</x> 
    </b> 
</struct> 

l'expression XPath unique est évaluée et les noeuds sélectionnés sont sortie:

<x id="1">a_1</x> 
<x id="3">a_3</x> 
<x id="2">b_2</x> 
+0

Merci pour cette réponse rapide! Mais, est-il possible de faire la même chose _without_ en déclarant une variable? –

+0

Oui, il suffit de remplacer '$ vB' par'/*/b' –

+0

@Savva Mikhalevski: J'ai édité la réponse avec une expression XPath qui ne fait référence à aucune –

Questions connexes