On the bash shell prompt i want to run xmllint to get data from a xml file. Lets look at a file in which i have no issues:
behold the fruits.xml file:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="mykey">grapes</string>
</map>
and this is me using xmllint to get the value "grapes" from fruits.xml
xmllint --xpath "string(/map/string[@name = 'mykey'])" fruits.xml
and i get the output of the following:
$ grapes
great i got the value, but this is not the actual key i need to use. "mykey" should be "c1:fruits_id-%1$s"
now when i change the "mykey" value in the fruits.xml file to another value i am unable to get any return value from xmllint:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="c1:fruits_id-%1$s">grapes</string>
</map>
xmllint --xpath "string(/map/string[@name = 'c1:fruits_id-%1$s'])" fruits.xml
the above command returns nothing. All im doing is changing the key name and now it wont work. can someone help ?
(The XML document you show does not have the c1:
in front of the attribute value - a typo, I guess?)
If you use $
in a shell command, it is interpreted as a variable and variable interpolation kicks in. Because the variable does not exist, it is replaced with nothing. You can test this by changing your XML document to
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="c1:fruits_id-%1">grapes</string>
</map>
The only change is that the two characters $s
are deleted. Now the path expression finds the string:
$ xmllint --xpath "string(/map/string[@name = 'c1:fruits_id-%1$s'])" fruit.xml
grapes
Either escape the character as \$
as Biffen has already suggested:
$ xmllint --xpath "string(/map/string[@name = 'c1:fruits_id-%1\$s'])" fruit.xml
grapes
or, equally easy, swap the quotes:
$ xmllint --xpath 'string(/map/string[@name = "c1:fruits_id-%1$s"])' fruit.xml
grapes
There is no variable interpolation for strings that are delimited by single quotes, even if there are double quotes inside them (see this question).