recursive function problem

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

recursive function problem

Jochen Rebhan

Hi ,

I am having some problems reading an external file, the "no" attribute gets incremented by 2 instead of 1.

If I declare the external xml File as interal variable with "let", everyting works as expected, the "no" attribute gets incremented by 1.

Here the snippets:

(: the xquery file :)

xquery version "1.0";

declare variable $input external;

declare function local:copy($number_in as xs:integer, $node as element() , $level as xs:integer) as item()* {
 
    element { node-name($node ) }
    {
        if ($level eq 1) then attribute no { $number_in } else (),
       
        for $! c at $number_out in $node/child::node() return
           
            typeswitch($c)
                case $e as element() return local:copy( $number_out, $e, $level + 1)
                case $t as text()    return $t
                default              return <error/>
    }
};

local:copy(0,$input/*, 0)

 

(: the input file :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1>something</level1>
   &nb! sp;    <level1 attr="someatt">some text</level 1>
        <level1>some text value</level1>
        <level1 attr="ter">some text</level1>
        <level1 someattr="something">
                <someelem>simple text</someelem>
                <someelems>simple textm</someelems>
        </level1>
        <level1 someattr="more text">
                <someelem>test1</someelem>
                <someelems>test2</someelems>
   !      </level1>
        <level1 someattr="some other text">
                <someelem>simple text1</someelem>
                <someelems>simple text2</someelems>
        </level1>
        <level1 someattr="sometext">
                <someelem attr="someatt">some text</someelem>
                <someelems attr="someatt">some text</someelems>
        </level1>
</root>

 

(: the windows .bat file I use! :)

java  -cp saxon8.jar net.sf.saxon.Query -o test.out.xml test.xq +input=test.in.xml

 

(: the output looks like that, note the "no" attribute gets incremented by 2 instead of 1 :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1 no="2">something</level1>
        <level1 no="4">some text</level1>
        <level1 no="6">some text value</level1>
....

Any idea why 2 ? As I said, when I define the Xml Input document as variable inside the Xquery file everything works like expected !

Any help is appreciated, thanks.

j.rebhan at web.de



Erweitern Sie FreeMail zu einem noch lei! stungsstarkeren E-Mail-Postfach!    
Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131  
Reply | Threaded
Open this post in threaded view
|

Re: recursive function problem

Andrew Welch


On 3/8/06, Jochen Rebhan <[hidden email]> wrote:

Hi ,

I am having some problems reading an external file, the "no" attribute gets incremented by 2 instead of 1.

If I declare the external xml File as interal variable with "let", everyting works as expected, the "no" attribute gets incremented by 1.

Here the snippets:

(: the xquery file :)

xquery version "1.0";

declare variable $input external;

declare function local:copy($number_in as xs:integer, $node as element() , $level as xs:integer) as item()* {
 
    element { node-name($node ) }
    {
        if ($level eq 1) then attribute no { $number_in } else (),
       
        for $! c at $number_out in $node/child::node() return
           
            typeswitch($c)
                case $e as element() return local:copy( $number_out, $e, $level + 1)
                case $t as text()    return $t
                default              return <error/>
    }
};

local:copy(0,$input/*, 0)

 

(: the input file :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1>something</level1>
   &nb! sp;    <level1 attr="someatt">some text</level 1>
        <level1>some text value</level1>
        <level1 attr="ter">some text</level1>
        <level1 someattr="something">
                <someelem>simple text</someelem>
                <someelems>simple textm</someelems>
        </level1>
        <level1 someattr="more text">
                <someelem>test1</someelem>
                <someelems>test2</someelems>
   !      </level1>
        <level1 someattr="some other text">
                <someelem>simple text1</someelem>
                <someelems>simple text2</someelems>
        </level1>
        <level1 someattr="sometext">
                <someelem attr="someatt">some text</someelem>
                <someelems attr="someatt">some text</someelems>
        </level1>
</root>

 

(: the windows .bat file I use! :)

java  -cp saxon8.jar net.sf.saxon.Query -o test.out.xml test.xq +input=test.in.xml

 

(: the output looks like that, note the "no" attribute gets incremented by 2 instead of 1 :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1 no="2">something</level1>
        <level1 no="4">some text</level1>
        <level1 no="6">some text value</level1>
....

Any idea why 2 ? As I said, when I define the Xml Input document as variable inside the Xquery file everything works like expected !

Any help is appreciated, thanks.


Hi,

I don't know  XQuery sufficiently yet to debug your query, but this sort of thing usually boils down to counting whitespace nodes when you dont really want to.

Try changing:

for $! c at $number_out in $node/child::node() return

to:

for $! c at $number_out in $node/child::* return

and see if that helps (node() includes whitespace only text nodes, * doesn't)

cheers
andrew
Reply | Threaded
Open this post in threaded view
|

Re: recursive function problem

David Carlisle
In reply to this post by Jochen Rebhan
 
 for $c at $number_out in $node/child::node() return

You are iterating over all nodes here which includes the text nodes used
to indent the document. So element nodes have position 2 4 6 ...
When you build the xml within the xquery it is controlled by the
boundary space declaration (defaulting to strip) so these text nodes are
not generated. saxon has a command line switch to ignore white space
text nodes when building input trees. (-sall)

David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
saxon-help mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help
Reply | Threaded
Open this post in threaded view
|

RE: recursive function problem

Michael Kay
In reply to this post by Jochen Rebhan
This is happening because you are counting whitespace text nodes as well as element nodes. Either replace child::node() by child::* (to select elements only), or use the command line option to cause whitespace to be stripped from source documents: -sall.
 
For documents created within the query in a let expression, boundary whitespace is stripped by default.
 
Michael Kay


From: [hidden email] [mailto:[hidden email]] On Behalf Of Jochen Rebhan
Sent: 08 March 2006 11:33
To: [hidden email]
Subject: [saxon] recursive function problem

Hi ,

I am having some problems reading an external file, the "no" attribute gets incremented by 2 instead of 1.

If I declare the external xml File as interal variable with "let", everyting works as expected, the "no" attribute gets incremented by 1.

Here the snippets:

(: the xquery file :)

xquery version "1.0";

declare variable $input external;

declare function local:copy($number_in as xs:integer, $node as element() , $level as xs:integer) as item()* {
 
    element { node-name($node ) }
    {
        if ($level eq 1) then attribute no { $number_in } else (),
       
        for $! c at $number_out in $node/child::node() return
           
            typeswitch($c)
                case $e as element() return local:copy( $number_out, $e, $level + 1)
                case $t as text()    return $t
                default              return <error/>
    }
};

local:copy(0,$input/*, 0)

 

(: the input file :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1>something</level1>
   &nb! sp;    <level1 attr="someatt">some text</level 1>
        <level1>some text value</level1>
        <level1 attr="ter">some text</level1>
        <level1 someattr="something">
                <someelem>simple text</someelem>
                <someelems>simple textm</someelems>
        </level1>
        <level1 someattr="more text">
                <someelem>test1</someelem>
                <someelems>test2</someelems>
   !      </level1>
        <level1 someattr="some other text">
                <someelem>simple text1</someelem>
                <someelems>simple text2</someelems>
        </level1>
        <level1 someattr="sometext">
                <someelem attr="someatt">some text</someelem>
                <someelems attr="someatt">some text</someelems>
        </level1>
</root>

 

(: the windows .bat file I use! :)

java  -cp saxon8.jar net.sf.saxon.Query -o test.out.xml test.xq +input=test.in.xml

 

(: the output looks like that, note the "no" attribute gets incremented by 2 instead of 1 :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1 no="2">something</level1>
        <level1 no="4">some text</level1>
        <level1 no="6">some text value</level1>
....

Any idea why 2 ? As I said, when I define the Xml Input document as variable inside the Xquery file everything works like expected !

Any help is appreciated, thanks.

j.rebhan at web.de



Erweitern Sie FreeMail zu einem noch lei! stungsstarkeren E-Mail-Postfach!    
Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131  
Reply | Threaded
Open this post in threaded view
|

RE: recursive function problem

Jochen Rebhan
In reply to this post by Jochen Rebhan


Wow ! I didn't know about that difference ! Thanks.

But this leads me to the question whether there is a possibility within the typeswitch statement that allows me to recognize whether this is an empty text node or a normal element() ?

If yes, let me know !

Jochen

[hidden email]

 

[hidden email] schrieb am 08.03.06 12:54:12:

This is happening because you are counting whitespace text nodes as well as element nodes. Either replace child::node() by child::* (to select elements only), or use the command line option to cause whitespace to be stripped from source documents: -sa! ll.
 
For documents created within the query in a let expression, boundary whitespace is stripped by default.
 
Michael Kay


From: [hidden email] [mailto:[hidden email]] On Behalf Of Jochen Rebhan
Sent: 08 March 2006 11:33
To: saxon-hel! [hidden email]
Subject: [saxon] recursive function problem

Hi ,

I am having some problems reading an external file, the "no" attribute gets incremented by 2 instead of 1.

If I declare the external xml File as interal variable with "let", everyting works as expected, the "no" attribute gets incremented by 1.

Here the snippets:

(: the xquery file :)

xquery version "1.0";

declare variable $input external;

declare function local:copy($number_in as xs:integer, $node as element() , $level as xs:integer) as item()* {
 
    element { node-name($node ) }
    {
        if ($level eq 1) then attribute no { $number_in } else (),
       
        for $! c at $number_out in $node/child::node() return
           
     &n! bsp;      typeswitch($c)
                case $e as element() return local:copy( $number_out, $e, $level + 1)
                case $t as text()    return $t
                default              return <error/>
    }
};

local:copy(0,$input/*, 0)

 

(: the input file :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1>something</level1>
   &nb! sp;    <level1 attr="someatt">some text</level 1>
        <level1>some text v! alue</level1>
        < level1 attr="ter">some text</level1>
        <level1 someattr="something">
                <someelem>simple text</someelem>
                <someelems>simple textm</someelems>
        </level1>
        <level1 someattr="more text">
                <someelem>test1</someelem>
                <someelems>test2</someelems>
   !      </level1>
        <level1 someattr="some other text">
  &! nbsp;             <someelem>simple text1</someelem>
                <someelems>simple text2</someelems>
        </level1>
        <level1 someattr="sometext">
                <someelem attr="someatt">some text</someelem>
                <someelems attr="someatt">some text</someelems>
        </level1>
</root>

 

(: the windows .bat file I use! :)

java  -cp saxon8.jar net.sf.saxon.Query -o test.out.xml test.xq +input=test.in.xml

 

(: the output looks like th! at, note the "no" attribute gets incremented by 2 instead of 1 :)

< P><?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1 no="2">something</level1>
        <level1 no="4">some text</level1>
        <level1 no="6">some text value</level1>
....

Any idea why 2 ? As I said, when I define the Xml Input document as variable inside the Xquery file everything works like expected !

Any help is appreciated, thanks.

j.rebhan at web.de



Erweitern Sie FreeMail zu einem noch lei! stungsstarkeren E-Mail-Postfach!    
Mehr Infos unter http://freemai! l.web.de/home/landingpad/?mc=021131  



Verschicken Sie romantische, coole und witzige Bilder per SMS!   
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193  
Reply | Threaded
Open this post in threaded view
|

RE: recursive function problem

Michael Kay
If you choose to process the text nodes, then the typeswitch will match them on the text() branch.
 
If you want to process the text nodes, and to number the elements in sequence as 1,2,3, then instead of using "at $number_out" to allocate the numbers, you could use count(preceding-sibling::*)+1. This is likely to be inefficient if the number of siblings becomes large. One way around this would be to have a memo-function node-number($e as element()) with the logic
 
let $x := $w/preceding-sibling::*
return if ($x) then node-number($x) else 1
 
This emulates the way xsl:number is implemented in XSLT.
 
Michael Kay


From: [hidden email] [mailto:[hidden email]] On Behalf Of Jochen Rebhan
Sent: 08 March 2006 13:48
To: [hidden email]
Subject: RE: [saxon] recursive function problem


Wow ! I didn't know about that difference ! Thanks.

But this leads me to the question whether there is a possibility within the typeswitch statement that allows me to recognize whether this is an empty text node or a normal element() ?

If yes, let me know !

Jochen

[hidden email]

 

[hidden email] schrieb am 08.03.06 12:54:12:

This is happening because you are counting whitespace text nodes as well as element nodes. Either replace child::node() by child::* (to select elements only), or use the command line option to cause whitespace to be stripped from source documents: -sa! ll.
 
For documents created within the query in a let expression, boundary whitespace is stripped by default.
 
Michael Kay


From: [hidden email] [mailto:[hidden email]] On Behalf Of Jochen Rebhan
Sent: 08 March 2006 11:33
To: saxon-hel! [hidden email]
Subject: [saxon] recursive function problem

Hi ,

I am having some problems reading an external file, the "no" attribute gets incremented by 2 instead of 1.

If I declare the external xml File as interal variable with "let", everyting works as expected, the "no" attribute gets incremented by 1.

Here the snippets:

(: the xquery file :)

xquery version "1.0";

declare variable $input external;

declare function local:copy($number_in as xs:integer, $node as element() , $level as xs:integer) as item()* {
 
    element { node-name($node ) }
    {
        if ($level eq 1) then attribute no { $number_in } else (),
       
        for $! c at $number_out in $node/child::node() return
           
     &n! bsp;      typeswitch($c)
                case $e as element() return local:copy( $number_out, $e, $level + 1)
                case $t as text()    return $t
                default              return <error/>
    }
};

local:copy(0,$input/*, 0)

 

(: the input file :)

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1>something</level1>
   &nb! sp;    <level1 attr="someatt">some text</level 1>
        <level1>some text v! alue</level1>
        < level1 attr="ter">some text</level1>
        <level1 someattr="something">
                <someelem>simple text</someelem>
                <someelems>simple textm</someelems>
        </level1>
        <level1 someattr="more text">
                <someelem>test1</someelem>
                <someelems>test2</someelems>
   !      </level1>
        <level1 someattr="some other text">
  &! nbsp;             <someelem>simple text1</someelem>
                <someelems>simple text2</someelems>
        </level1>
        <level1 someattr="sometext">
                <someelem attr="someatt">some text</someelem>
                <someelems attr="someatt">some text</someelems>
        </level1>
</root>

 

(: the windows .bat file I use! :)

java  -cp saxon8.jar net.sf.saxon.Query -o test.out.xml test.xq +input=test.in.xml

 

(: the output looks like th! at, note the "no" attribute gets incremented by 2 instead of 1 :)

< P><?xml version="1.0" encoding="UTF-8"?>
<root>
        <level1 no="2">something</level1>
        <level1 no="4">some text</level1>
        <level1 no="6">some text value</level1>
....

Any idea why 2 ? As I said, when I define the Xml Input document as variable inside the Xquery file everything works like expected !

Any help is appreciated, thanks.

j.rebhan at web.de



Erweitern Sie FreeMail zu einem noch lei! stungsstarkeren E-Mail-Postfach!    
Mehr Infos unter http://freemai! l.web.de/home/landingpad/?mc=021131  



Verschicken Sie romantische, coole und witzige Bilder per SMS!   
Jetzt bei WEB.DE FreeMail: http://f.web.de/?mc=021193