xsl-list
[Top] [All Lists]

RE: [xsl] Generating ID key values

2008-12-11 04:59:58
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



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>