IBM webMethods Hybrid Integration

IBM webMethods Hybrid Integration

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only
  • 1.  Help! Can anybody explain this XQuery?

    Posted Wed April 12, 2006 10:20 AM

    Can anybody explains this part?
    if (
    for $e3 in $other
    return
    if ($e3 << $e1) then 1 else ()
    ) then $e1 else ()
    )
    Thanks!
    THis is the whole function definition:

    declare function count-nodes($sequence) {
    if ($sequence) then (
    let $head := (
    for $e1 in $sequence
    let $other := (
    for $e2 in $sequence
    return (
    if (not($e1 is $e2)) then $e2 else ()
    )
    )
    return
    if (
    for $e3 in $other
    return
    if ($e3 << $e1) then 1 else ()
    ) then $e1 else ()
    ) return
    let $tail := (
    for $e1 in $sequence
    return
    if (not($e1 is $head)) then $e1 else ()
    )
    return (1 + count-nodes($tail))
    )
    else 0
    }


    #API-Management
    #Tamino
    #webMethods


  • 2.  RE: Help! Can anybody explain this XQuery?

    Posted Wed April 12, 2006 05:07 PM

    I can.

    but before I do, let me give some remarks:
    I do not know where you got this XQuery from. Either it is a puzzle , or something programmed by an XQuery novice. Judging from the variable names, what is intended to be achieved can be achieved in a much simpler way with XQuery. Besides, the query does not do what the variable names suggest. And it will create a type exception. And it does not conform to XQUery as of teh current spec and Tamino 4.4. implementation. Here we go:

    declare function xx:count-nodes($sequence)
    {
    if ($sequence) then
    ( let $head := ( for $e1 in $sequence
    let $other := ( for $e2 in $sequence
    return ( if (not($e1 is $e2)) then $e2
    else () ) )
    return if ( for $e3 in $other
    return if ($e3 << $e1) then 1
    else () ) then $e1
    else () )
    return let $tail := ( for $e1 in $sequence
    return if (not($e1 is $head)) then $e1
    else () )
    return (1 + xx:count-nodes($tail)) )
    else 0}

    from the name of the function, we can assume that it is intended to
    count the nodes in a sequence. The fact that all entries of the sequence
    are compared using the “is” operator also implies that the sequence consists of nodes only (otherwise you get a type exception, because the
    “is” operation is defined on nodes only.

    the outermost if says:
    if the incoming sequence is empty, return 0

    so for the empty sequence, teh number of nodes is correctly returned.

    In case the sequence is not empty:
    a variable $head is defined. However, in contrast to its name, it will contain a sequence of all nodes that are not identical to the first node of the sequence (in document order, i.e. not the first entry in the sequence):
    This is the reason for this result:

    for $e1 in $sequence
    let $other := ( for $e2 in $sequence
    return ( if (not($e1 is $e2)) then $e2
    else () ) )
    for each entry i$e1 n the sequence, the variable $other is computed.
    it will contain a sequence of all nodes which are not identical to $e1
    return if ( for $e3 in $other
    return if ($e3 << $e1) then 1
    else () )
    then $e1
    else () )
    means that whenever there is a node is before $e1 in document order, the argument of teh if evaluates to true, and $e1 is returned, i.e. , all nodes are returned that have a predecessor in document order in the sequence (not really what is implied by the name $head)

    return let $tail := ( for $e1 in $sequence
    return if (not($e1 is $head)) then $e1
    else () )
    will fails because of a type error, whenever the input sequence has more than two different nodes as entries, because then $head is a non-atomic sequence which creates a type error if operator “is” is applied to it.
    The intention seems to be: compute all node except the $head one.

    As there is a built-in count function, I wonder what the intention of this question to the forum is

    Regards

    Harald


    #API-Management
    #Tamino
    #webMethods


  • 3.  RE: Help! Can anybody explain this XQuery?

    Posted Thu April 13, 2006 05:04 AM

    Thank you very much, Doctor. Your insight was very keen.

    This XQuery is excerpted from a technical report “Expressive Power of Recursion and Aggregates in XQuery” which can be found as an attachement or at http://www.adrem.ua.ac.be/pub/TR2005-05.pdf

    This function aims to simulate the “count” function using recursion and constructors. Its argument “$sequence” is a sequence of nodes. This example shows that count() can be simulated by recursion and constructors. However its lemma 7 gives the result that count() CANNOT be simulated by recursion itself, given that count() can distinguish two set-equivalent environments while Recursion can’t. I’m a little confused at this. Do you see any example that can exemplify this argument?

    And I still have the same stupid question: Look at this paragraph:
    if (
    for $e3 in $other
    return
    if ($e3 << $e1) then 1 else ()
    ) then $e1 else ()

    Note that $other may contain multiple nodes. So for each node in $other, if it’s less than $e1 in document order, it would return a 1. Will there be multiple 1s in the outer if argument then? Or there’s only one 1 so that the if clause can be executed because 1 is a literal value?

    Please excuse my stupid questions as I’m a novice in XQuery. I look forward to your reply, especially to the first question. Many thanks!
    TR2005-05.pdf (337 KB)


    #Tamino
    #webMethods
    #API-Management


  • 4.  RE: Help! Can anybody explain this XQuery?

    Posted Fri April 21, 2006 12:24 PM

    Hi,

    the paper you ae referring to is definitely not a good choice to learn XQuery.
    To answer your second question on:

    
    if ( 
    for $e3 in $other 
    return 
    if ($e3 << $e1) then 1 else () 
    ) then $e1 else () 

    In deed, if there are three nodes before $e1, this is equivalent to

    
    if (( 1, 1, 1)) then $e1 else () 

    the effective boolean value of the expression in “if” is “true”, so the result of the expression is $e1.
    The effective boolean value is defined as
    If its operand is an empty sequence, fn:boolean returns false.

    If its operand is a sequence whose first item is a node, fn:boolean returns true.

    If its operand is a singleton value of type xs:boolean or derived from xs:boolean, fn:boolean returns the value of its operand unchanged.

    If its operand is a singleton value of type xs:string, xdt:untypedAtomic, or a type derived from one of these, fn:boolean returns false if the operand value has zero length; otherwise it returns true.

    If its operand is a singleton value of any numeric type or derived from a numeric type, fn:boolean returns false if the operand value is NaN or is numerically equal to zero; otherwise it returns true.

    Regards

    Harald


    #webMethods
    #Tamino
    #API-Management