Subject: RE: Generating ID key values
From: "Trevor Nicholls" <trevor@xxxxxxxxxxxxxxxxxx>
Date: Thu, 11 Dec 2008 22:59:24 +1300
|
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
|