views:

347

answers:

4

I want to get an attribute out of a XML-Tree. Therefor I use the command xpath from package libxml-xpath-perl. I figured out this command:

virsh dumpxml save | xpath -e "/domain/devices/disk[@type='file']/source/@file[1]"

This gives me

 file="/var/lib/libvirt/images/save.raw"

How can I select the value only? (/var/lib/libvirt/images/save.raw)

Thanks

falstaff

A: 

You want to separate the string based on the =, so use split (perldoc -f split):

my ($attr, $value) = split /=/, 'file="/var/lib/libvirt/images/save.raw"';

However, instead of parsing these values literally, you should use the many libraries of XML parsers, such as XML::XPath.

Ether
Its the workaround I use now in my bashscript, splitting it litterally by using cut -d = -f 2, but i want to use the xpath function for it, something like $ virsh dumpxml save 2>/dev/null | xpath -e "value(/domain/devices/disk[@type='file']/source/@file[1])"...
falstaff
A: 
/domain/devices/disk[@type='file']/source/@file[1]/text()
Tomalak
This gives me:$ virsh dumpxml save 2>/dev/null | xpath -e "/domain/devices/disk[@type='file']/source/@file[1]/text()"No nodes found in stdin
falstaff
Hm, obviously naked text nodes cannot be processed/displayed. It was just a guess on my part, admittedly.
Tomalak
A: 

I think returning only the value is normal behaviour. Maybe it is a bug? I tried /text() like Tomalak suggested and it returns nothing (at least with this tool).
You could now pipe the output in another command like sed to get the desired result:

... | sed -r 's/.*?"(.*)"/\1/'

Edit:
Apparently the perl script uses XML::XPath and uses only find for the query which returns a NodeSet object. But there also is findvalue which the script doesn't use. Maybe you could fiddle around a little with the script. Only replacing find with findvalue gives just the value on stdout, but also error messages on stderr.
Doc for the library: http://search.cpan.org/~msergeant/XML-XPath-1.13/XPath.pm

andre-r
Yeah its somewhat like I use now... I just would like to do it in the xpath way... cut -d = -f 2
falstaff
+1  A: 

I use (maybe because I wrote it ;--) xml_grep2, from App::xml_grep2, which has a convenient -t option that returns the text value of the result:

virsh dumpxml save | xml_grep2 -t "/domain/devices/disk[@type='file']/source/@file[1]"

should work

mirod