Today I get to learn how to use xmllint properly. It does not seem to be well covered or explained. I plan to use a single language resource file to run my entire system.
I had the same problem a few minutes ago and saw this post.
After hacking a bit I found the following solution to extract the city:
(
wget 'http://maps.googleapis.com/maps/api/geocode/xml?latlng=53.244921,-2.479539&sensor=true' \
-O dummy.xml -o /dev/null
xmllint --format \
--xpath '/GeocodeResponse/result[type = "postal_town"]/address_component[type = "postal_town"]/short_name/node()' \
dummy.xml
)
You nee to specify the correct X-Path to get the desired XML-Tag and then return only the node value.
My favorite is xmlstarlet because it seems to be more powerful than xmllint:
xmlstarlet sel -t -v '/resources/item[@id="index.php"]/description/text()' en.xml
how best to target a specific and then drill down to its child element
The correct XPath expression to do this is:
/resources/item[@id="index.php"]/description/text()
In plain English: Start from the document node, to the document element resources
, on to its child item
, but only if the value of the id
attribute is "index.php", on to its child description
and retrieve its textual value.
I use xmllint to validate XML documents, but never for path expressions. In a bash shell (at least with Mac OS) there is an even simpler tool for evaluating XPath expressions, called "xpath":
$ xpath en.xml '/resources/item[@id="index.php"]/description/text()'
Then, the following result is obtained:
Found 1 nodes:
-- NODE --
DESCRIPTION
If you still prefer xmllint, use it in the following way:
$ xmllint --xpath '/resources/item[@id="index.php"]/description/text()' en.xml > result.txt
By default, --xpath
implies --noout
, which prevents xmllint from outputting the input XML file. To make the output more readable, I redirect the output to a file.
$ cat result.txt
DESCRIPTION