Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort attributes in specific order for output

How do you write element attributes in a specific order without writing it explicitly?

Consider:

<xsl:template match="Element/@1|@2|@3|@4">
    <xsl:if test="string(.)">
        <span>
            <xsl:value-of select="."/><br/>
        </span>
    </xsl:if>
</xsl:template>

The attributes should appear in the order 1, 2, 3, 4. Unfortunately, you can't guarantee the order of attributes in XML, it could be <Element 2="2" 4="4" 3="3" 1="1">

So the template above will produce the following:

<span>2</span>
<span>4</span>
<span>3</span>
<span>1</span>

Ideally I don't want to test each attribute if it has got a value. I was wondering if I can somehow set an order of my display? Or will I need to do it explicitly and repeating the if test as in:

<xsl:template match="Element">

    <xsl:if test="string(./@1)>
        <span>
            <xsl:value-of select="./@1"/><br/>
        </span>
    </xsl:if>
    ...
    <xsl:if test="string(./@4)>
        <span>
            <xsl:value-of select="./@4"/><br/>
        </span>
    </xsl:if>
</xsl:template>

What can be done in this case?

like image 495
DashaLuna Avatar asked Dec 22 '22 05:12

DashaLuna


1 Answers

In an earlier question you seemed to use XSLT 2.0 so I hope this time too an XSLT 2.0 solution is possible.

The order is not determined in the match pattern of a template, rather it is determined when you do xsl:apply-templates. So (with XSLT 2.0) you can simply write a sequence of the attributes in the order you want e.g. <xsl:apply-templates select="@att2, @att1, @att3"/> will process the attributes in that order.

XSLT 1.0 doesn't have sequences, only node-sets. To produce the same result, use xsl:apply-templates in the required order, such as:

<xsl:apply-templates select="@att2"/>
<xsl:apply-templates select="@att1"/>
<xsl:apply-templates select="@att3"/>
like image 177
Martin Honnen Avatar answered Jan 05 '23 23:01

Martin Honnen