RE: [xsl] sequence of strings

Subject: RE: [xsl] sequence of strings
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 2 Dec 2008 13:58:07 -0000
A couple of things come to mind:

>    <xsl:template name='get_attributes'>
>      <xsl:param name='string' select='zip'/>
>        <xsl:variable name='blip'
>                      as='xs:string*'
>                      select="for $h in ('bold', 'italic') return
>                            if (contains($string, $h)) then $h 
> else ()"/>
>        <xsl:sequence select="for $h in $blip return if ($h = 
> 'bold') then
>                                                          'BLD' else
>                                if ($h = 'italic') then 'ITA' 
> else ()" />
>    </xsl:template>

I would tend to write that as

<xsl:function name="get-attributes" as="xs:string*">
  <xsl:param name="string" as="xs:string"/>
  <xsl:sequence select="'BLD'[contains($string, 'bold')],
'ITA'[contains($string, 'italic')]"/>
</xsl:function>

or if it were a longer list of names then

<xsl:variable name="styles" as="element(style)">
  <style name="BLD" code="bold"/>
  <style name="ITA" code="italic"/>
</xsl:variable>

<xsl:function name="get-attributes" as="xs:string*">
  <xsl:param name="string" as="xs:string"/>
  <xsl:sequence select="$styles[contains($string, @code)]/@name"/>
</xsl:function> 

Either way, this:

>      <xsl:variable name='blop' as='xs:string*'>
>        <xsl:call-template name='get_attributes'>
>          <!-- make sequence of strings -->
>          <xsl:with-param name='string'
>                          select='"style: italic;bold"'/>
>        </xsl:call-template>
>      </xsl:variable>

becomes

<xsl:variable name="blop" as="xs:string*" 
         select="get-attributes('style: italic;bold')"/>

I don't think there's much you can do about the main recursive template
(name="nest").

Michael Kay
http://www.saxonica.com/
  


> -----Original Message-----
> From: Ruud Grosmann [mailto:r.grosmann@xxxxxx] 
> Sent: 02 December 2008 13:18
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] sequence of strings
> 
> hi group,
> 
> I have made a test style sheet to examine how I can use a 
> string value to create nested elements (xslt2, saxon9).
> The string contains one or more style descriptors; the needed 
> elements have a different name than the corresponding styles.
> 
> My strategy is to convert the string to a sequence of 
> relevant substrings and then to map the sequence to the right 
> element name.
> 
> Below I have pasted my stylesheet. For the input document
> 
> <root/>
> 
> it creates the expected output
> 
> <?xml version="1.0" encoding="utf-8"?>
> <document>
>     <BLD>
>        <ITA/>
>     </BLD>
> </document>
> 
> My question is: this solution looks clumsy. How can I improve 
> it? My focus is not on the nest-template itself, but on the 
> get_attributes-template and the calling of the nest-template 
> (is the extra blop variable needed?)...
> 
> thanks in advance, Ruud
> 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <!-- maak een stack van strings -->
> 
> <xsl:stylesheet version="2.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>                          xmlns:xs="http://www.w3.org/2001/XMLSchema";
>                          exclude-result-prefixes="xs">
> 
>    <xsl:output method="xml" version="1.0" encoding="utf-8" 
> indent="yes"/>
> 
>    <xsl:template match="/root">
>      <xsl:variable name='blop' as='xs:string*'>
>        <xsl:call-template name='get_attributes'>
>          <!-- make sequence of strings -->
>          <xsl:with-param name='string'
>                          select='"style: italic;bold"'/>
>        </xsl:call-template>
>      </xsl:variable>
> 
>      <document>
>        <xsl:call-template name='nest'>
>          <xsl:with-param name='lijst' select='$blop'/>
>        </xsl:call-template>
>      </document>
>    </xsl:template>
> 
>    <xsl:template name='nest'>
>      <xsl:param name='lijst' select='zip'/>
>      <xsl:choose>
>        <xsl:when test="empty($lijst)">
>          <!-- end recursion -->
>          <xsl:sequence select="()"/>
>        </xsl:when>
>        <xsl:otherwise>
>          <xsl:element name="{$lijst[1]}">
>            <xsl:call-template name='nest'>
>              <xsl:with-param name='lijst' 
> select='$lijst[position() != 1]'/>
>            </xsl:call-template>
>          </xsl:element>
>        </xsl:otherwise>
>      </xsl:choose>
>    </xsl:template>
> 
>    <xsl:template name='get_attributes'>
>      <xsl:param name='string' select='zip'/>
>        <xsl:variable name='blip'
>                      as='xs:string*'
>                      select="for $h in ('bold', 'italic') return
>                            if (contains($string, $h)) then $h 
> else ()"/>
>        <xsl:sequence select="for $h in $blip return if ($h = 
> 'bold') then
>                                                          'BLD' else
>                                if ($h = 'italic') then 'ITA' 
> else ()" />
>    </xsl:template>

Current Thread