RE: [xsl] Prior Instance of term in main text, before first glossary markup

Subject: RE: [xsl] Prior Instance of term in main text, before first glossary markup
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 28 Oct 2004 08:08:28 +0100
The crude way of testing whether a glossary term is its first appearance in
the document is

<xsl:if test="not(preceding::term[.=current()]))">...

However, this is very inefficient. A better approach is to use keys. This is
essentially the Muenchian grouping technique. Using the XPath 2.0 "is"
operator:

<xsl:key name="k" match="term" use="."/>

<xsl:if test=". is key('k', .)[1]">...

In 1.0 you can implement the "a is b" test as [generate-id(a) =
generate-id(b)] or as [count(a|b)=1].

Michael Kay
http://www.saxonica.com/


> -----Original Message-----
> From: David Riggs [mailto:dariggs@xxxxxxxxxxxxxx] 
> Sent: 28 October 2004 07:20
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Prior Instance of term in main text, before 
> first glossary markup
> 
> Dear XSL listers,
> 
> I am marking up foreign words so that I can display the 
> Japanese/Chinese
> characters in my text, but only for only the first usage of a 
> term, and
> also to have the stylesheet generate a glossary at the end. 
> Cutting and
> pasting and rewriting, it is easy to forget if I have already 
> "glossed" a
> term or not, and I cannot figure out a correct xsl test to 
> see if the term
> is properly marked up the first time it is used. That is to 
> say, I need to
> test to see if the word has been used before (in document 
> order) in the
> source tree, before the first glossary markup.
> 
> 
> It seems like it should be easy to check with a simple 
> <xsl:if test---> but
> I do not seem to be able to get it to work, and I do not see anything
> relevant in the archives.
> 
> If I have this source, to make the smallest example:
> 
> <p>The Buddhist way is zazen. When first practicing sitting meditation
> <mygloss><gr>zazen</gr><gk>==Japanese 
> Characters==</gk></mygloss> select a
> quiet place. </p>
> 
> And my stylesheet includes:
> 
> <xsl:template match="mygloss">
> <xsl:if test="contains(ancestor::text(), gr) or 
> contains(preceding::text(), gr)">
>         XXX ERROR-- NOT FIRST USAGE XXX
>       </xsl:if>
> <!----- rest  of template to put in italic, proper font, 
> check for first
> gloss markup of this word etc -->
> </xsl:template>
> 
> The above test does not find and output the error of the 
> earlier first use,
> i.e. when I forgot to gloss it when I first used in the 
> beginning of the 
> paragraph (or anywhere earlier, to make the general case).
> 
> I tried this test:
> 
> contains(ancestor::*, gr) or contains(preceding::*, gr)
> 
> But the test is always true, even if there is no prior use.
> 
> This following test works if the word is not further marked up in the
> paragraph, but of course it fails to look in end notes and such:
> 
> contains(ancestor::p/text(), gr) or contains(preceding::p/text(), gr)
> 
> So, in sum, how do I do this properly? And of course, a kind 
> explanation to
> get me out of my confusion about the xpath and xsl would be very much 
> appreciated.
> 
> David Riggs
> 
> International Research Center for Japanese Studies, Kyoto 

Current Thread