Search code examples
regexxmlbashxmlstarlet

Searching and replacing a block of XML formatted text in Bash


I have been trying to figure out how to search a block of XML formatted text and modify it in Bash. The file I want to process is a simulation file with XML fomatting. Assume that the file contains multiple blocks of XML stataments as:

<mote>
  <breakpoints />
  <interface_config>
    org.contikios.cooja.interfaces.Position
    <x>0.0</x>
    <y>75.0</y>
    <z>0.0</z>
  </interface_config>
  <interface_config>
    org.contikios.cooja.mspmote.interfaces.MspClock
    <deviation>1.0</deviation>
  </interface_config>
  <interface_config>
    org.contikios.cooja.mspmote.interfaces.MspMoteID
    <id>4</id>
  </interface_config>
  <motetype_identifier>sky2</motetype_identifier>
</mote>

What I want to search is a block of XML statements here:

<id>4</id>
  </interface_config>
  <motetype_identifier>sky2</motetype_identifier>

And replace it with

<id>4</id>
  </interface_config>
  <motetype_identifier>sky3</motetype_identifier>

Rest of the XML statements before and after these statements will remain unchanged. This will enable me to change the mote type Node 4 from sky2 to sky3 in a script in Bash.


Solution

  • xmlstarlet ed --omit-decl -u "//mote[interface_config/id='4']/motetype_identifier" -v 'sky3' file.xml
    

    Output:

    <mote>
      <breakpoints/>
      <interface_config>
        org.contikios.cooja.interfaces.Position
        <x>0.0</x>
        <y>75.0</y>
        <z>0.0</z>
      </interface_config>
      <interface_config>
        org.contikios.cooja.mspmote.interfaces.MspClock
        <deviation>1.0</deviation>
      </interface_config>
      <interface_config>
        org.contikios.cooja.mspmote.interfaces.MspMoteID
        <id>4</id>
      </interface_config>
      <motetype_identifier>sky3</motetype_identifier>
    </mote>
    

    If you want to edit file.xml inplace, add option -L.

    See: xmlstarlet ed --help