2011-02-14 2 views
2

J'ai un problème avec le retour du résultat HTML multi-éléments (je ne connais pas le nom pour cela). Pour le rendre plus clair, veuillez voir le code ci-dessous.renvoyer le code HTML multi-éléments en tant que résultat xquery

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

Ce code fonctionne, mais vous pouvez remarquer que je dois mettre cette <div> et </div> au début et à la fin de la partie return, que je ne veux pas vraiment. Ma question est la suivante: y a-t-il un moyen de l'enlever? J'ai essayé avec { } et () et les deux ne fonctionnent pas.

+0

Bonne question, +1. Voir ma réponse pour l'explication et la solution complète. :) –

Répondre

4

Voici la règle de syntaxe pour la grammaire de XQuery 1.0, tirée du XQuery 1.0 w3c spec.

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

Comme on peut le voir clairement, le jeton return (mot-clé) doit être suivi d'un expression.

Cependant, en se débarrassant de vous élément 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> 

Comme on peut le voir clairement, le mot-clé return est pas suivie d'une seule expression, tel que défini par le XQuery 1.0 grammaire.

Solution: indiquer clairement la séquence des éléments qui suivent le mot-clé return, comme une séquence:

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

Avis que la séquence des éléments suivants return est maintenant entouré par des crochets, et que la Les éléments de la séquence sont délimités par une virgule.

Maintenant, lorsque le code XQuery ci-dessus est exécuté sur ce fichier nobel.xml:

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

le résultat recherché, est produit correct:

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

C'est génial ... Je n'ai pas remarqué que nous devrions mettre la virgule pour définir la séquence ... – zfm

+0

+1 Excellente réponse. Il existe un arbre de production en profondeur qui va de [OrExpr] (http://www.w3.org/TR/xquery/#doc-xquery-OrExpr) à [PrimaryExpr] (http://www.w3.org/TR/xquery/# doc-xquery-PrimaryExpr) –

Questions connexes