User04
User04

Reputation: 41

xml to csv transformation value incrementation

i would like to transform an xml file to csv ( the structure above) and count the number of low nodes, i try to use

 <xsl:value-of select="position()"/>

and number but i get always 1231212 what i would like to get is 1234567

<root>
    <row>
        <low id="1d" name="bio">FNO</low>
        <low id="1d" name="bbn">NBN</low>
         <low id="1d" name="afs">CAA</low>
    </row>
    <row>
        <low id="1a" name="adn">VHH</low>
        <low id="1d" name="bio">ADN</low>
    </row>
<row>
        <low id="1r" name="rio">BOA</low>
        <low id="1f" name="flo">KGG</low>
    </row>
</root>

someone can help please? thank you

the desired output :

 row  low  id name
  row1 low1  1d bio
  row1 low2  1c bbn
  row1 low3  1d afs
  row2 low4  1a adn
....

used xsl

<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="/root">
    <xsl:apply-templates select="row/low"/>
  </xsl:template>

  <xsl:template match="low">
    <xsl:value-of select="concat(position(),',',.,'&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

Upvotes: 0

Views: 44

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52888

Try using xsl:number

Example...

XML Input

<root>
    <row>
        <low>FNO</low>
        <low>NBN</low>
        <low>CAA</low>
    </row>
    <row>
        <low>VHH</low>
        <low>ADN</low>
    </row>
    <row>
        <low>BOA</low>
        <low>KGG</low>
    </row>
</root>

XSLT 1.0

<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="low">
    <xsl:number level="any"/>
    <xsl:value-of select="concat(',',.,'&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

Output

1,FNO
2,NBN
3,CAA
4,VHH
5,ADN
6,BOA
7,KGG

Alternatively, if you change the node set being processed, position() will work. In the example below, the only nodes being processed are low so position() works (produces the same output as above)....

<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="/root">
    <xsl:apply-templates select="row/low"/>
  </xsl:template>

  <xsl:template match="low">
    <xsl:value-of select="concat(position(),',',.,'&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

This would come in handy if you had to do something like sort the low's before outputting the position. (You would just add <xsl:sort/> to the xsl:apply-templates.)


EDIT

Here's another example using your updated input and desired output. This output is a little different than your desired output because it is comma separated. Replace the commas with whatever separator you want.

XML Input

<root>
    <row>
        <low id="1d" name="bio">FNO</low>
        <low id="1d" name="bbn">NBN</low>
        <low id="1d" name="afs">CAA</low>
    </row>
    <row>
        <low id="1a" name="adn">VHH</low>
        <low id="1d" name="bio">ADN</low>
    </row>
    <row>
        <low id="1r" name="rio">BOA</low>
        <low id="1f" name="flo">KGG</low>
    </row>
</root>

XSLT 1.0

<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="/root">
    <xsl:text>row,low,id,name&#xA;</xsl:text>    
    <xsl:apply-templates select="row/low"/>
  </xsl:template>

  <xsl:template match="low">
    <xsl:text>row</xsl:text>
    <xsl:number count="row"/>
    <xsl:value-of select="concat(',low',position(),',',@id,',',@name,'&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

Output

row,low,id,name
row1,low1,1d,bio
row1,low2,1d,bbn
row1,low3,1d,afs
row2,low4,1a,adn
row2,low5,1d,bio
row3,low6,1r,rio
row3,low7,1f,flo

Upvotes: 1

Related Questions