Newsgroup: it.comp.os.linux.sys
Titolo: parsing file XML

Scusate innanzitutto per la lunghezza del messaggio. Dato un file XML di
questo tipo:
<!DOCTYPE KEEPASSX_DATABASE>
<database>
 <group>
  <title>Server Linux</title>
  <icon>62</icon>
  <group>
   <title>Esercizio</title>
   <icon>0</icon>
   <entry>
 [ CUT: qui c'è una lista di server ]
  </group>
  <group>
   <title>Collaudo</title>
   <icon>0</icon>
   <entry>
 [ CUT ]
 </group>
  <group>
   <title>Sviluppo</title>
   <icon>0</icon>
   <entry>
 [ CUT ]
  </group>
 </group>
</database>
IO DEVO: "greppare" l'occorrenza "url" e "password", ma solo per i
server di Esercizio, quindi dal tag "<title>Esercizio</title>", fino
alla sua chiusura.
Secondo voi qual è il metodo più umano per fare questa cosa con la
shell? Ho già fatto uno script che fa uso di due array, uno contenente
i server e uno contenente le password. Adesso però è nata l'esigenza di
costruire questi array solo per un unico gruppo di server all'interno
del file.
-- 
Wikipedia Admin: "wikipedia non è un blog"
Iosif Stalin: "i compagni hanno scambiato il partito per un circolo di
discussione"

 shell? 
perl
XML::Parser
-- 
Flavio Visentin
Scientists have finally discovered what's wrong with the female brain:
On the left side, there is nothing right, and on the right side, there
is nothing left.

 XML::Parser
purtroppo ho già fatto il 90% del lavoro in shell.



Perchè insistere con la shell ?
Non è adatta per queste cose
La risposta ti è già stata data;
usa un parser in un linguaggio come perl,python,java,ecc..
e includi la chiamata nella shell

  ...
Usare Perl o AWK.
Lascia perdere grep e sed; quello che vuoi fare è al limite delle
loro possibilità.

 Perchè insistere con la shell ?
Perché è una sfida, come volare con un accrocchio fatto di nylon, 
tubi di alluminio e un motore di un Ciao Piaggio.
 
sed -n ' \_<title>Esercizio</title>_,\_</group>_ { /url/p;/password/p }' ... 
PS Lo so, ma non ho resistito.

 loro possibilita'.
roby@rcwalker:~# awk -F '<|</|>' -v apice=\" -v contatore=0 
'/<title>|<url>|<password>/ {if ($2 == "title") {if ($3 == "Esercizio") 
{contatore = 1} else {contatore = 0}} if (contatore == 1) {print apice $2 
apice,$3}}' nome_file.xml
"title" this
"url" 0001
"password" 0000
"url" 0002
"password" 0000
ciao.
Corrado Roberto
Cossato - Biella
Fingerprint: 8FC8 05DE 2B53 A8AF 8B2B 6CBF AD23 C4D5 86FE 80BB



Sfide a parte, ci sono tanti buoni motivi per non fare il parsing di XML 
con strumenti rivolti all'elaborazione del testo.
Per quanto riguarda la domanda iniziale, da shell direi che si può fare 
con xsltproc e un'apposita trasformazione xslt.

 XML con strumenti rivolti all'elaborazione del testo.
e ancora sfida a parte, premetto ovviamente la superiorità degli altri
linguaggi, però da quando con bash 4 ci sono anche gli array
associativi, direi che non manca più quasi nulla. E tra la shell, e i
tool a disposizione su tutti gli unix, ce la si può cavare nella quasi
totalità dei casi.


 { /url/p;/password/p }' ... 
thumb up :-) Grazie.
p.s.: fra l'altro, grazie ai tanti tool a disposizione, le soluzioni
con la shell sono spesso (come in questo caso) "one-line solutions".
E questo (tranne che non usi i moduli pappa-pronta del perl) non è
quasi mai possibile con i linguaggi..... anche se a voler essere
puntigliosi: sed != shell, ma è anche un tool che sulle macchine unix è
più diffuso di perl e di python.



Si, ma perl rimane sempre piu ricco della shell (te lo dice uno che 
progetta in perl anche in obj)

 tubi di alluminio e un motore di un Ciao Piaggio.
Io ti aspetto a terra, buona fortuna :)
Nicola.
-- 
chi va pian va san e va lontan


Tranquillo: non lo metto neanche minimamente in dubbio :-)
Massimiliano

 Addì  martedì 5 aprile 2011 19:58 Max_Adamo scrisse:

no no: il tuo suggetimento delle 23:53 è entrato a far parte del mio
script e va più che bene.
Non che non possa usare awk, però va benissimo con quella unica riga di
codicillo. Perché andare a installare ulteriori librerie per perl,
mettendo a rischio la portabilità (dovrò installare la libreria in
ciascuna macchina dove voglio far girare lo script), o perché andare a
scrivere cose interminabili?


 ...
ATTENZIONE! Il codice sed che ho scritto non va affatto bene.
È una soluzione rattoppata, un trucchetto e non funziona sempre.
L'unica soluzione è fare il parsing (non è necessario ricorrere
a librerie sofisticate, si può fare a mano) che però risulta 
complicato e inefficiente farlo con sed o con la bash.
Poi sta attento alla portabilità: Perl è uno standard su Unix,
non troverai mai un sistema Unix dove non ci sia perl e non è
necessari ricorrere a librerie sofisticate per fare il parsing.
Viceversa bash e sed *NON* sono standard. Troverai molti 
sistemi dove non è installata bash ed è ancora più facile 
incappare in qualche particolarità del GNUsed che ignoravi.

 ...
Il vero problema della shell (non di bash ma di tutte le 
shell) è  che sono linguaggi per interagire col sistema
operativo, connettere i programmi e controllare i processi.
Non sono adatti a elaborare testi o fare altro. Altrimenti
AWK e Perl non sarebbero neanche nati.

 incappare in qualche particolarità del GNUsed che ignoravi.
ma troverei 99 sistemi su 100 dove non è installato XML::Parser :-)
Nella realtà dei fatti, io dovrò lanciare quello script da una macchina
linux a caso e l'unico requirement che ho per il momento è expect (che
prende le password dall'XML originale per fare login e cambiare le
password).


 password).
Password in chiaro in un file XML?