smo
smo

Reputation: 89

XQuery: How to deal with multiple if-then-elses in a nested FLWOR statement?

Having dealt with XQuery for the last couple of weeks, I'm sometimes still at odds with the XQuery syntax when mixing XQuery and (X)HTML code.

I have a nested FLWOR statement, as a result of a more complex structure in my XML document. At some point I need to insert a few if-then-else statements, but depending on their position in the code, they either cause no problem at all or the file won't be validated any more.

Here's a shortened version of my code:

xquery version "3.0";
declare option exist:serialize "method=xhtml media-type=text/html";
<html>
    <head>
        <meta HTTP-EQUIV="Content-Type" content="text/html; charset=UTF-8"/>
        <link rel="stylesheet" type="text/css" href="style.css"/>
        <title>{$page-title}</title>
    </head>
    <body>   
        {
        let some variables
        ...
        return
        for $text in $texts
        let some variables
        ...
        return
        <div id="text">
            <div id="title">{$title}</div>
            <div id="id">({data($id)})</div>
            {
            if ($headword/form = $searchphrase) then
            <div id="headword2">{$headword/form}</div>
            else
            <div id="headword1">{$headword/form}</div>
            }
            {
            for $variant in $variants
            return
            ***
            <div id="variant">{$variant/form}
            ***
                {
                for $variant_cit in $variant/citation
                return
                if ($variant_cit/form = $searchphrase) then
                <div id="variant_cit_2">{$variant_cit/form}</div>
                else
                <div id="variant_cit_1">{$variant_cit/form}</div>
                }
            </div>
            }
        </div>
        }  
    </body>
</html>

This code works as expected, but as soon as I want to replace

<div id="variant">{$variant/form}

(line between the asterisks) by

if ($variant/form = $searchphrase) then
    <div id="variant2">{$variant/form}
else
    <div id="variant1">{$variant/form}

the code can no longer be validated. Adding another pair of brackets doesn't help either.

Perhaps I'm just missing a tiny little detail, but I'm not seeing it. Could anyone please help?

Upvotes: 0

Views: 961

Answers (1)

Michael Kay
Michael Kay

Reputation: 163458

XQuery is an orthogonal expression language, which means you can replace any expression, for example

<div>{$variant/@form}</div>

by a different expression, for example

if ($condition) then
  <div>{$variant/@form}</div>
else
  <span>{$variant/@form}</span>

But the fragment of text that you're trying to replace, namely

<div id="variant">{$variant/form}

is not a complete expression, so you can't do this (this kind of thing is possible in some macro languages, e.g. shell scripts, where conditionals apply to arbitrary sequences of characters in the expression text. But XQuery is not a macro language).

In your particular case the solution is very simple. Rather than writing

if ($variant/form = $searchphrase) then
    <div id="variant2">{$variant/form}
else
    <div id="variant1">{$variant/form}
...

you can use the much simpler (and valid)

<div id="{if ($variant/form = $searchphrase) 
          then 'variant2' 
          else 'variant1'}">{$variant/form} ...

Upvotes: 2

Related Questions