2014-09-02 2 views
-2

S'il vous plaît considérer cet exemple naïf:créer un noeud à partir de la différence de deux fichiers XML avec la même structure tag

let $Best := <root> 
      <p name='p1'> 
       <s name='s1'> 
       <line nr='1' ci='0'/> 
       <line nr='2' ci='10'/> 
       </s> 
       <s name='s2'> 
        <line nr='5' ci='2'/> 
        <line nr='6' ci='3'/> 
       </s> 
      </p> 
      <p name='p2'> 
       <s name='s1'> 
        <line nr='34' ci='0'/> 
        <line nr='35' ci='1'/> 
       </s> 
       <s name='s2'> 
        <line nr='37' ci='2'/> 
        <line nr='38' ci='3'/> 
       </s> 
      </p> 
     <root> 

    let $Least := 
      <root> 
      <p name='p1'> 
       <s name='s1'> 
       <line nr='1' ci='15'/> 
       <line nr='2' ci='1'/> 
       </s> 
       <s name='s2'> 
        <line nr='5' ci='2'/> 
        <line nr='6' ci='5'/> 
       </s> 
       </p> 
      <p name='p2'> 
       <s name='s1'> 
        <line nr='34' ci='0'/> 
        <line nr='35' ci='0'/> 
       </s> 
       <s name='s2'> 
       <line nr='37' ci='1'/> 
       <line nr='38' ci='7'/> 
       </s> 
      </p> 
      <root> 

Ces noeuds ont la même structure d'étiquette et les mêmes valeurs d'attribut, à l'exception de la valeur de l'attribut " ci ". J'ai besoin d'une fonction xquery qui construit un nouveau noeud $ Résultat de $ Meilleur en remplaçant chaque noeud "ligne" qui a l'attribut "ci" moins que la valeur du même attribut "ci" du nœud correspondant "ligne" de $ Least:

$Result := <root> 
       <p name='p1'> 
        <s name='s1'> 
        <line nr='1' ci='15'/> 
        <line nr='2' ci='10'/> 
        </s> 
        <s name='s2'> 
        <line nr='5' ci='2'/> 
        <line nr='6' ci='5'/> 
        </s> 
       </p> 
       <p name='p2'> 
        <s name='s1'> 
        <line nr='34' ci='0'/> 
        <line nr='35' ci='1'/> 
        </s> 
        <s name='s2'> 
         <line nr='37' ci='2'/> 
         <line nr='38' ci='7'/> 
        </s> 
       </p> 
       <root> 

Merci d'avance pour votre aide.

+1

Bienvenue à SO. S'il vous plaît lire les [FAQ] et [Ask] pour obtenir des conseils sur la rédaction de bonnes questions. On s'attend à ce que vous vous efforciez de résoudre le problème vous-même au lieu de simplement présenter un problème et d'attendre que quelqu'un d'autre le résolve pour vous. –

Répondre

0

Utilisez la récursivité et parcourez les arbres en parallèle, en fonction de l'identificateur dont vous disposez (@name, @nr). Lorsque vous atteignez le nœud feuille <line>, triez les valeurs @ci et prenez le plus grand.

declare function local:diff-cis(
    $best as node(), 
    $least as node() 
) as node()? 
{ 
    typeswitch($best) 
    case element(root) | element(p) | element(s) return 
     element { node-name($best) } { 
     $best/@name, 
     for $n in $best/* 
     return local:sub-cis($n, 
      $least/*[@name=$n/@name or @nr=$n/@nr]) 
     } 
    case element(line) return 
     element line { 
     $best/@nr, 
     attribute ci { 
      (for $ci in ($least/@ci, $best/@ci) 
      order by $ci descending 
      return $ci)[1] 
     } 
     } 
    default return() 
}; 

local:diff-cis($Best, $Least) 
+0

Merci pour votre temps. – user3664323

+0

@ user3664323 Si cette réponse est suffisante, veuillez l'accepter en cliquant sur la petite case à gauche. – wst

Questions connexes