Προς το περιεχόμενο

bash script για δεδομένα σε xml ανάμεσα σε nested tags


nikolaos_

Προτεινόμενες αναρτήσεις

Θέλω έναν τρόπο να χρησιμοποιώ το bash για να ανακτώ δεδομένα τα οποία βρίσκονται ανάμεσα σε xml tags.

 

Παράδειγμα:

 

>
...
<employee>
<name> makis </name>
<salary> 700 </salary>
<bodymetrics>
<weight> 75 </weight>
<height> 1.65 </height>
</bodymetrics>
</employee>

<employee>
...
</employee>

...

 

και θέλω για έναν υπάλληλο (employee) που θα εντοπίζω με το <name> tag να ανακτώ το βάρος του ανάμεσα σε <weight> και </weight>

Να γράφω δηλαδή κάτι σαν

>
./myscript makis weight

και να απαντά 75

 

Το ίδιο αν υπάρχουν attributes στο tag.

 

Καμιά ιδέα?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ας κανω την αρχη επειδη δεν ξερω ουτε απο bash ουτε απο xml :P

 

Για να παρω τα οσα περιλαμβανονται μεταξυ <weight> και </weight> θα εκανα αυτο (εστω lista.xml το ονομα του αρχειου)

>cat lista.xml | grep weight | cut -c10-11

και θα ελεγε 75... και πολλους ακομα αριθμους.

 

Με μια καταχωρηση

>[b]$ cat Desktop/lista.xml | grep weight | cut -c10-11[/b]
75

Και με 2

>[b]$ cat Desktop/lista.xml | grep weight | cut -c10-11[/b]
75
80

:D

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κάτι πολύ quick and dirty είναι το παρακάτω. Σίγουρα θα υπάρχει ποιο σωστός τρόπος. Κάπου θα υπάρχει xml parser.

 

>
#!/bin/bash

name=$1
token=$2

flag=0

while read line
do
       echo  $line|grep $name > /dev/null 2>&1
       if [ $? -eq 0 ] || [ "$flag" -eq "1" ]; then
               flag=1
               echo  $line|grep $name |  sed -e 's/<[a-z]*>//' -e 's/<\/[a-z]*>//' -e 's/ //'|tr -d '\n'
               echo $line|grep $token |  sed -e 's/<[a-z]*>//' -e 's/<\/[a-z]*>//' -e 's/ //'
       fi

       echo $line|grep "</employee>" > /dev/null 2>&1
       if [ $? -eq 0 ] && [ "$flag" -eq "1" ]; then
               break
       fi
done < list.xml

 

[12:01 - firewalker@sapiokouti tmp]$ ./myscript makis height

makis 1.65

[12:02 - firewalker@sapiokouti tmp]$

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Νομίζω οτι καλύτερα θα ήτανε να φτιάξεις ένα πολύ μικρό python ή perl script χρησιμοποιώντας κάποιο έτοιμο module που μιλάει με την libxml.

 

Πολύ καλύτερα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σε pure bash, χωρίς χρήση εξωτερικών coreutils (grep, sed, awk κλπ):

 

>
!/bin/bash
FOUNDNAME=false
while read LINE
do
   if [[ $LINE == *\<name*\>$1\</name\> ]]
   then
       FOUNDNAME=true
       while read LINE
       do
           if [[ $LINE == *\</name\>* ]]
           then
               break
           elif [[ $LINE == *\<$2*\> ]]
           then
               LINE=${LINE#*\<*\>}
               LINE=${LINE%\<*\>*}
               echo $LINE
               exit
           fi
       done
   fi
done
if [[ $FOUNDNAME == false ]]
then
   exit 1
else
   exit 2
fi

 

Δουλεύει μόνο αν στο XML αρχείο δεν υπάρχουν κενά πριν και μετά την τιμή του κάθε element (στο παράδειγμά σου π.χ. υπάρχουν, θα πρέπει να αφαιρεθούν για να δουλέψει). Επιστρέφει την τιμή του ζητούμενου element με exit code 0 αν βρέθηκε, exit code 1 αν βρέθηκε το ζητούμενο employee element (υπήρχε child element name με τη δοθείσα τιμή) αλλά όχι το ζητούμενο child element του και exit code 2 αν δε βρέθηκε καθόλου το ζητούμενο employee element.

 

 

Παραδείγματα εκτέλεσης με το ακόλουθο αρχείο εισόδου:

<employee>

<name>makis</name>

<salary>700</salary>

<bodymetrics>

<weight>75</weight>

<height>1.65</height>

</bodymetrics>

</employee>

 

<employee>

<name>sakis</name>

<salary>800</salary>

<bodymetrics>

<weight>85</weight>

<height>1.75</height>

</bodymetrics>

</employee>

 

<employee>

<name>takis</name>

<salary>900</salary>

<bodymetrics>

<weight>95</weight>

<height>1.85</height>

</bodymetrics>

</employee>

 

 

>
parsifal@phenom2:/tmp$ ./myscript.sh makis salary < employees.xml 
700
parsifal@phenom2:/tmp$ ./myscript.sh sakis weight < employees.xml 
85
parsifal@phenom2:/tmp$ ./myscript.sh takis height < employees.xml 
1.85

 

 

Τα παιδιά όμως έχουν δίκιο' date=' το bash [b']δεν[/b] είναι το κατάλληλο εργαλείο για τη δουλειά που θέλεις να κάνεις.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καμιά ιδέα?

 

Χρησιμοποίησε κάποια interpreted γλώσσα με XML parser (python, perl, whatever). Η XML δεν είναι regular language για να γίνεται parse με regular expressions. Μπορείς πάντα να κάνεις parse ένα συγκεκριμένο κομμάτι XML με regular expressions, αλλά αν κάτι αλλάξει θα σου σκάσει.

 

Όπως λέει και ο jwz:

 

Some people, when confronted with a problem, think ``I know, I'll use regular expressions.'' Now they have two problems.

 

Enjoy.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κάποιοι, κάπου (ονόματα δεν λέμε) ζηλεύουν τον xml parser που κατασκεύασα. Ελπίζω μην σκάσουν μύτη...

 

:P:p:p

 

Ενα ντετερμινιστικο πεπερασμενο αυτοματο χωρις μνημη ΔΕΝ ειναι ικανο να αναγνωρισει το συνολο των αναδρομικως απαριθμησιμων γλωσσων. Να στο πω στα Ελληνικα για να το καταλαβεις;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ενα ντετερμινιστικο πεπερασμενο αυτοματο χωρις μνημη ΔΕΝ ειναι ικανο να αναγνωρισει το συνολο των αναδρομικως απαριθμησιμων γλωσσων. Να στο πω στα Ελληνικα για να το καταλαβεις;

 

Ναι αλλά στην πράξη...

 

Χα χα χα χα!!!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ενα ντετερμινιστικο πεπερασμενο αυτοματο χωρις μνημη ΔΕΝ ειναι ικανο να αναγνωρισει το συνολο των αναδρομικως απαριθμησιμων γλωσσων. Να στο πω στα Ελληνικα για να το καταλαβεις;

 

Ούτε μία (non-regular, ορίστε) δεν μπορεί να αναγνωρίσει, όχι το σύνολο :P. Όχι ότι ένα κατοζμπρωχνικό αυγόματο μπορεί...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ναι αλλά στην πράξη...

 

Χα χα χα χα!!!

 

Στην πραξη, παραμενεις ονειροπολος πιστευοντας οτι μπορει να τα καταφερεις.

 

---------- Προσθήκη στις 13:01 ---------- Προηγούμενο μήνυμα στις 12:56 ----------

 

Ούτε μία (non-regular, ορίστε) δεν μπορεί να αναγνωρίσει, όχι το σύνολο :P. Όχι ότι ένα κατοζμπρωχνικό αυγόματο μπορεί...

 

Σταματα να τρομπαρεις λημματα, κλεφτη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...