Subject: RE: Passing element nodes through string functions (WAS RE: [xsl]Preserving inline elements when using string functions) From: "Michael Kay" <mhk@xxxxxxxxx> Date: Tue, 26 Aug 2003 22:14:30 +0100 |
It's certainly a tricky one. I think the key is that instead of the recursive call passing "substring-after", it has to pass (a) the substring after the newline in the current text node, plus (b) the following sibling nodes. This is probably a lot easier in 2.0 where you can pass a heterogeneous sequence, but I think you can probably do it in 1.0 with two parameters, a string and a node-set. If the string is empty, you look at the node-set; if the first node is an element, you copy it out; if the first node is a text node, you look for newlines in it. Michael Kay > -----Original Message----- > From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx > [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of > Brook Ellingwood > Sent: 26 August 2003 18:19 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: Passing element nodes through string functions (WAS > RE: [xsl]Preserving inline elements when using string functions) > > > Hi, > > I'm pretty close to deciding that what I'm trying to do is > impossible, but before I give I'm going to try rephrasing my > question and see if anyone has any ideas. Apologies for > taking up bandwidth by reposting. > > I have elements containing PCDATA in the form of strings plus > child elements, which contain strings and have attributes. > > <page> > <bodytext>This is the <link url="">link</link> > This is another line</bodytext> > </page> > > I am serially applying two templates to these elements. The > first template transforms the <link> element into an HTML <a > href> element. The second template takes the output from the > first template, identifies the sections of text set apart by > CR/LF and surrounds them with an HTML <div> element. The > problem I am having is that the "substring-before" and > "substring-after" functions in the second template cause the > child elements (the post-transform <a href> tags) to be > discarded. Here is the XSL: > > <!-- begin a href transforms --> > > <xsl:template name="embeddedLinks"> > <xsl:apply-templates select="./node()"/> > </xsl:template> > > <xsl:template match="link"> > <a style="text-decoration:underline"><xsl:attribute > name="href"><xsl:value-of select="@url"/></xsl:attribute><xsl:value-of > select="."/></a> > </xsl:template> > > <!-- begin div transforms --> > > <xsl:template name="paragraphs"> > <xsl:param name="string" /> > <xsl:param name="linebreak" select="'
'" /> > <xsl:param name="divClass" /> > <xsl:choose> > <xsl:when test="contains($string, $linebreak)"> > <DIV><xsl:attribute name="class"><xsl:value-of > select="$divClass" /></xsl:attribute> > <xsl:copy-of > select="substring-before($string, $linebreak)" /> > </DIV> > <xsl:call-template name="paragraphs"> > <xsl:with-param name="string" > > select="substring-after($string, $linebreak)" /> > <xsl:with-param name="linebreak" > select="$linebreak" /> > <xsl:with-param name="divClass" select="$divClass" /> > </xsl:call-template> > </xsl:when> > <xsl:otherwise> > <DIV><xsl:attribute name="class"><xsl:value-of > select="$divClass" /></xsl:attribute> > <xsl:copy-of select="$string" /> > </DIV> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > > <!-- begin template calls and outputting --> > > Test 1: Links<br/> > <xsl:for-each select="./page/bodytext"> > <xsl:call-template name="embeddedLinks" /> > </xsl:for-each> > > <br/><br/>Test 2: Paragraphs<br/> > <xsl:for-each select="./page/bodytext"> > <xsl:call-template name="paragraphs"> > <xsl:with-param name="divClass" select="'para'" /> > <xsl:with-param name="string"> > <xsl:copy-of select="."/> > </xsl:with-param> > </xsl:call-template> > </xsl:for-each> > > <br/>Test 3: Links and Paragraphs<br/> > <xsl:for-each select="./page/bodytext"> > <xsl:call-template name="paragraphs"> > <xsl:with-param name="divClass" select="'para'" /> > <xsl:with-param name="string" > > <xsl:call-template name="embeddedLinks" /> > </xsl:with-param> > </xsl:call-template> > </xsl:for-each> > > > As you can see, I've got three different output tests to > check each stage of the transform. Here is my output (cleaned > up slightly for readability): > > Test 1: Links<br> > This is the <a style="text-decoration:underline" href="">link</a> > This is another line<br> > > <br>Test 2: Paragraphs<br> > <DIV class="para">This is the link</DIV> > <DIV class="para"> This is another line</DIV> > > <br>Test 3: Links and Paragraphs<br> > <DIV class="para">This is the link</DIV> > <DIV class="para"> This is another line</DIV> > > I could get around this by making any elements in the XML > that will have contents like this into CDATA, but to my way > of thinking, that's like putting processing instructions in > the XML. I'd rather keep it pure and do the work on the XSL > side. But, as I said, I'm starting to think this may be > impossible. If anyone thinks differently, I'd love to hear from them. > > Thanks, > > -- Brook > > > 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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: Passing element nodes through s, Bill Keese | Thread | [xsl] How to get attribute values a, Dipesh Khakhkhar |
RE: [xsl] jaxp vs xalan, Michael Kay | Date | [xsl] xsl fails to select html node, fe . sola |
Month |