[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: How to convert a recursive function to a loop, usi
Presuming your input has been validated so that only proper hex values for XML Unicode characters occur inside <Byte>, why not just treat it as a sequence of codepoints? <xsl:variable name="numSeq" select=".//Byte/text()/xs:integer(f:hexToDec(.))" as="xs:integer+"/> <xsl:variable name="codepoints" select="for $n in $numSeq return if ( $n eq 0 ) then 9216 else $n" as="xs:integer+"/> <xsl:variable name="string" select="codepoints-to-string($codepoints )"/> <xsl:for-each select="tokenize( $string,'␀')"> <String><xsl:value-of select="."/></String> </xsl:for-each> Note that NULL = 0 = � is converted to SYMBOL FOR NULL = 9216 = ␀ because NULL is not a valid XML character. You could use any character that is guaranteed not to occur in the input. You would need to write a hex-to-integer converter, or grab one off StackOverflow This would not work of course, if <Byte> represented actual bytes rather than characters. (I.e., if EURO SIGN were represented as <Byte>E2</Byte><Byte>82</Byte><Byte>AC</Byte> instead of <Byte>20AC</Byte>.) > My input file consists of a sequence (sourceSeq) of <Byte> elements > representing a sequence of null-terminated strings. I want to > create a function that returns a sequence of <String> elements. For > example, with this sourceSeq: > > <Byte>48</Byte> > <Byte>69</Byte> > <Byte>00</Byte> > <Byte>4A</Byte> > <Byte>69</Byte> > <Byte>6C</Byte> > <Byte>6C</Byte> > <Byte>00</Byte> > > the function should return: > > <String>Hi</String> > <String>Jill</String> > > The strings are of variable length. > > I do not know how many null-terminated strings are in sourceSeq. > However, I do know the total number (total-size) of <Byte> elements > within sourceSeq containing the null-terminated strings. > > Below is a recursive way to implement the function. Unfortunately, > total-size can be quite large, which means the function recurses > many times, resulting in a "Too many nested function calls" error. > Is there an iterative way to implement the function? /Roger > > <xsl:function name="f:make-string-table-entries" as="element(String)*"> > <xsl:param name="total-size" as="xs:integer" /> > <xsl:param name="current-size" as="xs:integer" /> > <xsl:param name="current-position" as="xs:integer" /> > <xsl:param name="sourceSeq" as="element(Byte)*" /> > > <xsl:choose> > <xsl:when test="$current-size ge $total-size" /> > <xsl:otherwise> > <xsl:variable name="string" select="f:make-element-from-null-terminated-string('String', $current-position, $sourceSeq)" as="element(String)"/> > <xsl:sequence select="$string" /> > <xsl:variable name="length" select="string-length($string/text()) + 1"/> <!-- add 1 for the null byte --> > <xsl:sequence select="f:make-string-table-entries($total-size, xs:integer($current-size+$length), xs:integer($current-position+$length), $sourceSeq)" /> > </xsl:otherwise> > </xsl:choose> > > </xsl:function> -- Syd Bauman, NRP (he/him/his) Senior XML Programmer/Analyst Northeastern University Women Writers Project s.bauman@xxxxxxxxxxxxxxxx or Syd_Bauman@xxxxxxxxxxxxxxxx
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|