开发者

returning multi-element HTML as an xquery result

I have a problem with returning multi-element HTML result (I dont know the name for this). To make it clearer, please see the code below.

<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")/开发者_Go百科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>

That code will work, but you can notice that I have to put that <div> and </div> in the beginning and the end of the return part, which I actually don't want. My question is, is there any way to remove it? I have tried with { } and ( ) and both don't work.


Here are the syntax rule for the grammar of XQuery 1.0 , as taken from the XQuery 1.0 w3c spec.:

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

As can be clearly seen, the return token (keyword) must be followed by a single expression.

However, by getting rid of the div element you have:

<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>

As we can clearly see, the return keyword is not followed by a single expression, as defined by the XQuery 1.0 grammar.

Solution: Clearly specify the sequence of elements that follow the return keyword, as a sequence:

<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>

Notice that the sequence of elements following return is now surrounded by brackets, and that the elements in the sequence are delimited by a comma.

Now, when the above XQuery code is executed on this nobel.xml file:

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

the wanted, correct result is produced:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜