Re: [xsl] Generating ID key values

Subject: Re: [xsl] Generating ID key values
From: "Vasu Chakkera" <vasucv@xxxxxxxxx>
Date: Thu, 11 Dec 2008 10:34:49 +0000
>After restoring the nested translate expression in all its glory, this is
>almost what I want, except that it assumes that the input document is
>basically id-free. That is not correct: in the typical case Framemaker will

The solution that i gave does *not*  assume that the input document is ID free.
What it does is it defines templates for the ones that do not have
ids. and for the ones that has ids, it just copies the input tree to
the output. So it calls the   <xsl:template
name="copy-elem-giving-id"> for those elements that do not have the ID
attribute. For those that has ID, it just copies as is.





2008/12/11 Trevor Nicholls <trevor@xxxxxxxxxxxxxxxxxx>:
> Thank you for your reply, Vasu, and I will try the technique you suggested
> instead of using keys.
>
>> I see some issues in your stylesheet.
>>
>> First: Your complex use of translate function
>>
>> >  <xsl:variable name="id"
>> > select="translate(normalize-space(translate(.,translate(.,'
>> > abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
>> > ')),' ','_')" />
>>
>  ..
>> so You see, your first translate is not doing anything interesting. It
>> is translateing your current text to blank space.
>> your second translate is again not doing anything. It is translating
>> space into space in your current. text
>
> The translate(n-s(translate(.,translate(.,),),) construction actually
> replaces any non NCName characters with spaces and then replaces any
> sequence of spaces with a single underscore. It turns any arbitrary string
> value into a valid NCName. Or it would if it had some way of adjusting the
> result when the first character isn't an upper or lowercase letter, which is
> a modification I can't see how to do in XSL 1. Maybe it is impossible after
> all.
>
>> Next: Your use of Keys and the for each:
>>
>> Looking at what you really want, i think you are thinking in the
>> direction of over engineering ..
>
> You could well be right!
>
>> I think what you want is below.. try it out and let me know if this is
>> not what you want.
>
>        <xsl:template name="copy-elem-giving-id">
>                <xsl:variable name="id"
> select="translate(normalize-space(.),' ','_')" />
>                <xsl:copy>
>                        <xsl:attribute name="id">
>                                <xsl:value-of select="$id" />
>                                <xsl:variable name = "current-node-name"
> select="name(.)"/>
>                                <xsl:variable name = "current-node-val"
> select="$id"/>
>                                <xsl:variable name = "prefix"
> select="count(preceding-sibling::*[not(@id)][(name() =
> $current-node-name ) and  translate(normalize-space(.),' ','_') =
> $current-node-val])+1"/>
>                                <xsl:if test = "string($prefix)">
>                                        <xsl:text>-</xsl:text>
>                                </xsl:if>
>                                <xsl:value-of select = "$prefix"/>
>                        </xsl:attribute>
>                        <xsl:apply-templates select="@*" />
>                        <xsl:apply-templates />
>                </xsl:copy>
>        </xsl:template>
>
> After restoring the nested translate expression in all its glory, this is
> almost what I want, except that it assumes that the input document is
> basically id-free. That is not correct: in the typical case Framemaker will
> run the stylesheet every time a user saves a document and will fill in ids
> for any new titles etc. that hadn't already been given them.
>
> Cheers
> Trevor
>
>



-- 
Vasu Chakkera
Numerical Algorithms Group Ltd.
Oxford
www.vasucv.com

Current Thread