xquery multi if-else statement

13,295

Solution 1

A let clause is not an expression. You need to change this kind of logic

if (contains($temp2,'-'))
    then
        let $bornDate := substring-before($temp2, '-')
        let $deathDate := substring-after($temp2, '-')
    else
        let $bornDate := $temp2
        let $deathDate := data('')

by this

let $hyphenated := contains($temp2, '-')
let $bornDate := if ($hyphenated) then substring-before($temp2, '-') else $temp2
let $deathDate := if ($hyphenated) then substring-after($temp2, '-') else ''
return ...

Though in this particular case I would be inclined to write:

let $tokens := tokenize($temp2, '-')
let $bornDate := $tokens[1]
let $deathDate := string($tokens[2])
return ...

Solution 2

Your let clauses are followed by expressions (starting with if), which is not valid syntax - a return is missing to make it a complete FLWOR expression.

Also the variables are defined in inner scopes, and their binding won't reach the outer scopes, which is not very useful.

Though they easily get cryptic, this might be a case for regular expressions, e.g.

for $input in
(
    "Capetown, 10/04/1932-01/14/2002",
    "Taipeh, 05/31/1988",
    "Anchorage",
    "08/19/1918-07/02/1997",
    "12/22/1978"
)
let $bornPlace := replace($input, ",.*$|^[-0-9/]+$", "")
let $bornDate := replace($input, "^.*, |-[0-9/]+$|^[^0-9][^,]+$", "")
let $DeathDate := replace($input, "^.*[0-9]+-|^.*,[^-]*$|^[^,-]+$", "")
return <test input="{$input}" 
             bornPlace="{$bornPlace}" 
             bornDate="{$bornDate}" 
             DeathDate="{$DeathDate}"/>

For details, see the specification of regular expressions and the corresponding XQuery functions.

Share:
13,295
Enissay
Author by

Enissay

Detective Conan at your service :P Favourite quote: Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety. (B.F.) A Goal without a plan is just a wish

Updated on June 04, 2022

Comments

  • Enissay
    Enissay almost 2 years

    Using xPath, I'm getting data from html field, this data can be in this format (including parentheses):

    DATA |||| symbols i'm using to explain my code

    (bornPlace, bornDate-DeathDate) |||| (str, A-B) = note that str may also contain '-'

    (bornPlace, bornDate) |||| (str, A)

    (bornPlace) |||| (str)

    (bornDate-DeathDate) |||| (A-B)

    (bornDate) |||| (A)

    Or completely empty

    I'm trying to retrieve each element into separate variable using multiple if-else statements, but it seems that it doesnt like multi-line commands (I think so).

    I already made a code wich is not working :-/ (it says expecting return, found else if ....)

    let $temp1 := data(normalize-space(substring-before(substring-after(//div/div[2]/h2/text(), '('), ')')))
    
    if (contains($temp1,','))           (:   (str, A-B) or (str, A)   :)
    then
        let $bornPlace := substring-before($temp1, ',')
        let $temp2 := substring-after($temp1, ',')
    
        if (contains($temp2,'-'))
        then
            let $bornDate := substring-before($temp2, '-')
            let $deathDate := substring-after($temp2, '-')
        else
            let $bornDate := $temp2
            let $deathDate := data('')
    
    else if (contains($temp1,'-'))
        then                            (:   (s-t-r) or (A-B)   :)
            let $temp2 := normalize-space(substring-before($temp1, '-'))
            if (number($temp2)=$temp2)     (: it's a number :)
            then
                let $bornDate := temp2
                let $deathDate := normalize-space(substring-after($temp2, '-'))
                let $bornPlace := data('')
            else
                let $bornPlace := $temp1
                let $bornDate := data('')
                let $deathDate := data('')
        else                            (:   (str) or (A)   :)
            if (number($temp1)=$temp1)     (: it's a number :)
            then
                let $bornDate := temp1
                let $deathDate := data('')
                let $bornPlace := data('')
            else
                let $bornPlace := $temp1
                let $bornDate := data('')
                let $deathDate := data('')
    

    Also if there's a more beautiful way to do that, i'll take it :D

    Thanks in advance for your help :)

  • Enissay
    Enissay almost 12 years
    Oh my, i'm so bad at regex xD... Thanks anyway :)
  • Enissay
    Enissay almost 12 years
    Can you please apply regex on my example? I'm desperate xD
  • Gunther
    Gunther almost 12 years
    You should get your desired result, when you use the three let clauses that I posted, replacing $input by $temp1, and dropping all of your code, except for let $temp1 := .... If that does not work, please explain what goes wrong.