Re: [xsl] A tricksy XSL question: key(name,match,use="contains()")

Subject: Re: [xsl] A tricksy XSL question: key(name,match,use="contains()")
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Mon, 29 Aug 2005 07:23:49 +1000
So what's wrong with Jeni's answer? It is a very good solution.

Cheers,
Dimitre Novatchev

On 8/29/05, David Priest <priest@xxxxxx> wrote:
> After extensive web searching, I can not find a direct answer to this
> problem (which, I rather suspect, means it is not solvable -- at
> least, not using the approach I'm attempting!).
>
> I have an XML file in which sections are given an "@ids" attribute
> which look just like this:
>   <section ids="this-is-an-unfriendly-id  this-is-the-friendly-id">
>
> I need to identify the page on which the section starts, ie. for in-
> text references to that section.
>
> In those cases where the section contains only a single ID, the
> following works:
>   <xsl:key name="sectionkey" match="section" use="@ids" />
>   <fo:page-number-citation ref-id="{key('sectionkey', @refid)/./
> @ids}" />
>
> However, as shown above, some sections have two ids (one from the
> actual title as written, and an abbreviated one that will continue to
> work even if someone were to change the title).  Thus, I need to
> modify the XSL so that if @ids *contains* the refid, it is a match.
> Something like -- but this doesn't work! -- the following:
>   <xsl:key name="sectionkey" match="section" use="contains(@ids,
> $refid)" />
>   <fo:page-number-citation ref-id="{key('sectionkey', contains(@ids,
> @refid)/./@ids" />
>
> Is there a solution to this problem?  Either way, it should probably
> appear in the FAQ,
>   http://www.dpawson.co.uk/xsl/sect2/N4852.html
>
> Any hints and tips appreciated.
>
> Footnote: Jeni's answer follows.  I am documenting this question and
> answer for future reference; please do add your solutions, too!
>
> Hi David,
>
> > However, as shown above, some sections have two ids (one from the
> > actual title as written, and an abbreviated one that will continue to
> > work even if someone were to change the title).  Thus, I need to
> > modify the XSL so that if @ids *contains* the refid, it is a match.
> >
>
> As you've found, you can only use keys to locate nodes whose key value
> *exactly equals* a value you're searching for: you can't use
> contains() semantics.
>
> All that means is that, in general, you need to use normal XPath
> expressions to get at the relevant section, as in something like:
>
>   <fo:page-number-citation
>     ref-id="{//section[contains(@ids, $refid)]}" />
>
> (though probably not that, since you don't want all the content of the
> <section> element within the ref-id attribute).
>
> However, what you have is a more specialised situation, where a
> <section> can either have one or two ids in the ids attribute, and if
> there are two then they are space-separated. That being the case, you
> can construct a sectionkey key that indexes each of the sections by
> the appropriate ID using string manipulation functions. For example:
>
> <!-- sections that only have one id are indexed by that id -->
> <xsl:key name="sectionkey"
>          match="section[not(contains(@ids, ' '))]"
>          use="@ids" />
>
>
> <!-- sections that have two ids are indexed by the first and the
>      second -->
> <xsl:key name="sectionkey"
>          match="section[contains(@ids, ' ')]"
>          use="substring-before(@ids, ' ')" />
> <xsl:key name="sectionkey"
>          match="section[contains(@ids, ' ')]"
>          use="substring-after(@ids, ' ')" />
>
> Then you can do:
>
>    <fo:page-number-citation ref-id="{key('sectionkey', @refid)}" />
>
> as normal.
>
> Cheers,
>
> Jeni
>
> ---
>
>


--
Cheers,
Dimitre Novatchev
---------------------------------------
Harry did not ask how Dumbledore knew; ...but Harry had long since
learned that bangs and smoke were more often the marks of ineptitude
than expertise.

Current Thread