Xquery:嵌套ifs

时间:2009-12-01 21:05:40

标签: xml xquery

基本上我有几个可能为空的序列,如果它们是空的,那么我不想输出它的父节点。如果所有序列都是空的,那么我不想要包含节点。基本上我有类似的代码,这不起作用:

let $a := //a
let $b := //b

return
<root>
   {if (exists($a) or exists($b)) then
      <div id="container">
         {if (exists($a)) then
            <h2>As</h2>
            <div>
               {for loop for $a sequence...}
            </div>
          else()
          }
          {if (exists($b)) then
            <h2>Bs</h2>
            <div>
               {for loop for $b sequence...}
            </div>
          else()
          }
      </div>
    else()
    }
</root>

1 个答案:

答案 0 :(得分:1)

您的查询中有一个简单的语法错误:

if (exists($a))
then
  <h2>As</h2>
  <div>
     {for loop for $a sequence...}
  </div>
else
  ()

then子句必须是XQuery表达式,但是这里有两个XQuery表达式,<h2>节点和<div>节点。

返回一系列节点修复了这个问题:

if (exists($a))
then
  (<h2>As</h2>, 
   <div>
     {for loop for $a sequence...}
   </div>)
else
  ()

有一个巧妙的技巧可以用来整理查询。表达式if (exists(A)) then B else ()等同于if (A) then B else (),因为在谓词周围引入了对布尔值的调用。这反过来只相当于B[A],因为A谓词可以被提升。

使用此技巧,可以更简洁地编写查询:

let $a := //a
let $b := //b
return
<root>
{
  <div id="container">
  {
    (<h2>As</h2>, 
     <div>
     {
       ...
     }
     </div>)[$a],

    (<h2>Bs</h2>,
     <div>
     {
       ...
     }</div>)[$b])
  }
  </div>[$a or $b]
}
</root>