Home > Blockchain >  XSL Position doesn't count correctly
XSL Position doesn't count correctly

Time:10-06

I've been trying a couple of days to resolve this XML transform problem. I need to add to the XML tags the "identifier" attribute with the sequential number via the XSLT file. I need to specify that the XSLT version is the 1.0. P.S. The code worked previously on Internet Explorer but the transform was inovked via JavaScript, thing that I cannot do now because of the newer browser support necessity. For anyone asking, that's a very old piece of code that the client don't want to change. I also tried to invoke the script via external file but that didn't work either.

That's the XSL:

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" > 
  <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:attribute name="identifier">
        <xsl:value-of select = "position()" />
      </xsl:attribute>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet> 

There you have the XML instead:

<?xml version="1.0" ?>
<root>
  <topic codice="02220020070748129" coobbligati="0" coobbligatiInfo="Unico Intestatario" status="0" statusWorkInProgress="0" imp1="22285" imp2="0" messaggio="" code="0">
    <fDi>-1</fDi>
    <art>
      <comp message="" code="0" importo="22285" numero="14" flag="0" messageEcc="" codeEcc="0"/>
      <def message="" code="0" importo="0" numero="0" flag="0" messageEcc="" codeEcc="0"/>
      <sel message="" code="0" importo="0" numero="0" flag="0" messageEcc="" codeEcc="0"/>
    </art>
    <datascad>0</datascad>
    <orig>0</orig>
    <sosp>0</sosp>
  </topic>
</root>

Now, using the XSLT in the example the result are definetly wrong, counting numbers also for the attributes and tag closing. An example underneath:

<?xml version="1.0"?>
<root identifier="1">
  <topic identifier="2" codice="02220020070748129" coobbligati="0" coobbligatiInfo="Unico Intestatario" status="0" statusWorkInProgress="0" imp1="22285" imp2="0" messaggio="" code="0">
    <fDi identifier="11">-1</fDi>
    <art identifier="13">
      <comp identifier="2" message="" code="0" importo="22285" numero="14" flag="0" messageEcc="" codeEcc="0"/>
      <def identifier="4" message="" code="0" importo="0" numero="0" flag="0" messageEcc="" codeEcc="0"/>
      <sel identifier="6" message="" code="0" importo="0" numero="0" flag="0" messageEcc="" codeEcc="0"/>
    </art>
    <datascad identifier="15">0</datascad>
    <orig identifier="17">0</orig>
    <sosp identifier="19">0</sosp>
  </topic>
</root>

Instead, the result I need is as it follows:

<?xml version="1.0"?>
  <root identifier="1">
    <topic identifier="2" codice="02220020070748129" coobbligati="0" coobbligatiInfo="Unico Intestatario" status="0" statusWorkInProgress="0" imp1="22285" imp2="0" messaggio="" code="0">
      <fDi identifier="3">-1</fDi>
      <art identifier="4">
      <comp identifier="5" message="" code="0" importo="22285" numero="14" flag="0" messageEcc="" codeEcc="0"/>
      <def identifier="6" message="" code="0" importo="0" numero="0" flag="0" messageEcc="" codeEcc="0"/>
      <sel identifier="7" message="" code="0" importo="0" numero="0" flag="0" messageEcc="" codeEcc="0"/>
    </art>
    <datascad identifier="8">0</datascad>
    <orig identifier="9">0</orig>
    <sosp identifier="10">0</sosp>
  </topic>
</root>

Thanks in advance for every contribute.

CodePudding user response:

Your approach has two problems:

  1. You are assigning an identifier to every node (element, attribute, text) in the XML document);

  2. The position() function works in the current context, not in the entire XML document.

I guess you want to do:

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:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:copy>
        <xsl:attribute name="identifier">
            <xsl:number count="*" level="any"/>
        </xsl:attribute>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • Related