Question

Étant donné le code XML suivant:

<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 &"; à partir de l'adaptateur actuel / de connexion?

J'ai essayé les solutions suivantes:

<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>
Était-ce utile?

La solution

Je définirais une clé pour indexer les personnes:

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

L'utilisation d'une clé ici maintient simplement le code propre, mais vous pouvez également la trouver utile pour l'efficacité si vous devez souvent récupérer les <person> éléments en fonction de leur <login_name> enfant.

J'aurais un modèle qui renvoyait le nom formaté d'un <>>

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

Et puis je ferais:

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

Autres conseils

Vous voulez une 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>

Si vous devez accéder à plusieurs utilisateurs, L’approche <xsl:key /> de JeniT est idéale.

Voici ma version alternative:

<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 attribuons le <person> nœud sélectionné à une variable, puis nous utilisons la fonction concat() pour générer le premier / dernier nom.

Il existe également une erreur dans votre exemple XML. Le noeud </preson> ne se termine pas correctement par <=> (typo)

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

Je pense que ce qu'il souhaitait en réalité, c'était le remplacement du match par le & "courant &"; noeud, pas de correspondance dans le noeud de la 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>

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, un IMHO plus détaillé mais plus clair.

En fonction de l'apparence 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 à "or :: people " par exemple, en utilisant " ancestor :: people [1] " contraindre au premier ancêtre du peuple.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top