Replace dynamic content in XML file Replace dynamic content in XML file xml xml

Replace dynamic content in XML file


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


The XML way is cool, but if you need to use normal bash tools, you can modify a line using sed. For instance:

PRICE=123sed -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.


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 elementmyParamElement=$(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>