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>
精彩评论