IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Récupérer les valeurs d'un fichier xml avec xmllint.


Sujet :

Linux

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut Récupérer les valeurs d'un fichier xml avec xmllint.
    Bonjour,

    Supposons que mon fichier test.xml soit de cette forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <root>
            <Balise1>txt1</Balise1>
            <Balise2>
                    <ssBalise2_1>txt2</ssBalise2_1>
                    <ssBalise2_2>
                                    <ssBalise2_2_1>txt3</ssBalise2_2_1>
                                    <ssBalise2_2_2>txt4</ssBalise2_2_2>
                    </ssBalise2_2>
            </Balise2>
    </root>
    En utilisant xmllint --shell test.xml, il arrive bien dans le shell du xmllint et l'on peut naviguer dans le fichier.
    Jusque là, tout va bien.

    Ma question est toute simple : comment récupérer la valeur txt3 et txt4 en utilisant xmllint en ligne de commande sans le shell du xmllint ?
    Le principe est que je dois créer des scripts qui vont lire des fichiers xml et forcément, je ne peux pas avoir une interaction avec l'utilisateur.
    Il faut donc dans une ligne de commande, récupérer les valeurs que je souhaite pour pouvoir les utiliser après dans une variable dans mon script.

    D'avance, merci pour vos réponses !
    Bonne journée à tous !

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    Bonjour,

    mais que tapes-tu une fois dans le shell xmllint ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    J'utilise un cd pour arriver dans le noeud souhaité et ensuite, je fais un ls qui me donne la valeur que je souhaite avoir.

  4. #4
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    Citation Envoyé par gabydebur Voir le message
    J'utilise un cd pour arriver dans le noeud souhaité et ensuite, je fais un ls qui me donne la valeur que je souhaite avoir.
    en deux invocations distinctes ça peut se faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ xmllint --xpath '//root/Balise2/ssBalise2_2/ssBalise2_2_1/text()' fichier
    txt3
    $ xmllint --xpath '//root/Balise2/ssBalise2_2/ssBalise2_2_2/text()' fichier
    txt4
    en une seule invocation en revanche j'ai pas mieux que ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xmllint --xpath '//root/Balise2/ssBalise2_2/*' fichier | awk -F'[<>]' '{print $3 "\n" $7}'

  5. #5
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    Merci pour ta réposne qui serait pour moi nickel !
    Malheureusement, je n'arrive pas à utiliser l'option --xpath. L'erreur remontée est :
    Manquerait-il un package ? et si oui lequel ?
    Si non, pour quelles raisons je ne peux pas utiliser xpath ?

    Merci pour tout !

  6. #6
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    il semblerait que certains (beaucoup) de clients ne supportent pas l'option --xpath, dommage

    une autre solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xmllint --shell fichier <<EOF | awk 'NR == 3 || NR == 5'
    cat //root/Balise2/ssBalise2_2/*/text()
    EOF
    (on pourra aussi remplacer le awk par awk '!/^ ---|^\/ >/')

  7. #7
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut
    Bonjour,

    Vraiment merci pour ce code, ca marche du tonnerre en ligne de commande, c'est génial! Exactement ce que je recherchais !
    Mais peut on l'intégrer dans un script shell ?

    J'ai en effet une erreur quand j'essaie de faire fonctionner ce bout de code à l'intérieur d'un script.
    Il marque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Caractère de fin de fichier (EOF) prématuré lors de la rechercher du " " " correspondant.
    Merci d'avance pour vos réponses !
    Bonne journée !


    Citation Envoyé par BufferBob Voir le message
    il semblerait que certains (beaucoup) de clients ne supportent pas l'option --xpath, dommage

    une autre solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    xmllint --shell fichier <<EOF | awk 'NR == 3 || NR == 5'
    cat //root/Balise2/ssBalise2_2/*/text()
    EOF
    (on pourra aussi remplacer le awk par awk '!/^ ---|^\/ >/')

  8. #8
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut
    Voici le script qui pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    #! /usr/bin/bash
    ####################################################################################
    #                                                                                  #
    #    Script      : VerifLiv.ksh                                                    #
    #    Autheur     : Gabydebur	                                                   #
    #    Version     : 2.1                                                             #
    #    Date 	     : 18/08/2016                                                      #
    #    Parametre   : RepLivraison : Repertoire de la livraison à checker             #
    # 				   EnvironnementCible : l'environnement a installer                #
    #    Commentaire : Check si la livraison est OK.                                   #																						
    #                  retourne 0 en cas d'erreur, 1 sinon.                            #
    ####################################################################################
     
    #Parametre globaux. 
    FichierLog=/tmp/gaby/VerifLog.log
    Rapport=/tmp/gaby/RapportDossierInstall.log
     
     
    #
    # Permet de creer des logs contenu dans le fichier log parametre dans les variables globales. 
    # La fonction prend comme parametre le texte et l'insère dans le fichier.
    #
    LogM ()
    {
    	datelog=$(date +%d%m%Y-%H:%M:%S)
    	if [ -f $FichierLog ]
    	then
    		echo -e "$datelog - $1" >> $FichierLog
    	else
    		echo -e "$datelog - $1" > $FichierLog
    	fi
    }
     
    #
    # fonction décrivant l'usage du script. 
    #
    usage ()
    {
    	echo -e "VerifLiv.sh [RepLiv] [EnvCible] \n"
    	echo -e "RepLiv : Repertoire de livraison a checker.\n"
    	echo -e "EnvCible : Environnemnet d'installation cible.\n"
    	LogM "fin $0 $1 $2"
    }
     
    #
    # Fonction permettant d'écrire le rapport. 
    #
    EcrireR ()
    {
    	LogM "EcrireR $1"
    	datelog=$(date +%d%m%Y-%H:%M:%S)
    	if [ -f $Rapport ]
    	then		
    		echo -e "$datelog - $1" >> $Rapport
    	else
    		echo -e "$datelog - $1" > $Rapport
    	fi
    }
     
    {
    	#On va vérifier si les fichiers rapport et log existent. Si c'est le cas, on les supprime.
    	if [ -f $FichierLog ]
    	then 
    		sudo rm -rf $FichierLog
    	fi
     
    	if [ -f $Rapport ]
    	then
    		sudo rm -rf $Rapport 
    	fi
     
     
    	LogM "debut $0 $1 $2"
    	#Verif que le nombre d'argument est bien a 2
    	if [ $# -ne 2 ] 
    	then 
    		usage
    		LogM "Fin du programme VerifLiv KO"
    		exit 0
    	fi
     
    	#Recuperation du premier argument de la commande, le repertoire a tester.
    	rep=$1
    	LogM "repertoire = $rep"
    	# Verif 1 : L'existence du dossier de livraison
    	LogM "Verif 1 : Repertoire inexistant?"
    	if [ ! -d $rep ]
    	then 
    		usage
    		EcrireR "[FATAL] : Pas de repertoire de livraison => LIVRAISON KO."
    		LogM "Fin du programme VerifLiv KO"
    		exit 0
    	fi
     
    	EcrireR "[SUCCESS] : Repertoire existant"
    	# En arrivant ici, on sait que le répertoire existe. 
    	# On va découper le nom du répertoire avec les /, récuperer le dernier champ qui sera le nom du répertoire,
    	# le splitter avec le _ et récupérer la version à installer (nom du répertoire [DATE]_[VERSION]
    	# Cette version sera utilisee pour verifier que le doc de livraison existe, avec l'environnement cible.
     
    	LogM "Verif 2 : Fiche de livraison inexistant ?"
    	#Recuperation du dernier champ (ex /tmp/gaby/toto ca donnerait toto)
    	NomRep=${rep##*/}
    	LogM "nom du repertoire : $NomRep"
    	#Récupération de la version, sur le même principe"
    	version=${rep##*_}
    	LogM "Version : $version"
     
    	# Verif 2 : On verifie que le fichier de livraison est bien située dans le repertoire.
    	# Si ce n'est pas le cas, on arrete le programme avec code retour 0. 
    	# typiquement le fichier s'appele "Livraison - INS - [ENVIRONNEMENT] [VERSION].doc
    	# Il faut donc verifier que le fichier "[rep]/DOCUMENTATION/Livraison*[ENVIRONNEMENT] [VERSION]*" existe.
    	nbfichier=$(find $rep/DOCUMENTATION -name "*$2 v$version*" | wc -l)
    	LogM "nb de fiche de livraison = $nbfichier"
    	if [ $nbfichier != 1 ]
    	then
    		EcrireR "[FATAL] : Pas de fiche de livraison => LIVRAISON KO."
    		LogM "Fin du programme VerifLiv KO"
    		exit 0
    	fi
    	EcrireR "[SUCCESS] : Fiche de livraison existante"
    	# A ce niveau, la fiche de livraison existe.	
    	# Maintenant, on va faire une boucle sur les dossiers contenus dans le repertoire.
    	# En fonction des repertoires, on va lister chacuns des fichiers et ensuite, il faudra trouver le moyen de comparer par rapport au fichier de livraison. 
    	# 
    	# V1 : Pour le moment, On ne va checker que si la taille des fichiers n'est pas nulle. 
    	# V2 : On incorpera la lecture du xml pour checker veritablement les fichiers.
    	# 
     
    	# Verif 3 : Taille des fichiers. 
    	LogM "Verif 3 : Presence de fichier vide"
    	nbfichier=$(find $rep -size 0 | wc -l)
    	if [ $nbfichier != 0 ]
    	then
    		EcrireR "[ERROR] : $nbfichier fichier(s) vide(s) present(s) ! => LIVRAISON KO"   
    		LogM "Fichier vide => Livraison KO"
    		exit 0
    	fi
    	LogM "Fin verif fichier vide"
    	EcrireR "[SUCCESS] : Pas de fichier vide"
     
    	#A FAIRE : Vérifier l'ensemble des repertoires 
    	# Faire une boucle sur les répertoires et vérifier un à un les fichiers. 
    	# Faire une boucle sur les répertoires et vérifier un à un les fichiers.
    	# Principe de l'algo : 
    	# on boucle sur chacun des sous-repertoires. 
    	# Pour chacun, la premiere verification est le nombre des fichiers present par rapport a la feuille de livraison.
    	# livraison KO si différents.
    	# ensuite, on va boucler sur chacun des fichiers presents dans la fiche de livraison. Et on checke s'ils sont presents dans le repertoire. 
    	# si OK : livraison OK. Sinon, livraison KO.
    	# 2 Cas particuliers dans les sous-repertoires : 
    	# DOCUMENTATIONS => On ne fait rien. 
    	# SQL => On ne fait rien. 
    	# Quand un répertoire est trouvé dans la livraison mais n'est pas dans la fiche de livraison => KO. 
    	LogM "Debut de verification des repertoires."
    	listerep=$(find $rep/* -type d )
    	for repertoire in $listerep
    	do
    		#repertoire contient le chemin complet. Ce qui nous interesse, c'est le dernier sous repertoire. 
    		repertoire=${repertoire##*/}
    		LogM "repertoire = $repertoire"
     
    		LogM "Recuperation du nombre de fichiers"
    		xmllint --shell $fichelivraison <<FINLEC | awk '!/^ ---|^\/ </' > $FichierTmp
    		cat //livraison/$repertoire/nbFichier/text()
    		FINLEC
     
    		exec 3<$FichierTemp
    		i=1
    		nbfic=''
    		nbligne=$(cat $FichierTemp | wc -l)
    		while read ligne <&3
    		do
    			if [[ $i -ne 1 ] || [ $i -ne $nbligne ]]
    			then
    				nbfic=$nbfic$ligne
    			fi
    			((i+=))		
    		done
    		LogM "nb de fichier dans le repertoire $repertoire : $nbfic"
     
    				#On boucle sur les fichier et on verifie leur existence dans le repertoire.
    		i=1
     
    		while [ $i -lt $nbfic ]
    		do
    			#On recupere son nom et sa version dans le fichier. 
    			LogM "xmllint du fichier $i de $repertoire"
    			xmllint --shell $fichelivraison <<TOTO | awk '!/^ ---|^\/ </' > $FichierTmp
    				cat //livraison/$repertoire/Fichier$i/text()
    			TOTO
     
    			nomVersion=''
    			exec 3<$FichierTemp
    			j=1
    			nbligne=$(cat $FichierTemp | wc -l)
    			while read ligne <&3
    			do
    				if [[ $i -ne 1 ] || [ $i -ne $nbligne ]]
    				then
    					nomVersion=$nomVersion$ligne
    				fi
    				((i+=))		
    			done
    			LogM "Nom du fichier $i : $nomVersion"
     
    			#On verifie son existence et son unicite. Si different de 1, livraison KO.
    			nbDuFichier=$(find $rep/DOCUMENTATION -name "*$nomVersion*" | wc -l)
    			LogM "nb de fichier $nomVersion = $nbDuFichier"
    			if [ $nbDuFichier != 1 ]
    			then
    				EcrireR "[FATAL] : $nomVersion trop nombreux ou absent => LIVRAISON KO"
    				LogM "Fin du programme VerifLiv KO"
    				exit 0
    			fi
    		done
    	done
     
     
    	LogM "$0 termine\n"
    	#Si on arrive là, c'est que tout est ok ! 
    	EcrireR "[SUCCESS] : Livraison OK!"
    	exit 1
    }
    J'ai essayé :
    • Refaire le fichier
    • Changer les delimiteur EOF par TOTO et un autre.
    • Mettre la liste des repertoires dans une variable et l'integrer dans le for


    Je ne sais pas où cela bug...
    Toujours cette même erreur fin de fichier prématuré.

    Merci pour votre aide !

  9. #9
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    c'est une tabulation qui pose problème.
    le here-doc commence par, il doit finir parsur la première colonne du fichier (tout à fait à gauche).
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut
    Je n'ai qu'un seul mot à te dire :
    Meeeerciiiiiii !!

  11. #11
    Membre à l'essai
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Août 2016
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2016
    Messages : 25
    Points : 21
    Points
    21
    Par défaut Récupération des &amp; dans le texte des noeuds.
    Bonjour,

    J'ouvre cette discussion de nouveau car je me retrouve confronté à un problème avec les &amp;.

    Supposons que je dois aller rechercher le "txt3" dans le fichier.
    Celui-ci contient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    export JAVA_HOME=/opt/java/jdk/jre/&amp;&amp;cd /opt/jaspersoft/jasperreports-server-6.1.1-bin/buildomatic&amp;&amp;./js-export.sh --uris /organizations/MonOrganisation--output-dir /tmp/IntegrationSav
    Lorsque je vais chercher avec la méthode décrite plus haut (donc un cat /chemin/text() que je met dans un fichier temporaire), les &amp; ne sont pas reconnus et ne sont donc pas remplacés par des "&".
    Pourtant, cela fonctionne avec les &pos; et les &quot;.

    Quelqu'un peut il me dire pourquoi cela ne fonctionne pas ?

    Merci d'avance.
    Bonne soirée!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [DOM] Récupérer les attributs d'un fichier XML en XPATH AVEC DOM
    Par jean22 dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 26/06/2013, 16h02
  2. [XML] Récupérer les données d'un fichier XML sur URL avec php
    Par ValooWart dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 01/03/2013, 16h40
  3. Réponses: 3
    Dernier message: 14/03/2007, 15h30
  4. [XSL]récupérer une valeur de plusieurs fichiers XML
    Par snoop dans le forum XSL/XSLT/XPATH
    Réponses: 7
    Dernier message: 05/02/2006, 00h32
  5. [](VB) Récupérer les données dans un fichier .xml
    Par Furius dans le forum VBScript
    Réponses: 4
    Dernier message: 02/10/2005, 20h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo