You may be able to combine a solution that works, but there is an inherent problem and your solution will break.
The problem is that the attributes in XML are not significant. You cannot rely on attributes that are presented to any process, in or from XSLT, in the same order that they display in the text. Honestly, I'm surprised that XSLT even allows you to use position() in an attribute predicate.
(By the way, this is the reason that identity conversion uses this odd pattern select="node()|@*" . @* Is required because node() does not match attributes. node() does not match attributes because attributes aren ' t nodes. Nodes have a position but no attributes.)
If your application depends on the order of the attributes, it will break and you need to redesign it.
However, there is a way out if you can rely on attribute names to provide some sort of order, as shown in your example:
<xsl:variable name="atts" select="@*"/> <xsl:for-each select="$atts"> <xsl:sort select="substring-after(name(), 'Node')" data-type="number"/> <td> <xsl:variable name="this" select="number(substring-after(name(), 'Node'))"/> <xsl:value-of select="sum($atts[ number(substring-after(name(), 'Node')) <= $this])"/> </td> </xsl:for-each>
Is it ugly? You are betting. And it breaks if you ever change the attribute naming scheme. But it will work, however the attributes are ordered.
source share