0
votes

XML file is a list of <n> tags each contains a single number, sorted in ascending order by number inside <n> tags. Need to find if three of them satisfies x^2 + y^2 = z^2

Here is my code:

declare function local:square($k as xs:decimal?)
as xs:decimal? {
   let $sq := ($k * $k) 
   return $sq
};

declare function local:square_sum($a as xs:decimal?,$b as xs:decimal?)
as xs:decimal? {
   let $sqsum := (local:square($a) + local:square($b)) 
   return $sqsum
};

<result>{
let $doc := doc("emp.xml")/list
let $x := 0
let $y := 0

for $z in //n
    let $zconv := xs:decimal($z/text())
    let $lhs := local:square( $zconv )
    let $rhs := local:square_sum($x, $y)
    if ($lhs = $rhs) then (
    return <t>
                <n>{$x}</n>
                <n>{$y}</n>
                <n>{$zconv}</n>
           </t>
    )

}</result>

why is it not running, instead prompting me with an error saying:

expected "return", found "if("

Please, help sort this out, also check if casting to decimal is okay? for $zconv


Based on suggestion Changed code to this:

for $z in //n
let $zconv := xs:decimal($z/text())
let $lhs := local:square( $zconv )
let $rhs := local:square_sum($x, $y)
return if ($lhs = $rhs) 
then (   <t>
            <n>{$x}</n>
            <n>{$y}</n>
            <n>{$zconv}</n>
        </t>
)
else (
    $x := $y
    $y := $zconv
)

now it says:

expected ")", found ":="

Need to update $x and $y then rerun the loop for next n-value because Need to satisfy the the given condition.

1
XQuery's language semantics don't give you the kinds of guarantees your recent edit depends on (ie. promising that items being iterated over are processed by their order in the input document). If it did, that would greatly curtail the engine's ability to optimize by parallelizing loop operations. - Charles Duffy
re "Need to update $x and $y": You can't update variables in XQuery. (So yes, the name "variable" is misleading.) To put it another way, a form like $x := $y is only allowed when you're declaring variable $x (e.g., in a let clause). You'll have to think of a different way to solve the problem, one that doesn't involve updating variables. - Michael Dyck
(btw, one way to solve this class of problem that doesn't depend on updating variables is with a reducer). - Charles Duffy

1 Answers

2
votes

if is not a valid element of a FLWOR.

One option is to use a where:

where ($lhs = $rhs)
return <t>...</t>

Another is just to move the if into the return:

return if ($lhs = $rhs) then <t>...</t> else ()