10

What's the way to get a tag name and attribute name in XML?

If I have a XML file like this:

<a>
<apple color="red"/>
<banana color="yellow"/>
<sugar taste="sweet"/>
<cat size="small"/>
</a>

And part of my XSLT file is as below:

<xsl:element name="AAA">
<???>
</xsl:element>

So what should I write in the ??? part so I can get the output like this:

For tag name:

<AAA>apple</AAA>
<AAA>banana</AAA>
<AAA>sugar</AAA>
<AAA>cat</AAA>

For attribute name:

<AAA>color</AAA>
<AAA>color</AAA>
<AAA>taste</AAA>
<AAA>size</AAA>
2
  • Can you show us what you've tried so far? And for the record, your example is not a valid XML file. Commented Dec 15, 2011 at 15:14
  • Is that the entire XML document? It's not well-formed. Can you show more context? Commented Dec 15, 2011 at 15:15

3 Answers 3

16

Tag name:

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

Attribute name of the first (!) attribute. If you have more attributes, you'd have to choose a different approach

<xsl:value-of select="name(@*[1])"/>

Both expressions would then be used in a template matching your input elements. e.g.

<xsl:template match="*">
  <xsl:element name="AAA">
    <!-- ... -->
  </xsl:element>
</xsl:template>
Sign up to request clarification or add additional context in comments.

1 Comment

@_Lucas Eder: <xsl:template match="//*"> can be written properly as: <xsl:template match="*"> . It is meaningless for a match expression to be absolute and in very few cases it consists of more than one location step.
4

Output the name of an element or attribute using one of name() or local-name():

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

Assume this document:

<root>
    <apple color="red"/>
    <banana color="yellow"/>
    <sugar taste="sweet"/>
    <cat size="small"/>
</root>

Then this stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="/*/*"/>
            <xsl:apply-templates select="/*/*/@*"/>
        </root>
    </xsl:template>
    <xsl:template match="*|@*">
        <AAA><xsl:value-of select="local-name()"/></AAA>
    </xsl:template>
</xsl:stylesheet>

Produces:

<root>
   <AAA>apple</AAA>
   <AAA>banana</AAA>
   <AAA>sugar</AAA>
   <AAA>cat</AAA>
   <AAA>color</AAA>
   <AAA>color</AAA>
   <AAA>taste</AAA>
   <AAA>size</AAA>
</root>

Notice that both elements and attributes are handled by the same template.

Comments

3

This is probably one of the shortest solutions:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="*/*|@*">
  <AAA>
   <xsl:value-of select="name()"/>
  </AAA>
   <xsl:apply-templates select="@*"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document (your fragment wrapped into a top element):

<things>
    <apple color="red"/>
    <banana color="yellow"/>
    <sugar taste="sweet"/>
    <cat size="small"/>
</things>

the wanted, correct result is produced:

<AAA>apple</AAA>
<AAA>color</AAA>
<AAA>banana</AAA>
<AAA>color</AAA>
<AAA>sugar</AAA>
<AAA>taste</AAA>
<AAA>cat</AAA>
<AAA>size</AAA>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.