[xsl] Unique id based on the position

Subject: [xsl] Unique id based on the position
From: Gábor Tóth <roysy@xxxxxxxx>
Date: Wed, 10 Nov 2010 09:58:48 +0000
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