[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: Passing element nodes through string functions (WAS RE: [xsl] Preserving inline elements when using string functions)


Subject: Re: Passing element nodes through string functions (WAS RE: [xsl] Preserving inline elements when using string functions)
From: Brook Ellingwood <brook@xxxxxxxxxxx>
Date: Wed, 27 Aug 2003 20:40:16 -0700

Hi David,

I've been having a hard time writing a recursive loop that works for this,
which I assume is partly because I'm still working on understanding it. I
get the concept, it's just how the pieces fit together that I'm working on.

In an attempt to see how the nodes are handled in your original version, I
added some numerical markers to the XSL:

<xsl:template match="bodytext">
    <xsl:for-each select=".|text()[contains(.,'&#10;')]">
        <div>
            1<xsl:value-of
              select="substring-after(self::text(),'&#10;')"/>
            2<xsl:apply-templates
            select="key('x',generate-id(.))[position()&lt;last()]"/>
        </div>
        3<xsl:value-of
        select="substring-before(key('x',generate-id(.))[last()],'&#10;')"/>
    </xsl:for-each>
</xsl:template>  

I also expanded the number of text nodes in the XML and added another link:

<page>
    <bodytext>This is the <link url="">link</link>
    This is another line
    This is the third line with another <link url="">link</link>
    This is the fourth line</bodytext>
</page>

Here's how the numerals added to the XSL came out in the output:

            1
            2This is the <a href="">link</a></div>
        3<div>
            1    This is another line
    This is the third line with another
            2<a href="">link</a></div>
        3<div>
            1    This is the fourth line
            2</div>
        3

Number 3 (xsl:value-of select="substring-before...") isn't selecting a node,
but what really surprised me is how the nodes being output move between
number 1 (value-of select="substring-after...") and number 2
(apply-templates select="key..."). Frankly, I'm getting pretty confused.

Is the output that I have shown what you expect? If it is, then I'll keep
working on my understanding of how you're using the keys and how I can
recurse this, but if this isn't what you expect, then I'd be better off
trying to get it to do what you intended it to do before I add recursion.

Incidentally, I'm running this through MSXML3 (not my choice), if that has
any bearing on differences in output, though it shouldn't.

Thanks,

-- Brook

> From: David Carlisle <davidc@xxxxxxxxx>
> Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Date: Tue, 26 Aug 2003 23:18:36 +0100
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: Passing element nodes through string functions (WAS RE: [xsl]
> Preserving inline elements when using string functions)
> 
> I wrote:
> 
>> it's a grouping problem (positional grouping in Mike's terminoligy)
>> you want to group all child nodes before or after text nodes containing
>> cr ie text()[contains(.,'&#10;')] you need to work at the level of nodes
>> not of the entire content of your bodytext element.
>> 
>> See Jeni's site on grouping techniques.
>> 
>> David
> 
> 
> I suppose this is probably more helpful...
> 
> div.xml
> ========
> 
> <page>
> <bodytext>This is the <link url="zzz">link</link>
> This is another line</bodytext>
> </page>
> 
> 
> 
> div.xsl
> ========
> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="1.0">
> 
> <xsl:key name="x" match="bodytext/node()"
> use="generate-id((..|preceding-sibling::text()[contains(.,'&#10;')][1])[last()
> ])"/>
> 
> <xsl:template match="page">
> <html>
> <head>
> <title>testing...</title>
> </head>
> <xsl:apply-templates/>
> </html>
> </xsl:template>
> 
> <xsl:template match="link">
> <a href="{@url}">
> <xsl:apply-templates/>
> </a>
> </xsl:template>
> 
> 
> <xsl:template match="bodytext">
> <body>
> <xsl:for-each select=".|text()[contains(.,'&#10;')]">
> <div>
> <xsl:value-of 
> select="substring-after(self::text(),'&#10;')"/>
> <xsl:apply-templates
> select="key('x',generate-id(.))[position()&lt;last()]"/>
> </div>
> <xsl:value-of
> select="substring-before(key('x',generate-id(.))[last()],'&#10;')"/>
> </xsl:for-each>
> </body>
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> 
> 
> 
> 
> 
> $ saxon div.xml div.xsl
> 
> 
> <html>
> <head>
> <meta http-equiv="Content-Type" content="text/html;
> charset=utf-8">
> 
> <title>testing...</title>
> </head>
> 
> <body>
> <div>This is the <a href="zzz">link</a></div>
> <div>    This is another line</div>
> </body>
> 
> </html>
> 
> 
> XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 
> 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords