I am a beginner and still learning in XSLT. I have a simple xml code below:
<?xml version="1.0" encoding="UTF-8"?>
<order id="1021">
<items>
<item code="11">
<quantity>2</quantity
<price>50</price>
</item>
<item code="21">
<quantity>1</quantity>
<price>250</price>
</item>
<item code="13">
<quantity>4</quantity>
<price>100</price>
</item>
</items>
<status>3</status>
</order>
And I want to write an XSLT script which will convert it into a simple text array which contains all item codes. For example, the above xml should be converted as: [11,21,13]
I have written the following XSLT Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<!-- Template to match the root 'order' element -->
<xsl:template match="/order">
<!-- Start bracket for the array -->
<xsl:text>[</xsl:text>
<!-- Iterate over each item -->
<xsl:for-each select="items/item">
<!-- Output the code attribute -->
<xsl:value-of select="@code"/>
<!-- If not the last item, add a comma and space -->
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<!-- End bracket for the array -->
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
I am facing the problem in iterating over all items. I only get the code of the first item in output: [11]
Where as I am expecting the codes of all items like: [11,21,13]
Kindly let me know if anyone can spot a mistake in my XSLT code. I have tried asking chatgpt for it but it was not much of a help.
Your XSLT 1.0 is perfectly working.
For comparison, please see below how it is much easier to implement in XSLT 2.0 and later versions.
In XSLT 2.0, <xsl:value-of>
was enhanced, and has a separator attribute.
XSLT, 2nd Edition by Doug Tidwell
For the reference: XSLT
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<order id="1021">
<items>
<item code="11">
<quantity>2</quantity>
<price>50</price>
</item>
<item code="21">
<quantity>1</quantity>
<price>250</price>
</item>
<item code="13">
<quantity>4</quantity>
<price>100</price>
</item>
</items>
<status>3</status>
</order>
XSLT 1.0
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<!-- Template to match the root 'order' element -->
<xsl:template match="/order">
<!-- Start bracket for the array -->
<xsl:text>[</xsl:text>
<!-- Iterate over each item -->
<xsl:for-each select="items/item">
<!-- Output the code attribute -->
<xsl:value-of select="@code"/>
<!-- If not the last item, add a comma and space -->
<xsl:if test="position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<!-- End bracket for the array -->
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
XSLT 2.0
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>[</xsl:text>
<xsl:value-of select="order/items/item/@code"
separator=", "/>
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
Output
[11, 21, 13]