How can I get xmllint to output multiple results of xpath selector for attributes "per line"?
Take this example:
<?xml version="1.0" encoding="ISO-8859-1"?>
<config>
<tagX key1="value1 " key2=" value2"/>
<tagY key3="value3" key4=" value4 "/>
</config>
$ xmllint example.xml --xpath "/config/*/@*"
The result is:
key1="value1 " key2=" value2" key3="value3" key4=" value4 "
What I'd like to get is:
key1="value1 "
key2=" value2"
key3="value3"
key4=" value4 "
Would I need to split after even-numbered quote marks, or is there any neater way to do this?
There's a related question, about the same subject except it's about picking out contents of <tag>value</tag>
, and not <tag attribute="value" />
You can try:
$ xmllint --shell inputfile <<< `echo 'cat /config/*/@*'`
You might need to grep
the output, though, so as to filter the undesired lines.
If it's an option, try using xmlstarlet instead:
xmlstarlet sel -t -v "/config/*/@*" example.xml
The question is old but as I came to this post searching a solution to the same problem, here is my solution
On linux add sed substitution to split output:
$ xmllint example.xml --xpath "/config/*/@*" | sed "s| key|\nkey|g"
of course the substitution expression depends on your xml structure and your xpath query.
And you can even add line numbers on each line if you add nl
$ xmllint example.xml --xpath "/config/*/@*" | sed "s| key|\nkey|g" | nl
Which gives
1 key1="value1 "
2 key2=" value2"
3 key3="value3"
4 key4=" value4 "
I found that Ubuntu v.14 and v.18 use too old libxml2 versions.
So i solved the issue mentioned in the topic by the recompiling of libxml2 v2.9.10.
1) Download the sources of libxml2 from http://linuxfromscratch.org/blfs/view/cvs/general/libxml2.html
2) Download the test suite:
$ wget http://www.w3.org/XML/Test/xmlts20130923.tar.gz
3) Execute:
$ tar xf libxml2-2.9.10.tar.gz
4) Execute:
$ cd libxml2-2.9.10/
5) Execute:
$ sed -i 's/test.test/#&/' python/tests/tstLastError.py
6) Execute:
$ export CPATH="/usr/include/python3.6/:$CPATH"
7) Execute:
$ sudo apt-get install -y python3-libxml2 python3-pip
8) Execute:
$ sudo pip3 install libxml2dom
9) Execute:
$ ./configure --prefix=/usr --disable-static --with-history --with-python=/usr/bin/python3 && make
Ensure here that the returning code ($?) is 0.
10) Execute:
$ tar xf ../xmlts20130923.tar.gz
11) Execute:
make check > check.log
Ensure here that the returning code ($?) is 0.
12) Execute:
$ sudo make install
Enjoy
$ xmllint data.xml -xpath "//some_child/ancestor::some_parent/attribute::id"
id="1"
id="10010"
id="10011"
id="10020"
id="10021"
If using the latest xmllint, results should have been separated by \n
now. However, if fields contain \n
, you can use this patched version to use \0
as a separator, with --xpath0
. For whatever reason the PR hasn't been merged yet.