Adding a content

Original file
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    </inner>
    <inner name="third"/>
  </outer>
</root>
Patch fileResult

Default adding

By default, <add> node content is added after the last child of the node specified in the "pos" attribute.
<?xml version="1.0"?>
<changes>
  <change>
    <add sel="//inner[@name='second']">
      <new>1 st</new>
      <new>2 nd</new>
    </add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    <new>1 st</new><new>2 nd</new></inner>
    <inner name="third"/>
  </outer>
</root>

Adding after the last child

If the "pos" attribute of a <add> node is set to "to", the content of the <add> node is added after the last child of the node selected using the "pos" attribute.
<?xml version="1.0"?>
<changes>
  <change>
    <add sel="//inner[@name='second']" 
         pos="to">
      <new>1 st</new>
      <new>2 nd</new>
    </add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    <new>1 st</new><new>2 nd</new></inner>
    <inner name="third"/>
  </outer>
</root>

Adding before the first child

If the "pos" attribute of a <add> node is set to "prepend", the content of the <add> node is inserted before the first child of the node selected using the "pos" attribute.
<?xml version="1.0"?>
<changes>
  <change>
    <add sel="//inner[@name='second']" 
         pos="prepend">
      <new>1 st</new>
      <new>2 nd</new>
    </add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second"><new>1 st</new><new>2 nd</new>
      <leaf/>
    </inner>
    <inner name="third"/>
  </outer>
</root>

Adding after the node

If the "pos" attribute of a <add> node is set to "after", the content of the <add> node is added after the node selected using the "pos" attribute.
<?xml version="1.0"?>
<changes>
  <change>
    <add sel="//inner[@name='second']" 
         pos="after">
      <new>1 st</new>
      <new>2 nd</new>
    </add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    </inner><new>1 st</new><new>2 nd</new>
    <inner name="third"/>
  </outer>
</root>

Adding before the node

If the "pos" attribute of a <add> node is set to "before", the content of the <add> node is added before the node selected using the "pos" attribute.
<?xml version="1.0"?>
<changes>
  <change>
    <add sel="//inner[@name='second']" 
         pos="before">
      <new>1 st</new>
      <new>2 nd</new>
    </add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <new>1 st</new><new>2 nd</new><inner name="second">
      <leaf/>
    </inner>
    <inner name="third"/>
  </outer>
</root>

Adding attribute

Attribute node is added using the "type" attribute of <add> node, which contains @ followed by the new attribute name.
<?xml version="1.0"?>
<changes>
  <change>
    <add sel="//inner[@name='second']" 
         type="@attr">Say "Hallo"</add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second" attr="Say &quot;Hallo&quot;">
      <leaf/>
    </inner>
    <inner name="third"/>
  </outer>
</root>

Adding into multiple locations

Normaly, only one node can match xpath expresion specified in "sel" attribute. If the operation shall be performed on more nodes, "msel" attribute must be used.
<?xml version="1.0"?>
<changes>
  <change>
    <add msel="//inner" 
         pos="before">
      <new>1 st</new>
      <new>2 nd</new>
    </add>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <new>1 st</new><new>2 nd</new><inner name="first"/>
    <new>1 st</new><new>2 nd</new><inner name="second">
      <leaf/>
    </inner>
    <new>1 st</new><new>2 nd</new><inner name="third"/>
  </outer>
</root>

Removing a content

Original file
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    </inner>
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>
Patch fileResult

Remove a node (and all its children)

<?xml version="1.0"?>
<changes>
  <change>
    <remove sel="//inner[@name='second']"/>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>

Remove a node and all surrounding blank nodes

The "ws" attribute can be used to remove also the surrounding blank nodes. Possible values for that attribute are "both" to remove all surrounding blank nodes, "before" to remove preceding blank node or "after" to remove following blank node.
<?xml version="1.0"?>
<changes>
  <change>
    <remove sel="//inner[@name='second']" ws="both"/>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/><inner name="third">
      Some text
    </inner>
  </outer>
</root>

Remove a node and preceding blank node

To maintain indentation, it is sufficient to remove blank node at only one side of removed node.
<?xml version="1.0"?>
<changes>
  <change>
    <remove sel="//inner[@name='second']" ws="before"/>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>

Remove a text node

<?xml version="1.0"?>
<changes>
  <change>
    <remove sel="//inner[@name='third']/text()"/>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    </inner>
    <inner name="third"/>
  </outer>
</root>

Remove an attribute

<?xml version="1.0"?>
<changes>
  <change>
    <remove sel="//inner[@name='second']/@name"/>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner>
      <leaf/>
    </inner>
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>

Removing all children of node

To remove more then one node, "msel" attribute must be used instead of "sel". Note that expresion "//outer/*" will not work, as it does not remove the text nodes containing white characters used for indentation.
<?xml version="1.0"?>
<changes>
  <change>
    <remove msel="//outer/node()"/>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer/>
</root>

Replacing a content

Original file
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    </inner>
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>
Patch fileResult

Replacing a node

Replace one node with another
<?xml version="1.0"?>
<changes>
  <change>
    <replace sel="//inner[@name='second']">
      <new>1 st</new>
    </replace>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <new>1 st</new>
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>

Replacing a text node

Replace text node with another. Note that whitespaces are preserved, so if the output shall be alligned, there must be the right number of whitespaces.
<?xml version="1.0"?>
<changes>
  <change>
    <replace sel="//inner[@name='third']/text()">
      Other text
    </replace>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="first"/>
    <inner name="second">
      <leaf/>
    </inner>
    <inner name="third">
      Other text
    </inner>
  </outer>
</root>

Replacing an attribute value

Change value of attribute. Note how the replace node is split on two lines to maintain indentation and don't polute the attribute value with unwanted spaces.
<?xml version="1.0"?>
<changes>
  <change>
    <replace sel="//inner[@name='first']/@name"
    >realy first</replace>
  </change>
</changes>
<?xml version="1.0"?>
<root>
  <outer>
    <inner name="realy first"/>
    <inner name="second">
      <leaf/>
    </inner>
    <inner name="third">
      Some text
    </inner>
  </outer>
</root>