Home > OS >  Row counting including transformed nodes
Row counting including transformed nodes

Time:09-27

i need correct row-counting (in attribute pos="1", "2", etc) for the line element node which is partially tranforming from its child elements. Present counting-part of the XSLT-code doesn't work properly. I also tried to create a variable template that would count the required node, but so far the variable is useless because it is not entirely clear how to apply it in the next step.

Source XML

<?xml version="1.0" encoding="UTF-8"?>
<entry>

  <line id="001" att1="aaa" att2="bbb" att3="ccc"/>
  <line id="002" att1="ddd" att2="eee" att3="fff"/>
  <line id="003" att1="ggg" att2="hhh" att3="iii">

    <subline  x="name" z="lastname"/>
    <subline  x="name2" z="lastname2"/>
    <underline  a="bar" b="foo"/>
  </line>

</entry>

Desired output (anyhow pos= position among attributes can be any)

<?xml version="1.0" encoding="UTF-8"?><entry>
<entry>

  <line pos="1" id="001" att1="aaa" att2="bbb" att3="ccc"/>
  <line pos="2" id="002" att1="ddd" att2="eee" att3="fff"/>
  

  <line pos="3" id="003" att1="ggg" att2="hhh" att3="iii" x="name" z="lastname"/>
  <line pos="4" id="003" att1="ggg" att2="hhh" att3="iii" x="name2" z="lastname2"/>
  <line pos="5" id="003" att1="ggg" att2="hhh" att3="iii" a="bar" b="foo"/>

</entry>

Present XSLT code

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="line[*]">
    <xsl:apply-templates/>
  </xsl:template>

<xsl:template match="/">
  <xsl:for-each select="entry/line">
    <xsl:variable name="pos" select="position()" />
  </xsl:for-each>

  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

  <xsl:template match="line/*">
    <line  pos="{position()}">
      <xsl:copy-of select="../@* | @*"/>
    </line>
  </xsl:template>

</xsl:stylesheet>

CodePudding user response:

How about just:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/entry">
    <xsl:copy>
        <xsl:for-each select="line[not(*)] | line/*">
            <line pos="{position()}">
                <xsl:copy-of select="parent::line/@* | @*"/>
            </line>
        </xsl:for-each>     
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • Related