Search code examples
xmlstarlet

XMLSlartlet Grep xml node and replace


how to find blocks of node and replace by custom block using xmlstarlet

Below my xml sample:

<?xml version="1.0" encoding="UTF-8"?>
<job>
    <input>
    <par_denominator nil="true"/>
    <par_follow_source>true</par_follow_source>
    <par_numerator nil="true"/>
    <deblock_enable>Auto</deblock_enable>
    <deblock_strength>0</deblock_strength>
    <no_psi>false</no_psi>
    </input>
 <h264_settings>
    <par_denominator nil="true"/>
    <par_follow_source>true</par_follow_source>
    <par_numerator nil="true"/>
 </h264_settings>
</job>

I'd like to replace all the block contains

    <par_denominator nil="true"/>
    <par_follow_source>true</par_follow_source>
    <par_numerator nil="true"/>

replacement value

    <par_denominator>1</par_denominator>
    <par_follow_source>false</par_follow_source>
    <par_numerator>1</par_numerator>

Solution

  • xmlstarlet solution:

    xmlstarlet ed -u '//*["par_denominator" or "par_numerator"][@nil="true"]' -v 1 \
    -u '//par_follow_source[.="true"]' -v 'false' \
    -d '//*["par_denominator" or "par_numerator"]/@nil' input.xml
    

    The output:

    <?xml version="1.0" encoding="UTF-8"?>
    <job>
      <input>
        <par_denominator>1</par_denominator>
        <par_follow_source>false</par_follow_source>
        <par_numerator>1</par_numerator>
        <deblock_enable>Auto</deblock_enable>
        <deblock_strength>0</deblock_strength>
        <no_psi>false</no_psi>
      </input>
      <h264_settings>
        <par_denominator>1</par_denominator>
        <par_follow_source>false</par_follow_source>
        <par_numerator>1</par_numerator>
      </h264_settings>
    </job>