Existe-t-il un nom d'élément XSLT?

101

Dans XSLT, il y a le

<xsl:value-of select="expression"/>

pour obtenir la valeur d'un élément, mais y a-t-il quelque chose pour sélectionner le nom de balise de l'élément?

Dans une situation comme celle-ci:

<person>
  <!-- required stuff -->
  <name>Robert</name>
  <!-- optional stuff, free form for future extension. 
       Using XMLSchema's xsd:any -->
  <profession>programmer</profession>
  <hobby>photography</hobby>
</person>

<xsl:for-each select="person">
   <xsl:tag-of select="."/> : <xsl:value-of select="."/>
</xsl:for-each>

Pour obtenir une sortie comme celle-ci:

name : Robert
profession : programmer
hobby : photography

Bien sûr, le XSLT ci-dessus ne se compilera pas car

 <xsl:tag-of select="expression"/>

n'existe pas. Mais comment cela pourrait-il être fait?

Robert Gould
la source
La balise la plus pertinente pour cette question est XPath. Les deux fonctions sont des fonctions standard XPath et peuvent être utilisées dans une expression XPath dans le contexte de n'importe quel langage d'hébergement (C #, XSLT, XQuery, ...) S'il vous plaît, re-tag
Dimitre Novatchev
Ce texte: "Dans XSLT, il y a <xsd: value-of select =" expression "/>" - contient une erreur. Le préfixe généralement utilisé pour les instructions XSLT est "xsl". Habituellement, lorsque nous utilisons XML Schema, nous utilisons le préfixe "xsd" ou "xs". Corrigez s'il vous plaît.
Dimitre Novatchev le

Réponses:

157

Cela vous donnera le nom de l'élément actuel (nom de la balise)

<xsl:value-of select ="name(.)"/>

OP-Edit: Cela fera également l'affaire:

<xsl:value-of select ="local-name()"/>
Utilisateur SO
la source
12
nom-local est ce que vous voulez 9 fois sur 10
annakata
20
local-name est sans espace de noms, c'est pourquoi il est généralement préférable.
Jon W
102

Personne n'a souligné la différence subtile dans la sémantique des fonctions name()et local-name().

  • name(someNode) renvoie le nom complet du nœud, et cela inclut le préfixe et deux-points au cas où le nœud est un élément ou un attribut.
  • local-name(someNode) renvoie uniquement le nom local du nœud, et cela n'inclut pas le préfixe et deux points au cas où le nœud est un élément ou un attribut.

Par conséquent, dans les situations où un nom peut appartenir à deux espaces de noms différents, il faut utiliser la name()fonction pour que ces noms soient toujours distingués.

Et, BTW, il est possible de spécifier les deux fonctions sans aucun argument :

name() est une abréviation pour name(.)

local-name() est une abréviation pour local-name(.)

Enfin , rappelez-vous que non seulement les éléments et les attributs ont des noms, ces deux fonctions peuvent également être utilisées sur les PI et sur ceux-ci elles sont identiques).

Dimitre Novatchev
la source
15
<xsl:for-each select="person">
  <xsl:for-each select="*">
    <xsl:value-of select="local-name()"/> : <xsl:value-of select="."/>
  </xsl:for-each>  
</xsl:for-each>
Ray Lu
la source
Comme bonne pratique, utilisez toujours normalize-space () lors de l’obtention de la valeur du nœud <xsl: value-of select = "normalize-space (.)" /> Cela réduira les espaces supplémentaires
Utilisateur SO
Une telle normalisation / désinfection ne serait nécessaire que si elle n'avait pas été gérée au stade de la collecte des entrées. Le faire évite alors d'avoir à le faire au moment de l'accès, qui est généralement beaucoup plus souvent. On le ferait avant d'ajouter à un RDB, et un document xml n'est qu'une autre base de données.
Patanjali
9

Pour les personnes intéressées, il n'y a pas:

<xsl:tag-of select="."/>

Cependant, vous pouvez recréer la balise / l'élément en allant:

<xsl:element name="{local-name()}">
  <xsl:value-of select="substring(.,1,3)"/>
</xsl:element>

Ceci est utile dans un modèle xslt qui, par exemple, gère le formatage des valeurs de données pour de nombreux éléments différents. Lorsque vous ne connaissez pas le nom de l'élément sur lequel vous travaillez et que vous pouvez toujours afficher le même élément, et modifier la valeur si nécessaire.

Tim
la source
6
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
Rowland Shaw
la source
Alors pourquoi cela a-t-il été voté? Certes, vous auriez pu mentionner local-name () si vous ne vouliez pas non plus l'espace de noms, mais il serait utile à la communauté plus large d'expliquer pourquoi cela ne fonctionnerait pas.
Rowland Shaw le
Peut-être qu'il ne pouvait pas transformer le XML donné. le nom (.) sera "personne" dans ce cas. il devrait s'agir de «nom», «profession» et «passe-temps».
Ray Lu
@CodeMelt Pourquoi alors n'avez-vous pas voté contre la réponse acceptée? C'est bien, mais c'est encore moins précis que celui-ci. J'ai voté à la hausse pour la réponse de Rowland Shaw car elle fournit la réponse à la question. Merci de voter uniquement lorsqu'une réponse contient des informations fausses, incorrectes ou trompeuses
Dimitre Novatchev
4
Correction de ce détail mineur - personnellement, je pense que les gens devraient expliquer pourquoi quelque chose est critiqué, car cela aide à expliquer les connaissances collectives ...
Rowland Shaw
Notre réputation peut attirer l'attention, mais comme elle ne garantit pas que ce que nous avons publié en vaut la peine, c'est la qualité de notre contribution qui compte vraiment. Aucun raisonnement ne conduit à des contributions de mauvaise qualité.
Patanjali