Overview
We get a lot of forum questions about the use of the Update XML with Xpath step of the File Utils plugin, so I figured I’d post some examples to help people along. It’s a very useful step because it can update XML files on the fly, which is great for changing configurations on a deployment.
To use this step, make sure you’ve got the File Utils automation plugin installed. You can use this step in any component process or generic process.
To use this step, you’ll need a basic knowledge of XPath, which is how you specify where to add, remove, or change the XML code. There are lots of resources out there for learning XPath, but here’s a good one: http://www.w3schools.com/xpath/
For full details on the File Utils plugin and the Update XML with XPath step, see its documentation page. In short, this step has several fields in which you can specify changes to XML files:
- Insert XML
- This field adds XML nodes to the document. You specify one or more XPath expression -> content pairs, separated by newlines. The XPath expression points to the parent node, and the content is inserted under that node.
- Remove
- This field removes elements or attributes to remove. You specify one or more XPath expressions and the step removes the matching elements.
- Replace with text
- This field replaces the content of text nodes or attributes with new text. You specify one or more XPath expression -> content pairs, separated by newlines. The XPath expression points to the parent node or attribute, and the content is inserted in that node or attribute.
- Set Attributes
- This field updates the attributes that you specify, similar to the Replace with text field. You specify one or more expression -> content pairs, separated by newlines. The XPath expression points to one or more attributes, and the content becomes the new value of that attribute.
Here’s a picture of the step properties, which include each of the above fields. To use it, open a component process or generic process and drag the Update XML with Xpath step to the process.

Use cases
Here are some common use cases of the step. I’ll use the following example XML file in these use cases:
<?xml version="1.0" encoding="UTF-8"?>
<testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
<data att1="one" att2="two" name="attributes" value="something"/>
</myData>
</testFile>
Use case 1: Inserting XML nodes
To insert XML nodes, specify the parent of the new node with XPath code. For example, to add a new <data> node next to the existing nodes, I specify the parent of the <data> nodes. The Insert XML field of the Update XML File with XPath step looks like this:
//testFile/myData-><data name="myNewData"/>
The updated file has the new <data> node:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
<data att1="one" att2="two" name="attributes" value="something"/>
<data name="myNewData"/>
</myData>
</testFile>
The step can also accept more complicated XPath expressions. For example, you can use an XPath predicate to specify a node with a certain attribute. The following code inserts a node under the <data> node that has the attribute name="filePath"
:
//testFile/myData/data[@name='filePath']-><info/>
The resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory">
<info/>
</data>
<data name="textData">Here is some text.</data>
<data att1="one" att2="two" name="attributes" value="something"/>
</myData>
</testFile>
Use case 2: Changing an attribute value
The Set Attributes field of the step lets you change an attribute. All you have to do is point to the attribute with an XPath expression and provide the new value. For example, the following code changes the value of an attribute on a <data> node.
//testFile/myData/data[@name='filePath']/@value->/home/user1
The resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="/home/user1"/>
<data name="textData">Here is some text.</data>
<data att1="one" att2="two" name="attributes" value="something"/>
</myData>
</testFile>
XPath expressions can target multiple places in the XML code. For example, the following code selects the <data> nodes that have a value attribute and changes both of those attributes:
//testFile/myData/data[@value]/@value->newValue
The resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="newValue"/>
<data name="textData">Here is some text.</data>
<data att1="one" att2="two" name="attributes" value="newValue"/>
</myData>
</testFile>
Use case 3: Changing a text node
Accessing text nodes (that is, the text that’s inside the content of a node) is a little different than accessing an attribute. Here’s an example of code to change the content of a text node, which goes in the Replace with text field of the step:
//testFile/myData/data[@name='textData']/text()->Some new text content.
The resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Some new text content.</data>
<data att1="one" att2="two" name="attributes" value="something"/>
</myData>
</testFile>
Use case 4: Changing attributes
Changing attributes is straightforward. In the Set Attributes field, specify an XPath expression that points to one or more attributes and then provide the content for the attributes. For example:
//testFile/myData/data[@att1='one']/@att2->NewAttributeValue
The resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
<data att1="one" att2="NewAttributeValue" name="attributes" value="something"/>
</myData>
</testFile>
Use case 5: Removing XML nodes
To remove XML content, specify an XPath expression in the Remove field. Here’s a simple example that deletes one node:
//testFile/myData/data[@value='something']
The resulting XML looks like this:
<?xml version="1.0" encoding="UTF-8"?><testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
</myData>
</testFile>
You can also remove attributes; just specify an attribute with the XPath expression, as in the following example:
//testFile/myData/data[@name='filePath']/@value
Common problems
1. Using quotes in the update content.
You don’t need to enclose your new content in quotes.
Wrong:
//testFile/myData/data[@value]/@value->"newValue"
Correct:
//testFile/myData/data[@value]/@value->newValue
2. Specifying the wrong location for the file.
If the file doesn’t change, be sure that you’ve got the right path to the file and the correct file name in the step. You can also select the Fail if no match found check box to prevent this problem.
Known issues
1. Namespaces without prefixes (internal work item jazz02:134075)
If your XML document has a default namespace (that is, a namespace that is specified without a prefix), the step won’t work.
For example, XPath expressions won’t work on the following document because its namespace does not have a prefix:
<?xml version="1.0" encoding="UTF-8"?>
<testFile xmlns="http://example.com/mynamespace">
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
<data name="attributes" att1="one" att2="two" value="something"/>
</myData>
</testFile>
There are two possible workarounds for this issue:
First, you can assign a prefix to the namespace, as in the following example. Then, the step can process the XML data as usual, with no change in your XPath expressions.
<?xml version="1.0" encoding="UTF-8"?>
<testFile xmlns:mynamespace="http://example.com/mynamespace">
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
<data name="attributes" att1="one" att2="two" value="something"/>
</myData>
</testFile>
If you don’t want to edit the XML file, another workaround (that does not require changing the XML file) is to use the local-name() function. With this technique, you replace the node names with a function that returns the name of the node without respect to its namespace. For example, the following code deletes a node:
//*[local-name()='testFile']/*[local-name()='myData']/*[local-name()='data' and @name='attributes']
The resulting XML code looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<testFile xmlns:mynamespace="http://example.com/mynamespace">
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
</myData>
</testFile>
2. Inserting text nodes (internal work item jazz02:129806)
The Update XML with XPath step fails to add a text node if the node does not have one already. For example, the first <data> node in the following code does not have a text node like the second <data> node does:
<?xml version="1.0" encoding="UTF-8"?>
<testFile>
<myData>
<data name="filePath" value="/opt/sampleDirectory"/>
<data name="textData">Here is some text.</data>
<data att1="one" att2="two" name="attributes" value="something"/>
</myData>
</testFile>
If you use the following code in the Insert XML or Replace with text field, the step can’t add the text because there is no text node there currently.
Wrong:
//testFile/myData/data[@name='filePath']/text()->New text
As a workaround, add text as a child of the node and the step adds the text node automatically:
Correct:
//testFile/myData/data[@name='filePath']->New text
3. Resolving and removing DTDs
If your XML file has a doctype declaration, the step tries to retrieve the DTD and validate the XML file before it makes any changes. If the step can’t find that DTD, the step fails.
For example, the following XML file has a doctype declaration at the top:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
"http://java.sun.com/dtd/application_1_3.dtd">
<application>
<module>
<web>
<web-uri>myapp.war</web-uri>
<context-root>myapplication</context-root>
</web>
</module>
</application>
In this case, the agent that is running the step must be able to access the DTD at http://java.sun.com/dtd/application_1_3.dtd; otherwise the step fails.
Also note that DTD declarations like the one in the previous example are removed from the output of this step.
Testing with generic processes
When I’m working on processes that contain this step, I always test out the XML editing with a generic process first; it’s usually easier to test and debug my XML editing there than in a component process. My test process looks like this:
- Delete the edited copy of the XML file. I always leave my original XML file untouched and edit a copy, so I can compare with the original. (Make sure to make this step succeed whether it finds the edited copy of the file or not, or else it will fail the process if it can’t find the new file.)
- Make a copy of the XML file. By default, the Update XML with XPath step edits the file in place, so I like to make a copy for testing purposes.
- Edit the XML file with the Update XML with XPath step. Here’s where the process does the real work.
I hope that’s useful information. If you’ve got other questions, post them to the UrbanCode questions forum and I or someone else will try to help.