XSLT variable increment

I have an xml file like

<node> <elm val="data1"/> <elm val="data2"/> <elm val="data3"/> <elm val="data4"/> <elm val="data5"/> <elm val="data6"/> <elm val="data7"/> </node> 

I need to write xslt for this xml file that will be displayed in the fomat table, for example

  1 dat1 2 dat2 3 dat3 4 dat4 5 dat5 6 dat6 7 dat7 

please help me do this

+4
source share
5 answers
 <xsl:tempate match="node"> <table> <xsl:call-template select="elm"/> </table> </xsl:template> <xsl:template match="elm"> <tr> <td> <xsl:value-of select="count(preceding-sibling::elm) + 1"/> </td> <td> <xsl:value-of select="@val"/> </td> </tr> </xsl:template> 

Alternatively, if accurate output is required, use the following template for elm .

 <xsl:template match="elm"> <xsl:param name="pos" select="count(preceding-sibling::elm) + 1"/> <tr> <td> <xsl:value-of select="$pos"/> </td> <td> <xsl:text>dat</xsl:text> <xsl:value-of select="$pos"/> </td> </tr> </xsl:template> 

Or in case of text output:

 <xsl:tempate match="node"> <xsl:foreach select="elm"> <xsl:value-of select="count(preceding-sibling::elm) + 1"/> <xsl:text> dat</xsl:text> <xsl:value-of select="count(preceding-sibling::elm) + 1"/> <xsl:text disable-output-escaping="yes">&amp;#xA;</xsl:text> </xsl:foreach> </xsl:template> 
+2
source

This is not true :

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="elm"> <xsl:value-of select="concat(position(), ' ', @val)"/> </xsl:template> </xsl:stylesheet> 

When launched with many XSLT processors, this will lead to the following (undesirable) conclusion :

  2 data1 4 data2 6 data3 8 data4 10 data5 12 data6 14 data7 

The reason is that when templates are applied to children of the top element, this includes child nodes containing only white spaces between every two consecutive elm elements.

So, the Oded solution is wrong .

Here is one correct solution (and one of the shortest):

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="elm"> <xsl:value-of select="concat(position(), ' ', @val, '&#xA;')"/> </xsl:template> </xsl:stylesheet> 

This conversion gives the correct result :

 1 data1 2 data2 3 data3 4 data4 5 data5 6 data6 7 data7 

Please note :

  • Using <xsl:strip-space elements="*"/> to force the XSLT processor to discard any text nodes with only a space.

  • Using the XPath concat() function to glue the position, data, and NL character.

+2
source

You can use the position() function

 <xsl:template match="elm"> <xsl:value-of select="concat(position(), ' ', @val)" /> </xsl:template> 

Note. The table format in your example does not match the value of the val attribute, but I assumed that you want both to be the same (the output of the first row should be 1 data1 instead of 1 dat1 .

As @Dimitre Novatchev noted in his answer, this assumes your source document has no nodes with a space. In his answer, he addresses this by removing all nodes of only “white space” from the input document (using the <xsl:strip-space elements="*"/> directive) and adding a new line character ( &#xA; ) at the end of the concatenation .

+1
source
 <xsl:template match="node"> <table> <xsl:apply-templates select="elm"/> </table> </xsl:template> <xsl:template match="elm"> <tr> <td><xsl:value-of select="position()"/></td> <td>dat<xsl:value-of select="position()"/></td> </tr> </xsl:template> 
0
source

XSLT "variables" are immutable variables. After installing them, you cannot arbitrarily change them.

The only hacks around it are to use the position () function and other "+1" functions, but you do not get the flexibility of a true variable.

There are many articles about the irregularity of XSLT "variables".

Quote from the article " http://www.xml.com/pub/a/2001/02/07/trxml9.html "

XSLT variables actually have a lot in common with constants in many programming languages ​​and are used for a similar purpose.

Counters in XSLT are not possible because XSLT is not a procedural language, it is declarative. For downvoter: please indicate the reason. If this is not true, then please prove the opposite.

-1
source

Source: https://habr.com/ru/post/1310963/


All Articles