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(.,' ')]">
<div>
1<xsl:value-of
select="substring-after(self::text(),' ')"/>
2<xsl:apply-templates
select="key('x',generate-id(.))[position()<last()]"/>
</div>
3<xsl:value-of
select="substring-before(key('x',generate-id(.))[last()],' ')"/>
</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(_at_)nag(_dot_)co(_dot_)uk>
Reply-To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Date: Tue, 26 Aug 2003 23:18:36 +0100
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(.,' ')] 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(.,' ')][1])[last()
])"/>
<xsl:template match="page">
<html>
<head>
<title>testing...</title>
</head>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="link">
<a href="{(_at_)url}">
<xsl:apply-templates/>
</a>
</xsl:template>
<xsl:template match="bodytext">
<body>
<xsl:for-each select=".|text()[contains(.,' ')]">
<div>
<xsl:value-of
select="substring-after(self::text(),' ')"/>
<xsl:apply-templates
select="key('x',generate-id(.))[position()<last()]"/>
</div>
<xsl:value-of
select="substring-before(key('x',generate-id(.))[last()],' ')"/>
</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