2010-06-22 6 views
0

Dans l'exemple XML, il existe deux formes qui correspondent au nombre et au type; dans la deuxième forme correspondante j'ai besoin de vider la valeur de l'élément flag. Je ne peux pas changer le niveau que je suis en train d'itérer en raison de certaines feuilles de style interdépendantes. Je peux faire preceding-sibling si j'étais itératif sur formslist mais je ne peux pas sembler obtenir la syntaxe correcte quand je suis un niveau plus profond sur l'élément flag. Le nombre et le type doivent correspondre avant de l'effacer.le parent précédent avec une torsion

<apply-templates match="formslist/flag"> 
<xsl:choose> 
    <xsl:when test=""></xsl:when> 
</xsl:choose> 
</apply-templates> 

XML Exemple

<forms> 
    <formslist> 
     <number>one</number> 
     <type>car</type> 
     <flag>da</flag> 
    </formslist> 
    <formslist> 
     <number>two</number> 
     <type>truck</type> 
     <flag>ex</flag> 
    </formslist> 
    <formslist> 
     <number>one</number> 
     <type>car</type> 
     <flag>da</flag> 
    </formslist> 
</forms> 
+0

Votre question est un peu déroutante. Si vous voulez obtenir le parent 'formslist' de votre' flag' actuel, vous devez utiliser '" .. "'. Pour une meilleure réponse, vous devez fournir une sortie désirée et une feuille de style complète. –

+0

Bonne question (+1). Voir ma réponse pour une solution complète et efficace. –

Répondre

1

Cette transformation:

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

<xsl:key name="kFlag" match="formslist/flag" 
    use="concat(../number, '+', ../type)"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
"flag/text()[generate-id(..) 
      != 
      generate-id(key('kFlag', 
          concat(../../number, 
            '+', 
            ../../type 
            ) 
          )[1] 
         ) 
      ] 
"/> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML fourni:

<forms> 
    <formslist> 
     <number>one</number> 
     <type>car</type> 
     <flag>da</flag> 
    </formslist> 
    <formslist> 
     <number>two</number> 
     <type>truck</type> 
     <flag>ex</flag> 
    </formslist> 
    <formslist> 
     <number>one</number> 
     <type>car</type> 
     <flag>da</flag> 
    </formslist> 
</forms> 

produit le résultat souhaité, correct:

<forms> 
    <formslist> 
     <number>one</number> 
     <type>car</type> 
     <flag>da</flag> 
    </formslist> 
    <formslist> 
     <number>two</number> 
     <type>truck</type> 
     <flag>ex</flag> 
    </formslist> 
    <formslist> 
     <number>one</number> 
     <type>car</type> 
     <flag/> 
    </formslist> 
</forms> 

Ne note l'utilisation de la méthode Muenchian pour le regroupement, ce qui est significativement plus rapide que l'utilisation de la comparaison à preceding-sibling::* (le dernier a une performance quadratique O(N^2)).

0

Lorsque évalué dans le match de modèle pour un flag cela devrait accomplir ce que vous recherchez:

<xsl:variable name="thisFormslist" select=".." /> 
    <flag> 
     <xsl:choose> 
      <xsl:when test="../preceding-sibling::*[$thisFormslist/number=number and $thisFormslist/type=type]"> 
       <!--number and type have been seen before, so don't put a value for this flag--> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="."/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </flag> 

Il crée une variable pour faire référence à la formslist actuelle élément, puis l'utilise dans le filtre de prédicat pour comparer les number et type à la e preceding-sibling éléments de l'élément parent (formslist).

Questions connexes