Forum Programmation.shell remplacement valeur attribut xml particulier

Posté par  .
Étiquettes : aucune
0
15
oct.
2010

Salut à tous :)
j'ai un problème assez simple mais cela fait presque 1h que je cherche le net en vain :(
Je dois tout "simplement" remplacer le contenu d'une balise XML, pour un élément particulier. Exemple :

[balise1]
[nom]toto[/nom]
[valeur]valeur_toto[/valeur]
[/balise1]
[balise2]
[nom]tata[/nom]
[valeur]valeur_tata[/valeur]
[/balise2]


(HS : désolé mais je n'ai pas trouver comment faire les "inférieur" et "supérieur"... je les ai donc remplacé par [ et ]...).

J'aimerais remplacer la valeur de [valeur] uniquement pour la [balise1]. Je voulais savoir si c'était possible avec sed ou awk, parce que j'ai testé quelques trucs avec sed, mais sans succès :/

Merci d'avance !
  • # xmlstarlet

    Posté par  (site web personnel) . Évalué à 1.

    Une solution qui n'utilise pas sed ni awk (mais qui me semble plus facilement adaptable aux variations du document xml) :

    xmlstarlet ed -u "/xml/balise1/valeur" -v "nouvelle_valeur" test.xml

    J'ai modifié ton exemple pour l'englober entre des balises [xml] histoire que le parser ne soit pas choqué par l'apparition de la balise2.
    Apparemment le binaire peut varier de nom selon la distribution/provenance.

    http://xmlstar.sourceforge.net
    http://xmlstar.sourceforge.net/doc/xmlstarlet.txt
    • [^] # Re: xmlstarlet

      Posté par  . Évalué à 1.

      Arf c'est bête j'ai oublié de préciser un truc assez important... En fait la commande sera exécutée sur un serveur au boulot, mais nous n'avons pas les droits pour installer de trucs dessus. En clair, il faut se contenter des commandes "de base"...
      Tant que j'y suis, c'est un serveur AIX, donc il y a quelques petites différences avec une distrib "standard", peut-être que ça vaut le coup de le signaler !

      Merci pour l'info cependant !
      • [^] # Re: xmlstarlet

        Posté par  (site web personnel) . Évalué à 1.

        avec awk ca doit etre possible en quelques lignes oui.

        j'ai pas de console sous la main et j'en aurai pas avant demain quand j'serais rentré chez moi, donc je peux pas te prouver mes dires mais...

        Avec awk tu peux aisément simuler une machine à état.

        Donc tu déclare un pattern [balise1] et dans le code associé tu mets juste un flag à true quand le pattern est rencontré.

        Par défaut, pour tous les patterns rencontrés tu recopie la ligne telle quelle

        tu définie ensuite un pattern 2 "[valeur]" et dans le code associé tu vérifie que le flag vu précédemment est sur true, car si c'est le cas c'est que tu es bien situé sous balise1.
        Donc tu recopie la ligne en substituant à la volée ce qui t'arrange.

        Ensuite tu penses à remettre à false le flag pour qu'il le reste jusqu'à la fin du fichier, sinon tu vas modifier toutes les balises [valeur] à venir...

        Et le fichier est ainsi recopié ligne par ligne jusqu'à la fin.

        J'sais pas si c'est clair ce que je dis :)

        Bien sûr ça suppose avoir déjà fait du awk sinon j'dois parler chinois là
  • # xmlstarlet (avec sed)

    Posté par  (site web personnel) . Évalué à 2.

    xmlstarlet permet de convertir le XML en un format orienté lignes : PYX. Cela permet de le filtrer par des outils comme sed ou awk, puis de le reconvertir en XML avec xmlstarlet.
  • # IFS+sed, ok pour AIX ?

    Posté par  . Évalué à 2.

    IFS='[/balise1]'; sed -e 's,\[valeur\]([^\[]\+)\[/valeur\]\n\[/balise1\],[valeur]NOUVELLE VALEUR[/valeur]\n[/balise1],g'

    modulo les erreurs basiques que je fais tout le temps avec sed et que les commentateurs suivants pourront corriger

    le IFS c'est pour dire à sed de découper son fichier d'entrée en blocs se terminant par [/balise1], et le sed sélectionne l'élément valeur contenu dans l'élément balise1 et en change le contenu

    La syntaxe n'est peut être pas la bonne, mais l'idée est là
    • [^] # Re: IFS+sed, ok pour AIX ?

      Posté par  (site web personnel) . Évalué à 2.

      Tu ne te serais pas pourri ton propre shell, en modifiant IFS ? Si c'est pour passer une variable d'environnement à sed, autant faire :
      IFS="[…]" sed […]
    • [^] # oula !

      Posté par  . Évalué à 0.

      IFS comprend des caractères (par défaut " ' ' '\t '\n' "), et les considère comme des alternatives l'un à l'autre : (IFS='bdf' read -a var <<< "abcdefg"; echo "${var[@]}")
      a c e g
  • # Et perl alors ?

    Posté par  (site web personnel) . Évalué à 3.

    Suivant ce qui est "install" sur le serveur tu pourras t'amuser avec XML::Parser , XML::Simple...etc...
    Ensuite remplacer un champs ça devrait se gérer....

    NB : si tu pars sur le parseur fait attention de ne pas remplacer toutes les occurrences de 'valeur' et met une variable de détection / blocage à la zone balise1... Bref, vérifie bien ce que tu codes..

    Fuse : j'en Use et Abuse !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.