Возможно, вам удастся собрать решение, которое кажется работающим, но есть неотъемлемая проблема, и ваше решение сломается.
Проблема в том, что атрибуты в XML не имеют значительного порядка. Вы не можете полагаться на атрибуты, представленные какому-либо процессу, в XSLT или вне его, в том же порядке, в котором они появляются в тексте. Честно говоря, я удивлен, что XSLT даже позволяет вам использовать position()
в предикате атрибута.
(Кстати, по этой причине преобразование идентичности использует этот нечетный шаблон select="node()|@*"
. Требуется @*
, поскольку node()
не соответствует атрибутам. node()
не соответствует атрибутам, поскольку атрибуты не являются ' узлы t. Узлы имеют позицию, а атрибуты - нет.)
Если ваше приложение зависит от порядка атрибутов, оно сломано, и вам необходимо изменить его.
Однако есть выход, если вы можете полагаться на имена атрибутов для обеспечения некоторого порядка, как показано в вашем примере:
<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>
Это уродливо? Вы ставите. И это сломается, если вы когда-нибудь измените свою схему именования атрибутов. Но это будет работать, однако атрибуты упорядочены.