Re: [xsl] Stumped on XPath

Subject: Re: [xsl] Stumped on XPath
From: Spencer Tickner <spencertickner@xxxxxxxxx>
Date: Tue, 7 Feb 2006 15:21:05 -0800
I have been able to solve this,, although it's more than a little
embarissingly ugly:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
             xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:variable name="ALPHA">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>

<xsl:template match="doc">
<html>
<head/>
<body>
 <xsl:apply-templates/>
</body>
</html>
</xsl:template>

<xsl:template match="sentence">
 <p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="clause">
 <p class="clause"><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="strong">
<strong><xsl:apply-templates/></strong>
</xsl:template>
<xsl:template match="appendix"/>

<xsl:template match="id">
<xsl:variable name="myid" select="@ref"/>
 <xsl:text> (see Appendix </xsl:text>
 <xsl:value-of select="substring($ALPHA, count(//refnote[@id =
$myid]/ancestor::appendix/preceding-sibling::*[self::appendix]) + 1,
1)"/>
 <xsl:text>) </xsl:text>
</xsl:template>

</xsl:stylesheet>

As of now, it does seem to work against the test scenarios I've thrown at it.

Thanks,

On 2/7/06, Spencer Tickner <spencertickner@xxxxxxxxx> wrote:
> Hi David,
>
> Thanks for the response. Your solution does in fact work perfectly.
> The only problem is when I move the refnote element around (I used
> 1,2,3 for testing purposes however in truth these are more on the
> lines of 2341234, 245532139, etc.) I don't get the results I expect.
>
> example
>
> <?xml version="1.0"?>
> <doc>
>  <manual>
>  <sentence>This is a sentence with a reference<id ref="1"/> as an
> inline element</sentence>
>     <clause>This is a clause with inline elements <strong>
> and</strong> a reference <id ref="3"/></clause>
> </manual>
> <appendix>
>  <refnote id="1">This is the first reference</refnote>
>  <refnote id="3">This is the third reference</refnote>
>  </appendix>
>  <appendix>
>  <refnote id="2">This is the second reference</refnote>
> </appendix>
> </doc>
>
> Should give
>
> <html><head><META http-equiv="Content-Type"
content="text/html"></head><body>
>  <p>This is a sentence with a reference (see Appendix A)  as an
> inline element</p>
>     <p class="clause">This is a clause with inline elements <strong>
> and</strong> a reference  (see Appendix A) </p>
> </body></html>
>
> However I get
>
> <html><head><META http-equiv="Content-Type"
content="text/html"></head><body>
>  <p>This is a sentence with a reference (see Appendix A)  as an
> inline element</p>
>     <p class="clause">This is a clause with inline elements <strong>
> and</strong> a reference  (see Appendix B) </p>
> </body></html>
>
> Even though the id 3 is within the first (Appendix A) appendix element.
>
> Any other thoughts would be appreciated
>
>
> On 2/7/06, David Carlisle <davidc@xxxxxxxxx> wrote:
> >
> >
> > The trick with doing cross references in XSLT is always generate the
> > reference text _at the referenced node_ not on the referencing node.
> > then you can easily get the same number in the reference and in the
> > referenced heading. (Often by just calling a named template or special
> > mode that just does the numbering.
> >
> > So at the referencing element, first follow the link, then generate the
> > number:
> >
> > <xsl:stylesheet version="1.0"
> >               xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> >
> > <xsl:key name="r" match="refnote" use="@id"/>
> >
> > <xsl:template match="doc">
> > <html>
> > <head/>
> > <body>
> >  <xsl:apply-templates/>
> > </body>
> > </html>
> > </xsl:template>
> >
> > <xsl:template match="sentence">
> >   <p><xsl:apply-templates/></p>
> > </xsl:template>
> > <xsl:template match="clause">
> >  <p class="clause"><xsl:apply-templates/></p>
> > </xsl:template>
> > <xsl:template match="strong">
> > <strong><xsl:apply-templates/></strong>
> > </xsl:template>
> > <xsl:template match="appendix"/>
> > <xsl:template match="id">
> > <xsl:for-each select="key('r',@ref)">
> >  <xsl:text> (see Appendix </xsl:text>
> >  <xsl:number format="A"/>
> >  <xsl:text>) </xsl:text>
> > </xsl:for-each>
> > </xsl:template>
> >
> > </xsl:stylesheet>
> >
> >
> >
> > $ saxon refid.xml refid.xsl
> > <html>
> >    <head>
> >       <meta http-equiv="Content-Type" content="text/html;
> > charset=utf-8">
> >    </head>
> >    <body>
> >
> >
> >       <p>This is a sentence with a reference (see Appendix A)  as an
> >          inline element
> >       </p>
> >
> >       <p class="clause">This is a clause with inline elements <strong>
> >             and</strong> a reference  (see Appendix B)
> >       </p>
> >
> >
> >
> >
> >    </body>
> > </html>
> >
> > ________________________________________________________________________
> > This e-mail has been scanned for all viruses by Star. The
> > service is powered by MessageLabs. For more information on a proactive
> > anti-virus service working around the clock, around the globe, visit:
> > http://www.star.net.uk
> > ________________________________________________________________________

Current Thread