Input XML:
<doc>
<section>
<para>Paragraph 1</para>
<para>Paragraph 2</para>
<para>Paragraph 3</para>
</section>
<para>Paragraph 4</para>
<para>Paragraph 5</para>
<para>Paragraph 6</para>
</doc>
Required output:
<book>
<section>
<p class="para" id="0001">Paragraph 1</p>
<p class="para" id="0002">Paragraph 2</p>
<p class="para" id="0003">Paragraph 3</p>
</section>
<p class="para" id="0004">Paragraph 4</p>
<p class="para" id="0005">Paragraph 5</p>
<p class="para" id="0006">Paragraph 6</p>
</book>
I tried with following XSL but I am not getting desired output. Anyone could help me in this?
<xsl:template match="para">
<xsl:variable name="count" select="position()"/>
<p class="para" id="{$count}">
<xsl:apply-templates/>
</p>
</xsl:template>
The result I am getting is:
<p class="para" id="2">Paragraph 1</p>
<p class="para" id="4">Paragraph 2</p>
<p class="para" id="6">Paragraph 3</p>
<p class="para" id="4">Paragraph 4</p>
<p class="para" id="6">Paragraph 5</p>
<p class="para" id="8">Paragraph 6</p>
The xsl:number element has two possible uses. It can determine the sequence number for the current node and it can format a number for display in the output. The sequence number is the integer position of the current node in a source document (source tree).
Used to construct arbitrary sequences. It may select any sequence of nodes and/or atomic values, and essentially adds these to the result sequence. Category: instruction. Content: sequence-constructor.
XSLT <xsl:text> The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.
If you can use XSLT 2.0 you could use unparsed-text() ... Text File (Do not use the text file as direct input to the XSLT.) ! ITEM_NAME Item value !
Here's an option that isn't using xsl:for-each
or any xsl:variable
's...
XML Input
<doc>
<section>
<para>Paragraph 1</para>
<para>Paragraph 2</para>
<para>Paragraph 3</para>
</section>
<para>Paragraph 4</para>
<para>Paragraph 5</para>
<para>Paragraph 6</para>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<book>
<xsl:apply-templates select="@*|node()"/>
</book>
</xsl:template>
<xsl:template match="para">
<p class="para" id="{format-number(count(preceding::para)+1,'0000')}">
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
</xsl:stylesheet>
XML Output
<book>
<section>
<p class="para" id="0001">Paragraph 1</p>
<p class="para" id="0002">Paragraph 2</p>
<p class="para" id="0003">Paragraph 3</p>
</section>
<p class="para" id="0004">Paragraph 4</p>
<p class="para" id="0005">Paragraph 5</p>
<p class="para" id="0006">Paragraph 6</p>
</book>
A second option is instead of counting preceding::para
you could use xsl:number
...
<xsl:template match="para">
<p class="para">
<xsl:attribute name="id">
<xsl:number format="0000" level="any"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With