With XMLStarlet, you can add a subnode to an element, or you can update an existing element. To cover both the case when the element exists and when it doesn't already exist, we can
- Delete the element.
- Add the element with the value that we want it to have.
Let's say the element that we want to add is <newtag>
and that its value should be tagval
. It should also have an attribute, newattr
, with value attrval
. This means that what we want to add is
<newtag newattr="attrval">tagval</newtag>
To delete the element:
$ xmlstarlet ed -d '//server-group/newtag' file.xml
To add the element with an attribute:
$ xmlstarlet ed -s '//server-group' -t elem -n 'newtag' -v 'tagval' \ -s '//server-group/newtag' -t attr -n 'newattr' -v 'attrval' file.xml
Adding these together:
$ xmlstarlet ed -d '//server-group/newtag' \ -s '//server-group' -t elem -n 'newtag' -v 'tagval' \ -s '//server-group/newtag' -t attr -n 'newattr' -v 'attrval' file.xml
Given the input XML
<?xml version="1.0"?> <server-groups> <server-group name="main-server-group" profile="full"> <jvm name="default"> <heap size="64m" max-size="512m"/> <jvm-options> <option value="somevalue"/> </jvm-options> </jvm> <socket-binding-group ref="full-sockets"/> </server-group> </server-groups>
this results in the output
<?xml version="1.0"?> <server-groups> <server-group name="main-server-group" profile="full"> <jvm name="default"> <heap size="64m" max-size="512m"/> <jvm-options> <option value="somevalue"/> </jvm-options> </jvm> <socket-binding-group ref="full-sockets"/> <newtag newattr="attrval">tagval</newtag> </server-group> </server-groups>
Note that the XPath expression //server-group
will match allserver_group
elements in the input XML. If you only want to match the one whose name
attribute is main-server-group
, you would have to change //server-group
to //server-group[@name="main-server-group"]
.
XMLStarlet is available from http://xmlstar.sourceforge.net/, but there's most likely a pre-packaged version available for your Unix already (use that). Sometimes, the XMLStarlet executable is called just xml
rather than xmlstarlet
.