How to get tag name of root element in an XML document w/ XSLT?

64,009

Solution 1

I think you want to retrieve the name of the outermost XML element. This can be done like in the following XSL sample:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:variable name="outermostElementName" select="name(/*)" />

  <xsl:template match="/">
    <xsl:value-of select="$outermostElementName"/>
  </xsl:template>
</xsl:stylesheet>

Please note that there is a slight difference in XPath terminology:

The top of the tree is a root node (1.0 terminology) or document node (2.0). This is what "/" refers to. It's not an element: it's the parent of the outermost element (and any comments and processing instructions that precede or follow the outermost element). The root node has no name.

See http://www.dpawson.co.uk/xsl/sect2/root.html#d9799e301

Solution 2

Use the XPath name() function.

One XPath expression to obtain the name of the top (not root!) element is:

       name(/*)

The name() function returns the fully-qualified name of the node, so for an element <bar:foo/> the string "bar:foo" will be returned.

In case only the local part of the name is wanted (no prefix and ":"), then the XPath local-name() function should be used.

Solution 3

Figured it out. The function name() given the parameter * will return foo.

Share:
64,009
Brian
Author by

Brian

Just a guy, getting by, with a little help from my stackoverflow friends.

Updated on December 16, 2020

Comments

  • Brian
    Brian over 3 years

    I'm interested in assigning the tag name of the root element in an xml document to an xslt variable. For instance, if the document looked like (minus the DTD):

    <foo xmlns="http://.....">
        <bar>1</bar>
    </foo>
    

    and I wanted to assign the string 'foo' to an xslt variable. Is there a way to reference that?

    Thanks, Matt

  • Dimitre Novatchev
    Dimitre Novatchev over 15 years
    @annakata: name() and local-name() are differnt. The OP clearly wants name(). Nowhere does he say that he wants the name stripped off any namespace prefix.
  • Diego Queiroz
    Diego Queiroz over 5 years
    Alternatively /*/name()
  • Dimitre Novatchev
    Dimitre Novatchev over 5 years
    @DiegoQueiroz, /*/name() will raise an error if one uses an XPath 1 processor, while name(/*) works nicely both with XPath 1.0 processors and with ones that implement versions higher than 1.0. So, 100% of the readers of this answer will benefit from it, while probably 80% will be frustrated by the failure to use /*/name()
  • Diego Queiroz
    Diego Queiroz over 5 years
    Good point, but sometimes you're not after compatibility. I was using a processor that forces me to specify a base XPath to loop (eg. /*), and then map the remaining XPath to fields. This way, my proposed solution was handy. But it is good to know it isn't compatible with older versions.