Retrieve all the attribute values from XML using XSLT

25,221

Solution 1

try the following:

<xsl:template match="/">
 <xsl:for-each select="names/name/@*">
        <xsl:value-of select="concat( ., ' ')"/>
  </xsl:for-each>
</xsl:template>     

Solution 2

Because I'm not sure if the use of xsl:value-ofis a hard requirement, perhaps something like the following could be what you are locking for.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <xsl:template match="name" mode ="print" >
        <xsl:value-of select="@firstname"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="@lastname"/>
        <xsl:value-of select="@divider"/>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates  select="names/name" mode="print"/>
    </xsl:template>

</xsl:stylesheet>

You can use <xsl:apply-templates select="names/name" mode="print"/> at any position you have considered about using a one line value-of for all attributes.
The above template will generate the following output:

Rocky Balboa, Ivan Drago,

Update crate output without using the attribute names:

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

    <xsl:template match="name" mode ="print" >
        <xsl:for-each select="@*" >
            <xsl:if test="not(position() = last() or position() = 1)">
                <xsl:text> </xsl:text>
            </xsl:if>
            <xsl:value-of select="."/>

        </xsl:for-each>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates  select="names/name" mode="print"/>
    </xsl:template>

</xsl:stylesheet>

Solution 3

You can use this XPath @* to get all attributes, e.g.:

<xsl:template match="/*">
    <xsl:for-each select="@*">
        <xsl:value-of select="concat(name(), ': ', ., ' ')"/>
    </xsl:for-each>
</xsl:template>

This will let you use just one value-of select to get the output you want. It will take all attribute into consideration.

This should be a sufficient hint for you to figure out things. Let me know if you have any other question.

Share:
25,221
Erik Åstrand
Author by

Erik Åstrand

Updated on February 11, 2020

Comments

  • Erik Åstrand
    Erik Åstrand about 4 years

    I can't figure out how to access all the attributes in a tag from an XML document.

    Let's say I have the following XML:

    <names>
      <name firstname="Rocky" lastname="Balboa" divider=", "/>
      <name firstname="Ivan" lastname="Drago" divider=", "/>
    </names>
    

    I want the following output: Rocky Balboa, Ivan Drago,

    What I currently have is:

    <xsl:for-each select="names/name">
       <xsl:value-of select="@firstname"/>
       <xsl:value-of select="@lastname"/>
       <xsl:value-of select="@divider"/>
    </xsl:for-each>
    

    What I'm wondering is if it's possible to do this in just one value-of select instead of having to do three of them. So to clarify, I want to be able to output all the attributes in the tag with one single value-of select. Is this possible?

    Thanks.

  • hr_117
    hr_117 almost 11 years
    This has not much to do with the request. You are generating something like firstname: Ivan lastname:... (if any). But requested is: Rocky Balboa, Ivan Drago,
  • Erik Åstrand
    Erik Åstrand almost 11 years
    I must have explained myself wrong. I'm wondering if its possible to print out all the attributes, not but calling the names of the attributes. Something like value-of select "*" or along those lines.
  • Erik Åstrand
    Erik Åstrand almost 11 years
    Hey. Thanks for the reply. I'm not acually wondering how to print out all the attributes in one line by calling the acual names of the attributes. I'm looking for a way to simply call all the attributes, regardless of the names. Something along these lines: value-of select = " * ". Something that can print all the attributes, but not by calling them individually.
  • Daniel Haley
    Daniel Haley almost 11 years
    @ErikÅstrand - That's what <xsl:value-of select="@*[not(name()='divider')]" separator=" "/> does except that it ignores the divider attribute. You could also do <xsl:value-of select="@*" separator=" "/>, but you wouldn't be guaranteed that divider would be the last output.
  • Baerkins
    Baerkins over 4 years
    Lolz - upvoting an answer about XSLT in 2019 - this works great tho!