2010-03-12 11 views
2

Im nouveau sur ce projet et je vais écrire, ce que je pensais était une chose simple. Fonction récursive qui écrit des éléments xml imbriqués dans des niveaux x (indiqués par une variable). Jusqu'ici j'ai trouvé ceci, mais continue à obtenir une erreur de compilation. S'il vous plaît noter que je dois générer de nouvelles xml, pas interroger XML existant:XQuery - problème avec la fonction récursive

xquery version "1.0"; 

    declare function local:PrintTest($amount) 
    { 
     <test> 
     { 
     let $counter := 0 
     if ($counter <= $amount) 
      then local:PrintTest($counter) 
      else return 
     $counter := $counter +1 
     } 
     </test> 
    }; 

local:PrintPerson(3) 

Mon erreur est:

File Untitled1.xquery: XQuery transformation failed 
    XQuery Execution Error! 
Unexpected token - " ($counter <= $amount) t" 

Je ne comprenais pas XQuery, et ne peux pas tout à fait voir pourquoi cela ne fonctionne pas (est-il juste moi ou y at-il incroyablement peu de ressources sur Internet concernant XQuery?)

Répondre

6

Vous avez écrit cette fonction de manière procédurale, XQuery est un langage fonctionnel.

Chaque corps de la fonction ne peut être qu'une seule expression; il semble que vous essayez d'écrire des instructions (qui n'existent pas dans XQuery).

Tout d'abord, votre expression let doit être suivi d'un mot-clé de retour.

return est utilisé uniquement dans le cadre d'une expression FLWOR, une fonction évalue toujours à une valeur. Comme vous l'avez écrit, return est équivalent à /return et retournera donc un noeud appelé return.

La ligne $counter := $counter + 1 n'est pas valide XQuery du tout. Vous ne pouvez définir une variable comme celle-ci avec une expression let, et dans ce cas il créerait une nouvelle variable appelée compteur qui remplacerait l'ancienne, qui serait dans la portée seulement dans l'expression retour de la variable.

La bonne façon de faire ce que vous essayez de faire est de réduire la valeur de $ argument à chaque fois que la fonction récursivement, et arrêter lorsque vous appuyez sur 0.

declare function local:Test($amount) 
{ 
    if ($amount == 0) 
    then() 
    else 
    <test> 
     { 
     local:Test($amount - 1) 
     } 
    </test> 
}; 

local:Test(3) 

Notez que j'ai changé le nom de la fonction à tester. Le nom "PrintTest" était trompeur, car cela implique que la fonction fait quelque chose (à savoir, l'impression). La fonction retourne juste un noeud, elle ne fait aucune impression. Dans une langue purement fonctionnelle (dont XQuery est assez proche), une fonction n'a jamais d'effets secondaires, elle renvoie simplement une valeur (ou dans ce cas un nœud).

+0

A la vôtre, faut que ma tête s'enroule autour de cette –

Questions connexes