Search code examples
xmlbashxmlstarlet

Updating value of xml tag through script


I need to update the value of following xml tag through shell script.

<sample>4</sample>

I have tried with below, but it doesnt work..

sed -i '' 's/\(<[^"]*"sample">\)\([^<]*\)\(<[^>]*\)/\1"$sampleVal"\3/g' $CONFIG_FILE

Any idea what is missing?

Update with complete xml nodes:

<?xml version="1.0" encoding="ISO-8859-1"?>
     <Server>
     <userInput>
            <sample>0</sample>
            <A>
            <a1>9999</a1>
            <a2>11111</a2>
           </A>
           <B>
            <b1>10389</b1>
            <b2>8000</b2>
           </B>

         <C>10500</C>
         </userInput>
      </Server>

Update with namespace:

<?xml version="1.0" encoding="ISO-8859-1"?>
     <Server xmlns="http://a/b/c/sample.com">
     <userInput>
            <sample>0</sample>
            <A>
            <a1>9999</a1>
            <a2>11111</a2>
           </A>
           <B>
            <b1>10389</b1>
            <b2>8000</b2>
           </B>

         <C>10500</C>
         </userInput>
      </Server>

Solution

  • With xmlstarlet:

    xmlstarlet ed -u '/Server/userInput/sample/text()' -v "100" file.xml
    

    Output:

    <?xml version="1.0"?>
    <Server>
      <userInput>
        <sample>100</sample>
        <A>
          <a1>9999</a1>
          <a2>11111</a2>
        </A>
        <B>
          <b1>10389</b1>
          <b2>8000</b2>
        </B>
        <C>10500</C>
      </userInput>
    </Server>
    

    If you want to edit your file "in place" add option -L:

    xmlstarlet ed -L -u '/Server/userInput/sample/text()' -v "100" file.xml
    

    If you want to omit XML declaration (<?xml ...?>) add option -O:

    xmlstarlet ed -O -u '/Server/userInput/sample/text()' -v "100" file.xml
    

    Output:

    <Server>
      <userInput>
        <sample>100</sample>
        <A>
          <a1>9999</a1>
          <a2>11111</a2>
        </A>
        <B>
          <b1>10389</b1>
          <b2>8000</b2>
        </B>
        <C>10500</C>
      </userInput>
    </Server>