|
Subject: Re: [xsl] How to convert a recursive function to a loop, using XSLT 2.0? From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sat, 11 May 2019 21:24:58 -0000 |
And to make this more efficient -- clearly O(N), change the XPath
expression to this:
for $ind in 1 to count($vEnds),
$vLastEnd in (0, $vEnds)[$ind],
$vThisEnd in $vEnds[$ind]
return
my:makeString(
for $pos in $vLastEnd+1 to $vThisEnd -1
return
$vHex2Dec/*[@from = $vBytes[$pos]]/@to/xs:integer(.)
)
On Sat, May 11, 2019 at 12:55 PM Dimitre Novatchev <dnovatchev@xxxxxxxxx>
wrote:
> Hi Roger,
>
> Besides the obvious grouping solution, here is a short XPath 2.0 (plus
> some XSLT 2.0) to do this in a non-recursive way.
>
> Ideally I would use no XSLT and pure XPath 3 -- taking advantage of XPath
> 3.0 features such as the let - expression and maps, and also the ability to
> generate XML as a string and then use the standard parse-xml() function to
> construct a new XML document, using only XPath.
>
> One can also produce an XSLT 1.0 solution, using keys.
>
> This XSLT 2.0 transformation:
>
> <xsl:stylesheet version="2.0" xmlns:xsl="
> http://www.w3.org/1999/XSL/Transform"
> xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my"
> exclude-result-prefixes="xs my">
> <xsl:output omit-xml-declaration="yes" indent="yes"/>
>
> <xsl:variable name="vHex2Dec">
> <tr from="48" to="72"/>
> <tr from="4A" to="74"/>
> <tr from="69" to="105"/>
> <tr from="6C" to="108"/>
> </xsl:variable>
>
> <xsl:template match="/">
> <xsl:variable name="vBytes" select="/*/Byte"/>
> <xsl:variable name="vEnds" select="index-of($vBytes, '00')"/>
>
> <xsl:sequence select=
> "for $vLastEnd in (0, $vEnds),
> $vThisEnd in $vEnds[. > $vLastEnd][1]
> return
> my:makeString(
> for $pos in $vLastEnd+1 to $vThisEnd -1
> return
> $vHex2Dec/*[@from = $vBytes[$pos]]/@to/xs:integer(.)
> )
>
> "/>
> </xsl:template>
>
> <xsl:function name="my:makeString" as="element()">
> <xsl:param name="pCodepoints" as="xs:integer*"/>
>
> <string>
> <xsl:sequence select="codepoints-to-string($pCodepoints)"/>
> </string>
> </xsl:function>
> </xsl:stylesheet>
>
> When applied on the provided XML fragment (made a wellformed XML document):
>
> <t>
> <Byte>48</Byte>
> <Byte>69</Byte>
> <Byte>00</Byte>
> <Byte>4A</Byte>
> <Byte>69</Byte>
> <Byte>6C</Byte>
> <Byte>6C</Byte>
> <Byte>00</Byte>
> </t>
>
> produces the wanted result:
>
> <string>Hi</string>
> <string>Jill</string>
>
>
> Cheers,
> Dimitre
>
>
> On Fri, May 10, 2019 at 4:20 AM Costello, Roger L. costello@xxxxxxxxx <
> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>> Hello XSLT experts!
>>
>> 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>
>>
>>
>
>
> --
> Cheers,
> Dimitre Novatchev
> ---------------------------------------
> Truly great madness cannot be achieved without significant intelligence.
> ---------------------------------------
> To invent, you need a good imagination and a pile of junk
> -------------------------------------
> Never fight an inanimate object
> -------------------------------------
> To avoid situations in which you might make mistakes may be the
> biggest mistake of all
> ------------------------------------
> Quality means doing it right when no one is looking.
> -------------------------------------
> You've achieved success in your field when you don't know whether what
> you're doing is work or play
> -------------------------------------
> To achieve the impossible dream, try going to sleep.
> -------------------------------------
> Facts do not cease to exist because they are ignored.
> -------------------------------------
> Typing monkeys will write all Shakespeare's works in 200yrs.Will they
> write all patents, too? :)
> -------------------------------------
> Sanity is madness put to good use.
> -------------------------------------
> I finally figured out the only reason to be alive is to enjoy it.
>
>
--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
To achieve the impossible dream, try going to sleep.
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
Typing monkeys will write all Shakespeare's works in 200yrs.Will they write
all patents, too? :)
-------------------------------------
Sanity is madness put to good use.
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] How to convert a recursiv, Dimitre Novatchev dn | Thread | Re: [xsl] How to convert a recursiv, Costello, Roger L. c |
| Re: [xsl] How to convert a recursiv, Dimitre Novatchev dn | Date | [xsl] What is the most efficient XP, Costello, Roger L. c |
| Month |