2010-03-10 9 views
2

Je suis nouveau à XSLT et je ne peut pas résoudre le problème suivant:Comment obtenir l'information et trier, un sous-ensemble d'éléments avec seulement des identifiants utilisant XSLT?

J'ai un fichier xml comme ceci:

<root> 
    <subset> 
     <e id="A"></e> 
     <e id="C"></e> 
    </subset> 

    <data> 
     <info id="A" order="3" name="ANode"></info> 
     <info id="B" order="4" name="BNode"></info> 
     <info id="C" order="1" name="CNode"></info> 
     <info id="D" order="2" name="DNode"></info> 
    </data> 
</root> 

Et je veux produire ceci:

<root> 
    <newnode id="C" order="1" name="CNode"></newnode> 
    <newnode id="A" order="3" name="ANode"></newnode> 
</root> 

Comme vous pouvez le voir l'idée est de "compléter" le sous-ensemble des identifiants en récupérant les informations respectives, et les trier en conséquence à leur ordre spécifié sur <data>.

Notez que <data> est supposé avoir beaucoup de nœuds enfants.

De plus, je sépare les nœuds avec l'information sur l'élément <data> des sous-ensembles d'identifiants, car j'aurai beaucoup de sous-ensembles et je ne veux pas avoir d'information répétée «partout».

Merci d'avance.

+0

+1 pour une belle première question (complète, bien formulé, bien formaté, pas des conneries). Beaucoup de questions de première heure que je vois score 0 sur 4 pour les critères mentionnés. – Tomalak

Répondre

1

Vous pouvez également désactiver le sous-ensemble en fonction de ce que vous pourriez avoir besoin de faire avec vos données réelles.

<xsl:output indent="yes" /> 

<xsl:key name="subset" match="e" use="@id" /> 

<xsl:template match="/"> 
    <root> 
    <xsl:for-each select="//info[count(key('subset',@id)[1]) &gt; 0]"> 
     <xsl:sort select="@order" data-type="number" /> 
     <newnode id="{@id}" order="{@order}" name="{@name}" /> 
    </xsl:for-each> 
    </root> 
</xsl:template> 

2

Les références croisées demandent l'aide des touches:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:output indent="yes"/> 

    <xsl:key name="k1" match="info" use="@id"/> 

    <xsl:template match="root"> 
    <xsl:copy> 
     <xsl:apply-templates select="subset/e"> 
     <xsl:sort select="key('k1', @id)/@order" data-type="number"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="e"> 
    <newnode id="{@id}" order="{key('k1', @id)/@order}" name="{key('k1', @id)/@name}"/> 
    </xsl:template> 

</xsl:stylesheet> 

Cela devrait faire pour l'échantillon d'entrée que vous avez présenté.

+0

+1 - La seule chose que je ferais différemment est que dans '' je stockerais la clé ('k1', @id) 'dans une variable, puisque j'en ai besoin deux fois. Je ne sais pas si cela fait beaucoup de différence, mais calculer deux fois la même valeur va à l'encontre de mes principes. ;) – Tomalak