Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 21/04/2016, à 09:37

Filador

Suppression de noeud XML sed/awk...

Bonjour,

Je souhaiterai dans un fichier XML, supprimer un nœud dupliqué, je m'explique :

En entrée, j'ai ce type de format :

<a>
  <b>
    <c>
       <d></d>
    </c>
  </b>
  <b>
    <e>
       <f></f>
    </e>
  </b>
</a>

et en sortie, j'aimerai avoir ceci :

<a>
  <b>
    <c>
       <d></d>
    </c>
  </b>
</a>

La balise <b> est dupliquée, on supprime donc le nœud et son contenu. J'espère avoir été clair.

PS : j'aimerai avoir une commande awk ou sed de préférence.

Merci d'avance.

Dernière modification par Filador (Le 21/04/2016, à 09:39)

Hors ligne

#2 Le 21/04/2016, à 10:41

pingouinux

Re : Suppression de noeud XML sed/awk...

Bonjour,
Le contenu des 2 séquences <b>...</b> est-il différent ?
Ces 2 séquences doivent-elles être consécutives ?
Ajouté : Le nom du nœud est-il connu ?

Dernière modification par pingouinux (Le 21/04/2016, à 10:42)

Hors ligne

#3 Le 21/04/2016, à 10:48

Filador

Re : Suppression de noeud XML sed/awk...

Bonjour pingouinux,

pingouinux a écrit :

Le contenu des 2 séquences <b>...</b> est-il différent ?

Non les balises des séquences ne sont pas différentes, uniquement les valeurs entre ses balises.

pingouinux a écrit :

Ces 2 séquences doivent-elles être consécutives ?

Oui les deux séquences se suivent, le but est de supprimer la seconde (doublon).

pingouinux a écrit :

Ajouté : Le nom du nœud est-il connu ?

Le nœud ici, serait la balise <b> qui encapsule d'autres balises <e> et <f>, elles doivent être supprimées aussi.

Dernière modification par Filador (Le 21/04/2016, à 10:48)

Hors ligne

#4 Le 21/04/2016, à 11:20

pingouinux

Re : Suppression de noeud XML sed/awk...

Si ça peut convenir, j'ai une proposition en python.

Hors ligne

#5 Le 21/04/2016, à 11:25

Filador

Re : Suppression de noeud XML sed/awk...

pingouinux a écrit :

Si ça peut convenir, j'ai une proposition en python.

Oui je suis intéressé si ça ne te dérange pas. Le faire avec awk ou sed est trop complexe ?

Hors ligne

#6 Le 21/04/2016, à 11:43

pingouinux

Re : Suppression de noeud XML sed/awk...

Voici le script noeud_dupli.py :

import sys, re

rec=re.compile(r'(<([^>]+)>).*?(<(/\2)>)\s*(\1.*?\3)',re.S)

with open(sys.argv[1],'r') as f: fic=f.read()
with open(sys.argv[2],'w') as g:

   while True :
      k=rec.search(fic)
      if(k) :
         g.write(fic[:k.end(3)])
         fic=fic[k.end(0):]
      else :
         g.write(fic)
         break

À lancer ainsi :

python noeud_dupli.py fichier_original fichier_modifie

J'ai choisi la méthode qui me paraît la plus simple.

Hors ligne

#7 Le 21/04/2016, à 11:46

carreti

Re : Suppression de noeud XML sed/awk...

Hello,

sinon il existe quelques utilitaires en ligne de commande qui permettent d'utiliser du XQuery et/ou du XPath qui pourraient faire le nécessaire avec la requête FLWOR qui convient ...

Il est probablement possible de spécifier comme condition au "return" la présence du nœud <d></d> et de tronquer toute la branche dupliquée ... mais il est préférable de connaitre et de considérer les namespaces impliqués.
La réécriture d'un XML en sortie n'est qu'un détail (voir, un autre avantage) en XQuery.

Solution peut-être plus compliquée à mettre en oeuvre mais d'une robustesse à toute épreuve, facilement maintenable et évolutive, le tout, dans le strict respect de la DOM XML ...

Une toute petite introduction au XQuery sur le W3C ...

Dernière modification par carreti (Le 21/04/2016, à 12:01)


Utilisateur et administrateur de Linux et d'Unix (depuis le siècle dernier) et plus précisément ces dernières années de  Linux Gentoo et de Windows 10 ...
Je cherche du boulot sur Paris et RP Ouest en administration système ou mieux dans la tierce maintenance applicative, middleware, base de données, flux ...

Hors ligne

#8 Le 21/04/2016, à 11:47

Filador

Re : Suppression de noeud XML sed/awk...

D'accord, merci pingouinux, en réalité, c'est parce que je fais d'autres opérations dans un script shell avant de vouloir enlever les doublons, d'où mon envie de chercher une commande shell (awk, sed,...), même si celle-ci est compliquée tu penses que c'est possible ?

Je te remercie en tout cas !

Hors ligne

#9 Le 21/04/2016, à 12:17

credenhill

Re : Suppression de noeud XML sed/awk...

hello
essayer

$ awk 't[$0] {x=$1; sub("<", "</", x); getline a; while (a !~ x)getline a} !t[$0] {print; t[$0]=$0}' fichier
<a>
  <b>
    <c>
       <d></d>
    </c>
  </b>
</a>

Hors ligne

#10 Le 21/04/2016, à 14:15

Filador

Re : Suppression de noeud XML sed/awk...

credenhill a écrit :

hello
essayer

$ awk 't[$0] {x=$1; sub("<", "</", x); getline a; while (a !~ x)getline a} !t[$0] {print; t[$0]=$0}' fichier
<a>
  <b>
    <c>
       <d></d>
    </c>
  </b>
</a>

Hello credenhill,

ça marche avec l'exemple, mais pas pour de plus gros fichiers avec des doublons. :'(

Je te remercie quand même smile

Hors ligne

#11 Le 21/04/2016, à 16:02

credenhill

Re : Suppression de noeud XML sed/awk...

je pensais aussi, peux montrer des données plus réelles ?

Hors ligne

#12 Le 21/04/2016, à 16:47

carreti

Re : Suppression de noeud XML sed/awk...

Re,

donc en XQuery ça donnerait une query file (test.xq) de type :

<a>
{
for $x in doc("test.xml")/a/b/c
where exists("$x/d")
    return (
            <b>
                <c>
                    <d>{data($x/d)}</d>
                </c>
            </b>
            )
}
</a>

ici je teste l'existence d'un noeud "d" dans un chemin "a/b/c" ...

[edit]Le where est pas nécessaire

declare boundary-space preserve;
for $x in doc("test.xml")/a/b/c
    return (<a>
    <b>
        <c>
            <d>{data($x/d)}</d>
        </c>
    </b>
</a>)

Fonctionne aussi ...
declare boundary-space preserve;
Permet d'éviter la beautification si le code est correctement indenté.
[/edit]


et en utilisant comme processeur XQuery une solution comme XQilla on appellerait :

xqilla test.xq

qui en sortie donnera :

<a><b><c><d>foo</d></c></b></a>

rien n'empêche de beautifier avec xmllint :

xqilla test.xq | xmllint --format -
<?xml version="1.0"?>
<a>
  <b>
    <c>
      <d>foo</d>
    </c>
  </b>
</a>

J'ai considéré qu'aucun nœud sauf le "d" (et le "f") n'avait de données ...

Mon fichier test.xml

<a>
  <b>
    <c>
       <d>foo</d>
    </c>
  </b>
  <b>
    <e>
       <f>bar</f>
    </e>
  </b>
</a>

En plus on peut tester la valeur des données en modifiant un peu la query file, utiliser des variables, utiliser les namespaces pour simplifier l'écriture, etc ...

Par contre, je ne pense pas que XQilla soit du standard Ubuntu ...
[EDIT]Je viens d'installer en virtualbox la 16.04 et xqilla fait bien parti des dépôts officiels[/EDIT]

Dernière modification par carreti (Le 23/04/2016, à 15:26)


Utilisateur et administrateur de Linux et d'Unix (depuis le siècle dernier) et plus précisément ces dernières années de  Linux Gentoo et de Windows 10 ...
Je cherche du boulot sur Paris et RP Ouest en administration système ou mieux dans la tierce maintenance applicative, middleware, base de données, flux ...

Hors ligne