2010-03-06 10 views
0

J'ai rencontré un problème lorsque j'ai essayé de créer une fonction de suppression. Mon code actuel est:Comment créer une fonction de suppression dans XQuery

XQuery:

declare variable $d as xs:string; 
declare variable $p as xs:string; 

let $xp := saxon:evaluate(concat("doc('",$d,"')",$p)) 

return document {for $n in doc($d)/* return qsx10p8:delete($n, $xp)} 

declare function qsx10p8:delete 
($n as node(), $xp as node()*) 
as node() { 
if ($n[self::element()]) 
then element 
    {fn:local-name($n)} 
    {for $c in $n/(*|@*) 
     return qsx10p8:delete($c, $xp), 
    if (some $x in $xp satisfies ($n is $x)) 
    then() 
    else ($n/text())} 

else $n 
}; 

Si l'entrée sont: $d = C:/supplier.xml and $p= /Suppliers/Supplier/* le résultat est:

<Suppliers><Supplier><address /><Phone /></Supplier></Suppliers> 

Mais je veux que le résultat soit <Suppliers><Supplier></Supplier></Suppliers>. Existe-t-il un moyen de modifier mes codes de fonction pour supprimer également ces balises?

Répondre

0

Vous pouvez essayer la fonction récursive suivante pour supprimer les éléments souhaités.

declare function local:transform ($x as node()) 
{ 
    typeswitch ($x) 
     case element(Supplier) return element {"Supplier"} {} 
     case text() return $x 
     default 
     return element { fn:node-name($x) } 
     { 
       $x/attribute::*, 
       for $z in $x/node() return local:transform($z) 
     } 
}; 


let $d := <Suppliers> 
<Supplier><address /><Phone /></Supplier> 
<Supplier><address /><Phone /></Supplier> 
<Supplier><address /><Phone /></Supplier> 
</Suppliers> 
return local:transform($d) 
0

Ce XQuery:

declare variable $pPath as xs:string external; 
declare variable $vPath := tokenize($pPath,'\|'); 
declare function local:copy-match($x as element()) { 
    element 
     {node-name($x)} 
     {for $child in $x/node() 
     return 
      if ($child instance of element()) 
      then 
      local:match($child) 
      else 
      $child 
     } 
}; 
declare function local:match($x as element()) { 
    let $element-path := string-join(
          $x/ancestor-or-self::node()/name(), 
          '/' 
         ) 
    where 
     not(
     some $path in $vPath 
     satisfies 
      ends-with($element-path,$path) 
    ) 
    return 
     local:copy-match($x) 
}; 
local:match(/*) 

Avec cette xs:string comme $pPath param: 'Supplier/address|Supplier/Phone'

Sortie:

<Suppliers> 
    <Supplier></Supplier> 
</Suppliers>