2008-09-15 17 views
8

Étant donné le code XML suivant:match conditionnellement à la valeur du noeud courant

<current> 
    <login_name>jd</login_name> 
</current> 
<people> 
    <person> 
    <first>John</first> 
    <last>Doe</last> 
    <login_name>jd</login_name> 
    </preson> 
    <person> 
    <first>Pierre</first> 
    <last>Spring</last> 
    <login_name>ps</login_name> 
    </preson> 
</people> 

Comment puis-je obtenir "John Doe" à l'intérieur du matcher courant/connexion?

J'ai essayé les éléments suivants:

<xsl:template match="current/login_name"> 
    <xsl:value-of select="../people/first[login_name = .]"/> 
    <xsl:text> </xsl:text> 
    <xsl:value-of select="../people/last[login_name = .]"/> 
</xsl:template> 

Répondre

10

je définir une clé pour indexer les personnes:

<xsl:key name="people" match="person" use="login_name" /> 

l'aide d'une clé ici conserve simplement le code propre, mais vous pourriez aussi être utile pour une efficacité si vous éprouvez souvent pour récupérer les <person> éléments basés sur leur <login_name> enfant.

j'aurais un modèle qui a renvoyé le nom d'un format donné <person>:

<xsl:template match="person" mode="name"> 
    <xsl:value-of select="concat(first, ' ', last)" /> 
</xsl:template> 

Et je ferais:

<xsl:template match="current/login_name"> 
    <xsl:apply-templates select="key('people', .)" mode="name" /> 
</xsl:template> 
+0

Bon, ignore ma réponse plus bas, celui-ci est génial.Propre et composé de belles pièces réutilisables. –

+0

je l'aime! merci ... jamais entendu parler de la clé xsl: avant ... –

0

Je pense que ce qu'il voulait en fait était le remplacement dans le match pour le noeud « en cours », pas un match dans le nœud de personne:

<xsl:variable name="login" select="//current/login_name/text()"/> 

<xsl:template match="current/login_name"> 
<xsl:value-of select='concat(../../people/person[login_name=$login]/first," ", ../../people/person[login_name=$login]/last)'/> 

</xsl:template> 
4

vous voulez current() fonction

<xsl:template match="current/login_name"> 
    <xsl:value-of select="../../people/person[login_name = current()]/first"/> 
    <xsl:text> </xsl:text> 
    <xsl:value-of select="../../people/person[login_name = current()]/last"/> 
</xsl:template> 

ou un peu plus propre:

<xsl:template match="current/login_name"> 
    <xsl:for-each select="../../people/person[login_name = current()]"> 
    <xsl:value-of select="first"/> 
    <xsl:text> </xsl:text> 
    <xsl:value-of select="last"/> 
    </xsl:for-each> 
</xsl:template> 
+0

thx pour la pointe en cours ... même si je n'aime vraiment pas l'utilisation de for-each dans xslt ... –

0

Juste pour ajouter mes pensées à la pile

<xsl:template match="login_name[parent::current]"> 
<xsl:variable name="login" select="text()"/> 
<xsl:value-of select='concat(ancestor::people/child::person[login_name=$login]/child::first/text()," ",ancestor::people/child::person[login_name=$login]/child::last/text())'/> 
</xsl:template> 

Je préfère toujours utiliser les axes explicitement dans mon XPath, à mon humble avis plus bavard mais plus clair. En fonction de l'aspect du reste des documents XML (en supposant qu'il ne s'agisse que d'un fragment), vous devrez peut-être contraindre la référence à "ancestor :: people" par exemple en utilisant "ancestor :: people [1]" pour contraindre à l'ancêtre premier peuple.

1

Si vous avez besoin d'accéder à plusieurs utilisateurs, JeniT's <xsl:key /> approach est idéal.

Voici mon autre avis sur la question:

<xsl:template match="current/login_name"> 
    <xsl:variable name="person" select="//people/person[login_name = .]" /> 
    <xsl:value-of select="concat($person/first, ' ', $person/last)" /> 
</xsl:template> 

Nous assignons le nœud <person> sélectionné à une variable, nous utilisons la fonction concat() à la sortie le premier/dernier nom.

Il y a aussi une erreur dans votre exemple XML. Le noeud <person> se termine de manière incorrecte avec </preson> (faute de frappe)

Une meilleure solution pourrait être donnée si nous savions que la structure globale du document XML (avec nœuds racines, etc.)

+0

merci pour le conseil ... fonctionne très bien ... je ne sais pas pourquoi, je n'aime pas utiliser des variables dans xslt ... –