69 votes

Comment analyser le XML en utilisant le shellscript ?

Je voudrais savoir quelle serait la meilleure façon d'analyser un fichier XML en utilisant un script shell ?

  • Faut-il le faire à la main ?
  • La bibliothèque de troisième niveau existe-t-elle ?

Si vous l'avez déjà fait, faites-moi savoir comment vous avez réussi à le faire.

3 votes

Devez-vous le faire en Shell ? Je sais qu'il est facile de le faire en Perl ou en Python.

0 votes

Une fois que le parseur a analysé le xml, que voulez-vous en faire ?

0 votes

@Joel : Je veux récupérer des adresses email à partir d'un fichier xml défini et envoyer des emails à ces adresses.

95voto

Joel Points 11003

Vous pouvez essayer xmllint

Le programme xmllint analyse un ou plusieurs éléments suivants fichiers XML, spécifiés dans la commande de commande comme xmlfile. Il imprime différents types de sortie, selon les options options sélectionnées. Il est utile pour détecter les erreurs à la fois dans le code XML et dans l'analyseur XML lui-même

Il vous permet de sélectionner des éléments dans le document XML par xpath, en utilisant l'option --pattern.

Sous Mac OS X (Yosemite), il est installé par défaut.
Sur Ubuntu, s'il n'est pas déjà installé, vous pouvez exécuter apt-get install libxml2-utils

1 votes

Ceci, par exemple, permettrait d'extraire la valeur textuelle du corps de la balise sample_type (utilisée seulement maintenant pour les ensembles de résultats TCGA). {{ xmllint --xpath 'sample_type/text()' result.xml }}

1 votes

Dans Ubuntu 10.04.4 LTS il n'est pas installé par défaut (du moins il ne l'était pas sur ma machine). Nécessaire pour exécuter apt-get install libxml2-utils pour l'utiliser.

24voto

aesede Points 97

Voici un exemple complet et fonctionnel.
S'il ne s'agit que d'extraire des adresses e-mail, vous pouvez simplement faire quelque chose comme :
1) Supposons que le fichier XML spam.xml est comme suit

<spam>
<victims>
  <victim>
    <name>The Pope</name>
    <email>pope@vatican.gob.va</email>
    <is_satan>0</is_satan>
  </victim>
  <victim>
    <name>George Bush</name>
    <email>father@nwo.com</email>
    <is_satan>1</is_satan>
  </victim>
  <victim>
    <name>George Bush Jr</name>
    <email>son@nwo.com</email>
    <is_satan>0</is_satan>
  </victim>
</victims>
</spam>

2) Vous pouvez obtenir les emails et les traiter avec ce court code bash :

#!/bin/bash
emails=($(grep -oP '(?<=email>)[^<]+' "/my_path/spam.xml"))

for i in ${!emails[*]}
do
  echo "$i" "${emails[$i]}"
  # instead of echo use the values to send emails, etc
done

Le résultat de cet exemple est :

0 pope@vatican.gob.va
1 father@nwo.com
2 son@nwo.com

Remarque importante :
Ne l'utilisez pas pour les affaires sérieuses. C'est bien pour jouer, obtenir des résultats rapides, apprendre grep, etc. mais vous devriez définitivement rechercher, apprendre et utiliser un analyseur XML pour la production (voir le commentaire de Micha ci-dessous).

0 votes

C'est exactement ce que je recherchais. Cela fonctionne comme prévu, mais je ne comprends pas les arguments -o et -P et l'expression que vous utilisez pour le grep. Pouvez-vous l'expliquer ? J'essaie juste d'apprendre quelque chose de nouveau.

3 votes

Bonjour, le -o o --only-matching signifie "ne montrer que la partie correspondante", dans ce cas les emails. Le site -P o --perl-regexp signifie "utiliser une expression régulière comme si c'était du Perl". Vous pouvez voir cela et toutes les autres options en faisant simplement grep --help dans la ligne de commande. Vous pouvez également faire man grep pour le manuel complet.

2 votes

Il convient également de noter qu'il s'agit d'une manière rapide et sale d'obtenir des e-mails à partir d'un document XML. Vous pourriez obtenir le même résultat avec cette méthode en ligne de commande : for email in $(cat /my_path/spam.xml | grep -oP '(?<=email>)[^<]+'); do echo "$email"; done Si vous souhaitez l'utiliser pour la production, vous devez Définitivement utiliser un analyseur syntaxique XML. Dans mon cas, j'utilise Python scripts avec lxml

13voto

tim Points 71

Il y a aussi xmlstarlet (qui est disponible pour Windows également).

http://xmlstar.sourceforge.net/doc/xmlstarlet.txt

10voto

Keith Points 13800

Essayez sgrep . Ce que vous essayez de faire n'est pas clair, mais je n'essaierais certainement pas d'écrire un analyseur XML en bash.

3 votes

J'ai écrit un "analyseur" (je ne l'appellerais pas vraiment "analyseur", bien qu'il fonctionne assez bien) pour JSON en utilisant sed/awk, c'était un cauchemar.

7voto

frankc Points 6014

Avez-vous installé xml_grep ? C'est un utilitaire basé sur perl, standard sur certaines distributions (il était pré-installé sur mon système CentOS). Plutôt que de lui donner une expression régulière, vous lui donnez une expression xpath.

0 votes

Oui, j'ai eu plus de succès avec xml_grep, voici un exemple pour obtenir la chaîne de connexion d'un XML Jboss : xml_grep '/domain/profiles/profile[@name="server1"]//datasources//con‌​nection-url' domain.xml matches : <domaine> <profils> <profil name="server1">....<datasources>...<connection-url> Voir syntaxe XPath

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X