Search code examples
xmlstarlet

xmlstarlet to insert tags


I am using the command:

xmlstarlet ed --omit-decl --subnode "/boinc" --type elem -n app -v "" project_00.xml > project_01.xml

However, I would like to insert two more tags into that one:

<app>
 <name>name</name>
 <nikname>nikname</nikname>
</app>

In my project_00.xml, I already have others tag app and it is causing conflicts.

The problem with this command:

xmlstarlet ed --subnode "/boinc" --type elem -n app -v "" project_00.xml|     xmlstarlet ed --subnode //app --type elem -n name -v "newApp"| xmlstarlet ed --subnode //app --type elem -n user_friendly_name -v "New.App" > project_01.xml

is that it created this.:

  <app name="wilson">
    <name>wilson</name>
    <user_friendly_name>Mr.Wilson</user_friendly_name>
    <name>newApp</name>
    <user_friendly_name>New.App</user_friendly_name>
  </app>
  <app>
    <name>newApp</name>
    <user_friendly_name>New.App</user_friendly_name>
  </app>

Does know the exactly command?

I tried this command but it replicated the to all app tags

xmlstarlet ed -s "/boinc" -t elem -n app -v "" -s "/boinc/app" -t elem -n name -v "name" -s "/boinc/app" -t elem -n user_friendly_name -v "New.App" project_00.xml > project_01.xml

Solution

  • Basically, you need an XPath expression to match the node you just inserted; since --subnode always puts new children in last place you can use /boinc/app[last()]:

    xmlstarlet ed \
      --subnode /boinc --type elem -n app -v '' \
      --subnode '/boinc/app[last()]' --type elem -n name -v newApp \
      --subnode '/boinc/app[last()]' --type elem -n user_friendly_name -v New.App \
      project_00.xml > project_01.xml