tags:

views:

3164

answers:

4

In XSLT there is the

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

to get the value of an element, but is there something to select the tag-name of the element?

In a situation like this:

<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>

To get output like this:

name : Robert
profession : programmer
hobby : photography

Of course the above XSLT won't compile because

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

doesn't exist. But how could this be done?

+8  A: 

This will give you the current element name (tag name)

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

OP-Edit: This will also do the trick:

<xsl:value-of select ="local-name()"/>
Rashmi Pandit
Thanks I just found it too. Also <xsl:value-of select ="local-name()"/> will work
Robert Gould
local-name is what you want 9 times out of 10
annakata
local-name is sans namespace, this is why it's usually better.
Jweede
+1  A: 
   <xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
Rowland Shaw
So why'd this get down voted? Granted could've mentioned local-name() if you didn't want the namespace as well, but it would be useful to the wider community to explain why this wouldn't work.
Rowland Shaw
Perhaps, it couldn't transform the given XML. the name(.) will be "person" in this case. it should be "name", "profession" and "hobby".
codemeit
@CodeMelt Why then you didn' downvote the accepted answer? It good, but is even less specific than this one. I up-voted Rowland Shaw's answer as it provides the answer to the question. Plese, downvote only when an aswer contains wrong, incorrect or misleading information
Dimitre Novatchev
Fixed that minor detail - personally, i think that people should explain why something is downvoted, as it helps explain the collective knowledge...
Rowland Shaw
+1  A: 
  <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>
codemeit
As a good practice always usenormalize-space() when getting value-of the node<xsl:value-of select="normalize-space(.)"/>This will trim the extra spaces
Rashmi Pandit
@Rashimi, thanks for point this out.
codemeit
+7  A: 

Nobody did point the subtle difference in the semantics of the functions name() and local-name().

  • name(someNode) returns the full name of the node, and that includes the prefix and colon in case the node is an element or an attribute.
  • local-name(someNode) returns only the local name of the node, and that doesn't include the prefix and colon in case the node is an element or an attribute.

Therefore, in situations where a name may belong to two different namespaces, one must use the name() function in order for these names to be still distinguished.

And, BTW, it is possible to specify both functions without any argument:

name() is an abbreviation for name(.)

local-name() is an abbreviation for local-name(.)

Finally, do remember that not only elements and attributes have names, these two functions can also be used on PIs and on these they are identical).

Dimitre Novatchev