Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create sequence number in xslt

Tags:

xml

xslt

xslt-2.0

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>
like image 225
VSr Avatar asked Nov 26 '12 07:11

VSr


People also ask

How to Generate sequence number in XSLT?

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).

What is XSL sequence?

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.

What is text () in XSLT?

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.

How do I read a text file in XSLT?

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 !


1 Answers

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>
like image 140
Daniel Haley Avatar answered Oct 02 '22 07:10

Daniel Haley