Replace dynamic content in XML file
Solution 1:
You can use xmlstarlet
to edit a XML
file in a shell
like this :
xmlstarlet edit -L -u "/scs-shop/price[@type='double']" -v '99.66' file.xml
NOTE
-
"/scs-shop/price[@type='double']"
is a Xpath expression - see
xmlstarlet ed --help
Solution 2:
The XML way is cool, but if you need to use normal bash tools, you can modify a line using sed. For instance:
PRICE=123
sed -i "s/\(<price.*>\)[^<>]*\(<\/price.*\)/\1$PRICE\2/" $XML_FILE_TO_MODIFY
This will replace the price with 123.
That sed command seems daunting, so let me break it down:
\(<price.*>\)[^<>]*\(<\/price.*\)
is the pattern to match. \(
... \)
are parenthesis for grouping. <price.*>
matches the opening price tag. [^<>]*
matches anything except angle brackets, and in this case will match the contents of the price tag. <\/price.*
matches the end of the price tag. Forward slash is a delimiter in sed, so I escape it with a back slash.
\1$PRICE\2
is the text to replace the matched text with. \1
refers to the first matched parenthesis group, which is the opening price tag. $PRICE
is the variable with the desired price in it. \2
refers to the second parenthesis group, in this case the closing tag.
Solution 3:
I did not have the luxury of having xmlstarlet. I found a solution though simply by doing an inline replacement;
template-parameter.xml
<ns:Parameter>
<ns:Name required="true">##-ParamName-##</ns:Name>
<ns:Value>
<ns:Text>##-ParamValue-##</ns:Text>
</ns:Value>
</ns:Parameter>
Snippet
tokenName="foo"
tokenValue="bar"
#Replace placeholders in parameter template element
myParamElement=$(cat template-parameter.xml)
myParamElement=${myParamElement//##-ParamName-##/$tokenName}
myParamElement=${myParamElement//##-ParamValue-##/$tokenValue}
Result
<ns:Parameter>
<ns:Name required="true">foo</ns:Name>
<ns:Value>
<ns:Text>bar</ns:Text>
</ns:Value>
</ns:Parameter>