Re: [xsl] Unique id based on the position

Subject: Re: [xsl] Unique id based on the position
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Wed, 10 Nov 2010 10:45:13 +0000
I can't exactly work out your requirements from this, but it looks to me as if the third component of the number should use xsl:number level="any" rather than level="single".

Michael Kay
Saxonica

On 10/11/2010 09:58, Gabor Tsth wrote:
Dear All,

I wish to give a unique ID to an element (seg) based on his position
within another element. The unique id should be the position of the
div1, p and seg element. The problem is when the seg element is not
the direct child of p element, then the xsl:number from function
restarts the numbering.  See the exact problem below in the comment of
the output , sorry but I am not able to explain it very well.

Thanks a lot,

Gabor

The XML fiile is this:


<?xml-stylesheet type="text/xsl" href="IDGeneratingTest1NONAMESPACE.xsl"?>


<text>
     <body>
         <div1 xml:id="ch.2" corresp="#toc.2">
             <p>
                 <seg ID=" ">econdariamente</seg>
                 <seg ID=" ">Pandolfo</seg>
                 <seg ID=" ">et</seg>
                 <list>
                     <item>
                         <seg ID=" ">Bernardo</seg>
                         <seg ID=" ">miei</seg>
                     </item>
                 </list>
             <seg ID=" ">figli</seg>
             </p>

             <p>
                 <seg ID=" ">gli</seg>
                 <unclear>
                     <seg ID=" ">fermiate</seg>
                     <seg ID=" ">domandate</seg>
                 </unclear>
                 <seg ID=" ">prima</seg>
                 <seg ID=" ">diligentemente</seg>

             </p>
         </div1>
     </body>
</text>

The stylesheet that I am using is this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0">

     <xsl:template match="@*|node()|comment()|processing-instruction()"
priority="-5">
         <xsl:copy>
             <xsl:apply-templates
select="@*|node()|comment()|processing-instruction()"/>
         </xsl:copy>
         <xsl:apply-templates select="//text/body/p//seg"/>
     </xsl:template>

<xsl:template match="@ID">
         <xsl:attribute name="xml:id">

             <xsl:for-each select="ancestor::seg/ancestor::p/ancestor::div1">
                 <xsl:number from="//text/body"/>.</xsl:for-each>

             <xsl:for-each select="ancestor::seg/ancestor::p">
                 <xsl:number from="//text/body/div1"/>.</xsl:for-each>

             <xsl:for-each select="ancestor::seg">
                 <xsl:number from="//text/body/div1/p"/>
             </xsl:for-each>

</xsl:attribute>

     </xsl:template>
</xsl:stylesheet>


Output:


<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl"
href="IDGeneratingTest1NONAMESPACE.xsl"?>
<text>
     <body>
         <div1 xml:id="ch.2" corresp="#toc.2">
             <p>
                 <seg xml:id="1.1.1">econdariamente</seg>
                 <seg xml:id="1.1.2">Pandolfo</seg>
                 <seg xml:id="1.1.3">et</seg>
                 <list>

                     <item>
                         <seg xml:id="1.1.1">Bernardo</seg>

                         <!-- I don't want that the numbering restarts
here, I wish to count the seg
                             elements from the p element, so ideally,
here the xml:id should be 1.1.4, and then 1.1.5 but I I see
                             what is the problem but I don't find the trick.-->

                         <seg xml:id="1.1.2">miei</seg>
                     </item>
                 </list>
                 <seg xml:id="1.1.4">figli</seg>
             </p>


<p> <seg xml:id="1.2.1">gli</seg> <unclear> <seg xml:id="1.2.1">fermiate</seg>

                     <!-- The problem is again the same, the xml:id
should 1.2.2-->

                      <seg xml:id="1.2.2">domandate</seg>
                 </unclear>
                 <seg xml:id="1.2.2">prima</seg>

<seg xml:id="1.2.3">diligentemente</seg>

             </p>
         </div1>
     </body>
</text>

Current Thread