возвращая многоэлементный HTML как результат xquery - PullRequest
2 голосов
/ 15 февраля 2011

У меня проблема с возвратом многоэлементного 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 Ответ

4 голосов
/ 15 февраля 2011

Вот синтаксическое правило для грамматики XQuery 1.0, взятое из спецификации XQuery 1.0 w3c .:

[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, теперь заключена в квадратные скобки, и что элементы в последовательности разделены запятой.

Теперь, когда вышеуказанный код XQuery выполняется для этого nobel.xml файла :

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