Search code examples
xmlbashxmlstarlet

xpath expression for updating xml in bash


I have written a deploy script which uses a third-party software.

It installs a file .plist file in XML format.

But to run the software, I need to update a XML node in the file.

From

<plist>
  <dic>
    <key>dynamic_ipaddress</key>
    <array>
    </array>
  </dict>
</plist>

to

<key>dynamic_ipaddress</key>
<array>
      <string>127.0.5.1</string>
</array>

I tried

xmlstarlet ed -L -u "//plist/dict/[key='dynamic_ipaddress']/array/string" -v 'xxxxxx' file.xml

It does not work. Fails with Invalid expression.

What would be the correct xpath expression?


Solution

  • You actually want to update the xpath to "array", adding a subnode. I've augmented your example file to demonstrate:

    $ cat file.xml
    <plist>
      <dict>
        <key>dynamic_ipaddress</key>
        <array>
        </array>
      </dict>
      <dict>
        <key>something else</key>
        <array><number>42</number></array>
      </dict>
    </plist>
    
    $ xmlstarlet ed -s '/plist/dict[key="dynamic_ipaddress"]/array' -t elem -n string -v foo file.xml
    <?xml version="1.0"?>
    <plist>
      <dict>
        <key>dynamic_ipaddress</key>
        <array>
        <string>foo</string></array>
      </dict>
      <dict>
        <key>something else</key>
        <array>
          <number>42</number>
        </array>
      </dict>
    </plist>