Search code examples
xmlshellxsdxml-parsingxmlstarlet

Searching for XML tag by value between them and inserting a new tag in shell script


Say I have this test.xml file which has these contents

<d>
  <p>
    <n>hi</n>
    <r>
      <s>1.0</s>
    </r>
  </p>

  <p>
    <n>hello</n>
    <r>
      <s>1.0</s>
    </r>
  </p>
</d>

I want to add a new <s>2.0</s> for "hello" object as shown below.

<d>
  <p>
    <n>hi</n>
    <r>
      <s>1.0</s>
    </r>
  </p>

  <p>
    <n>hello</n>
    <r>
      <s>1.0</s>
      <s>2.0</s>
    </r>
  </p>
</d>

I have to do this using shell script. There is a way of searching through the XML DOM and adding tags using xmlstarlet given here http://www.technomancy.org/xml/add-a-subnode-command-line-xmlstarlet/ . But this only describes adding new tag to certain nodes based on attribute value. I do not have any attributes. How can I do it ? Is there any way of doing it using grep ?


Solution

  • xmlstarlet ed -a '//p[n="hello"]/r/s' -t elem -n s -v 2.0 input.xml
    

    Explanation:

    • ed ==> edit
    • -a ==> append
    • -t ==> type
    • -n ==> name
    • -v ==> value