web-dev-qa-db-fra.com

Comment extraire un seul attribut d'un fichier XML?

Je ne connais pas vraiment regex, sed, etc. et je suis un peu paresseux pour comprendre tout de suite, alors comment puis-je extraire cette ligne:

<yweather:astronomy sunrise="6:50 am" sunset="7:06 pm"/>

Faites-moi savoir si plus de la structure XML est nécessaire.

2
knl

Étant donné que les données d'entrée (votre fichier XML) sont structurées, il vaut mieux utiliser une requête sur ces données structurées plutôt que de le traiter comme du texte brut et de jouer avec des expressions régulières.

Nous pouvons utiliser xmllint --xpath pour évaluer une expression XPath sur votre entrée XML:

$ xmllint --xpath 'string(rss/channel/*[local-name()="astronomy"]/@sunrise)' weather.xml
6:48 am

- c'est un peu compliqué, car nous devons traiter les différents espaces de noms dans ce fichier, mais cela fonctionne néanmoins.

Pour plus d'informations sur XPath, la spécification se trouve à http://www.w3.org/TR/xpath/

5
Jeremy Kerr

Vous n'utilisez pas regex ou sed. Vous utilisez un analyseur XML et un langage de requête XML (XPath ou XQuery). Et je crains que les détails dépendent du contexte: par exemple, "yweather" est un nom abrégé (préfixe) pour un espace de noms et vous devez savoir quel espace de noms il représente.

3
Michael Kay

Comme le dit Michael Kay, la bonne réponse consiste à utiliser un outil spécifique à XML.

Pour une solution rapide et sale, voici une approche sed. Commençons par ce fichier:

$ cat file
<yweather:astronomy sunrise="6:50 am" sunset="7:06 pm"/>

Pour extraire l'heure du coucher du soleil:

$ sed -rn 's/.*sunset="([^"]*)".*/\1/p' file
7:06 pm

Pour comprendre la regex, divisons-la en trois parties:

  1. .* correspond depuis le début de la ligne jusqu'à la deuxième partie

  2. Cette partie, sunset="([^"]*)", correspond aux caractères sunset=", suivis d'un nombre quelconque de caractères sauf ", suivis du " de fermeture. L'expression [^"] signifie n'importe quel caractère sauf " et [^"]* signifie n'importe quel nombre de ces caractères. Les parenthèses, (...), capturent les caractères à l'intérieur de "..." dans le groupe 1 de sed, que nous désignerons plus tard sous le nom de \1.

  3. .* correspond à tous les caractères après l'expression de coucher de soleil.

2
John1024

Je donnerai la même réponse de Jeremy Kerr mais en lui donnant un xml par exemple.

Nous avons un fichier XML appelé config.xml dans le dossier racine, et nous voulons lire un attribut ou une propriété d'une balise, que ce soit la balise widget.

config.xml:

<?xml version='1.0' encoding='utf-8'?>
<widget Android-versionCode="16" id="co.app.world" ios-CFBundleVersion="0.1.3" version="3.0.5" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.Apache.org/ns/1.0">
    <name>AppName</name>
    <description>Description.</description>
    <author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
</widget>

Nous voulons obtenir la valeur de la propriété Android-versionCode, nous le tapons dans le terminal:

xmllint --xpath "string(//*[local-name()='widget']/@Android-versionCode)" config.xml

Sortie:

16

Explication: nous utilisons /*[local-name()='widget'] pour mapper la balise widget, puis @Android-versionCode pour en lire la propriété.

0
Luigi Lopez