xsl-list
[Top] [All Lists]

Re: [xsl] A function that tokenizes a string, wrapping each token in start-tag , end-tag pairs?

2016-04-21 10:13:16
Why not use xsl:analyze-string?

<xsl:analyze-string select="$line" regex="....">
  <xsl:matching-substring/>
  <xsl:non-matching-substring>
    <xsl:variable name="p" select="position()"/>
    <xsl:element name="{$tag[$p]}"><xsl:value-of select="."/></xsl:element>
  </xsl:non-matching-substring>
</xsl:analyze-string>

For reusability in XSLT 3.0 this is a good candidate for a 
higher-order-function - you could pass a parameter which is a function to be 
called to determine the element name to be used for the Nth token.

Michael Kay
Saxonica


On 21 Apr 2016, at 13:20, Costello, Roger L. costello(_at_)mitre(_dot_)org 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:

Hi Folks,

I want a function that tokenizes a string and wraps each token in a 
start-tag, end-tag pair.

I figure that I should pass into the function the string to be tokenized and 
a sequence of integers corresponding to the decimal value(s) of the token 
delimiter.

Also, I figure that I should pass into the function a sequence of strings, 
corresponding to the tag names to be used for wrapping each token.

I've implemented the function, see below. It works fine, but I want to know 
if it can be improved. Is there a way to write the function more idiomatic? 
Shorter? Generalized to be more widely useful?  /Roger


   <!-- 
      Create an element for each non-empty token in $line.
      $line is tokenized using the sequence of symbols denoted
      by $line-delimiter.
      For the token at position i, name the element using the
      string in headers[$i]
  -->         
   <xsl:function name="f:line" as="element()*">
      <xsl:param name="line" as="xs:string" />
      <xsl:param name="line-delimiter" as="xs:integer+" />
              <xsl:param name="headers" as="xs:string+" />

      <xsl:variable name="tokens" select="tokenize($line, 
codepoints-to-string($line-delimiter))" as="xs:string*" />
              <xsl:variable name="len" select="count($tokens)" 
as="xs:integer" />
              <xsl:for-each select="1 to $len">
                      <xsl:variable name="index" select="xs:integer(.)" 
as="xs:integer" />
                      <xsl:variable name="value" select="$tokens[position() 
eq $index]" as="xs:string" />
                      <xsl:choose>
                              <xsl:when test="$value eq ''"/>
                              <xsl:otherwise>
                                      <xsl:element name="{$headers[position() 
eq $index]}">
                                                      <xsl:sequence 
select="$value"/>
                                      </xsl:element>
                              </xsl:otherwise>
                      </xsl:choose>
              </xsl:for-each>

   </xsl:function>

--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>