Search code examples
xmltext-processingxmlstarlet

XML Starlet Delete custom XMl Node


Basically, I have multiple <video_preprocessors> & </video_preprocessors> in my XML. I want to delete the first </video_preprocessors> node and the second <video_preprocessors> node how can I achieve it?

</video_preprocessors>
      <video_preprocessors>
        <timecode_burnin>
          <font_size>16</font_size>
          <position>top_center</position>
          <prefix/>
        </timecode_burnin>

It was located before <timecode_burnin>

Here is the full xml.

https://pastebin.com/sM7saneG

I want to delete </video_preprocessors> <video_preprocessors> before <timecode_burnin>

Thank you very much.


Solution

  • Analyzing your expected output/result I've come up to conclusion that it requires 2 actions:

    1) move timecode_burnin node to the previous sibling node video_preprocessors

    2) delete the "old" video_preprocessors node that initially contained timecode_burnin node

    xmlstarlet ed -m "//video_preprocessors/timecode_burnin" \
    "//video_preprocessors/timecode_burnin/../preceding-sibling::video_preprocessors" \
    -d "//video_preprocessors[timecode_burnin]/following-sibling::video_preprocessors" test.xml
    

    The above command will output the expected result.

    The crucial fragment after processing:

    ...
    <codec>h.264</codec>
          <video_preprocessors>
            <deinterlacer>
              <algorithm>interpolate</algorithm>
              <deinterlace_mode>Deinterlace</deinterlace_mode>
              <force>false</force>
            </deinterlacer>
            <timecode_burnin>
              <font_size>16</font_size>
              <position>top_center</position>
              <prefix/>
            </timecode_burnin>
          </video_preprocessors>
        </video_description>    
    ...
    

    To modify the file inplace - add global -L option :
    xmlstarlet ed -L -m ...