tags:

views:

201

answers:

2

How can XSL generate a unique id attribute for every element in an XML document using XSL where the id must be numeric? The XLS below works except that the generated ids are alphanumeric and I need numeric?

<?xml version='1.0' encoding='utf-8'?>  
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
    xmlns:msxsl='urn:schemas-microsoft-com:xslt' exclude-result-prefixes='msxsl'>  
    <xsl:output method='xml' indent='yes'/>  
    <xsl:template match='*'>  
      <xsl:copy>  
        <xsl:attribute name='ElementID'>  
          <xsl:value-of select='generate-id()'/>  
        </xsl:attribute>  
        <xsl:apply-templates/>  
      </xsl:copy>  
    </xsl:template>    
</xsl:stylesheet>  

Thank you.

+2  A: 

Switching using number() with level and count seems to have done the trick.

Thank you

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
    xmlns:msxsl='urn:schemas-microsoft-com:xslt' exclude-result-prefixes='msxsl'>
    <xsl:output method='xml' indent='yes'/>
    <xsl:template match='*'>
      <xsl:copy>
        <xsl:attribute name='ElementID'>
          <xsl:number level='any' count='*' />
        </xsl:attribute>
        <xsl:copy-of select="@*"/><!--copy of existing all attributes-->
        <xsl:apply-templates/>
      </xsl:copy>
    </xsl:template>  
</xsl:stylesheet>
emailgregn
This is valid XSLT 1.0, no need for XSLT 2.0 in this case. Just as well, since in your code you've changed the version number for XML, not XSLT. ;-)
markusk
Well spotted Markusk, 2.0 removed
emailgregn
Added <xsl:copy-of > to preserve existing attributes
emailgregn
*Hint*: If this is a general algorithm, it may be a good idea to select a very special name for the attribute, in order to minimize the possibility of any element having an attribute with that name -- for example use something as `__________id`. :)
Dimitre Novatchev
+2  A: 

You can alwas use:

concat(count(ancestor::node(), '00000000', count(preceding::node())))

Knowledgeable people such as Michael Kay warn that <xsl:number/> is not efficient (sometimes O(N^2)) and should be avoided if possible.

Dimitre Novatchev
That works too, I'll keep an eye on performance.
emailgregn