I have the following xml excerpt and what I want is just the string 2014.4.0.0008 in the Version tag.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExternalMetadataPack xmlns="xmlns://www.fortifysoftware.com/schema/externalMetadata" schemaVersion="1.0">
<PackInfo>
<Name>Main External List Mappings</Name>
<PackID>main-external-mappings</PackID>
<Version>2014.4.0.0008</Version>
</PackInfo>
</ExternalMetadataPack>
I've tried a few things and gotten as far as this:
xmllint --xpath "//PackInfo/@Version[local-name()='ExternalMetadataPack']" externalmetadata.xml
But nothing seems to be working. This says that the XPath set is empty and if I include string() in the --xpath parameter then it just doesn't return anything.
Try this (ignoring the NS) :
xmllint --xpath '//*[local-name()="Version"]/text()' file.xml
AFAIK, it's not possible to set a default NS with the --xpath switch, so with the --shell one :
$ xmllint --shell file.xml <<EOF
setns x=xmlns://www.fortifysoftware.com/schema/externalMetadata
cat //x:Version/text()
EOF
/ > setns x=xmlns://www.fortifysoftware.com/schema/externalMetadata
/ > cat //x:Version/text()
-------
2014.4.0.0008
/ >
But sadly, there's rubbish in the output, so :
$ xmllint --shell file.xml <<EOF | grep -Ev '^(/ *>| --+)'
setns x=xmlns://www.fortifysoftware.com/schema/externalMetadata
cat //x:Version/text()
EOF
2014.4.0.0008
Another way :
xmllint --xpath '//*[namespace-uri()="xmlns://www.fortifysoftware.com/schema/externalMetadata" and local-name()="Version"]/text()' file.xml
Finally xmlstarlet is quite more advanced and it seems the proper tool here :
xml sel -N x="xmlns://www.fortifysoftware.com/schema/externalMetadata" -t -m "//x:Version/text()" -c . -n file.xml
And bonus (avaibility to use XPath 3) saxon-lint
saxon-lint --xpath 'declare default element namespace "xmlns://www.fortifysoftware.com/schema/externalMetadata";//Version/text()' file.xml