[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: "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="'&#xA;'" />
>        <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
Keywords