将多元素HTML作为xquery结果返回

时间:2011-02-14 23:39:07

标签: html xquery transformation

我有一个返回多元素HTML结果的问题(我不知道这个名字)。为了更清楚,请参阅下面的代码。

<body>
  <h1>Nobel prize winners</h1>{
  for $subject in distinct-values(doc("nobel.xml")//subject)
    let $sn := $subject`
    return <div><h2>{$sn}</h2><ul>
       {for $row in doc("nobel.xml")/nobel/row
          let $name := $row/winner/text()
          let $year := $row/yr/text()
          where $row/subject/text()=$subject
          order by $year
          return <li> ({$year} {$name} </li>
        }</ul></div>
  }
</body>

该代码可行,但您可以注意到我必须将<div></div>放在return部分的开头和结尾,我实际上并不是这样想。我的问题是,有什么办法可以删除它吗?我尝试使用{ }( ),两者都无效。

1 个答案:

答案 0 :(得分:4)

以下是XQuery 1.0语法的语法规则,取自 XQuery 1.0 w3c spec 。:

[31]    Expr          ::=    ExprSingle ("," ExprSingle)* 
[32]    ExprSingle    ::=    FLWORExpr
                           | QuantifiedExpr
                           | TypeswitchExpr
                           | IfExpr
                           | OrExpr 
[33]    FLWORExpr    ::=    (ForClause | LetClause)+ WhereClause? 
                                             OrderByClause? "return" ExprSingle 

可以清楚地看到,return令牌(关键字)后面必须跟一个表达式。

然而,通过删除您拥有的div元素

<body>
    <h1>Nobel prize winners</h1>
    {
     for $subject in
           distinct-values(doc("nobel.xml")//subject)
      let $sn := $subject
        return
            <h2>{$sn}</h2>
                <ul>
                  {for $row in doc("nobel.xml")/nobel/row
                    let $name := $row/winner/text()
                    let $year := $row/yr/text()
                    where $row/subject/text()=$subject
                    order by $year
                       return
                         <li> ({$year} {$name} </li>
                  }
                </ul>
        }
</body>

我们可以清楚地看到,return关键字后面没有单个表达式,由XQuery 1.0语法定义。

解决方案:明确指定return关键字后面的元素序列,作为序列:

<body>
    <h1>Nobel prize winners</h1>
    {
     for $subject in
           distinct-values(doc("nobel.xml")//subject)
      let $sn := $subject
        return
          (
            <h2>{$sn}</h2>,
                <ul>
                  {for $row in doc("nobel.xml")/nobel/row
                    let $name := $row/winner/text()
                    let $year := $row/yr/text()
                    where $row/subject/text()=$subject
                    order by $year
                       return
                         <li> ({$year} {$name} </li>
                  }
                </ul>
          )
        }
</body>

注意return后面的元素序列现在被括号括起来,并且序列中的元素以逗号分隔。

现在,当在此nobel.xml文件上执行上述XQuery代码时:

<nobel>
 <row>
  <subject>Lit</subject>
  <winner>Solzhenitsin</winner>
  <yr>1969</yr>
 </row>
</nobel>

产生了想要的正确结果:

<body>
    <h1>Nobel prize winners</h1>
    <h2>Lit</h2>
    <ul>
        <li> (1969Solzhenitsin</li>
    </ul>
</body>