Namespace awareness of XML actions in install4j
This post explains an exceptional backward-incompatibility in the install4j 10.0.9 release. This was necessary due to a change in install4j 10.0.8 that was intended to fix the corruption of namespaced XML documents by modifying XML actions.
install4j provides a number of actions that work with XML files, like reading values, inserting fragments or removing nodes.
Most of these actions require that you enter an XPath expression to select the parts of the document to operate on. In versions prior to install4j 10.0.9, the XML parser used by the actions was not namespace-aware, so the XPath expressions did not require any namespaces.
This typically works well for reading values from an XML file, and it continues to be the default for install4j 10.0.9+, where the "XPath expression" property now has a new "Namespace-aware" child property that is initially deselected.
However, when modifying XML documents, the XML file needs to be written again, and using a non-namespace-aware XML parser means that the namespaces would be lost. To fix this problem, we turned on namespace-awareness for all XML actions in install4j 10.0.8. However, this meant that there was no way of specifying XPath expressions that matched namespaced elements anymore.
This is why the "XPath expression" property of all modifying XML actions has an "XML namespaces" child property since install4j 10.0.9.
Here you can specify namespaces and their prefixes in a separate dialog and then use the namespace prefixes in your XPath expression.
If you used XML documents without namespaces, no changes are required if you have configured XML actions in earlier versions of install4j. While the "Read value from XML file" and the "Count nodes in XML file" actions continue to work with namespaced elements as before, the following actions require changes to the XPath expression if they match namespaced elements with their "XPath expression" properties:
- "Insert XML fragment into XML files" action
- "Remove nodes from XML files" action
- "Replace text in XML files" action
Each node test in the XPath expression that required a qualified name (QName) must now include the appropriate namespace prefix that matches an entry in the "XML namespaces" child property. For example, in the XML document
<?xml version="1.0" encoding="utf-8" ?> <config xmlns="http://mycorp/cluster" xmlns:ext="http://mycorp/server"> <cluster> <ext:server name="production" port="8000"/> <ext:server name="staging" port="7000"/> </cluster> </config>
the non-namespaced XPath expression to match the server port of the production server is
//cluster/server[name='production']/@port
For the modifying XML actions, this XPath has to be changed to
/c:cluster/ext:server[name='production']/@port
with the namespace definitions
c=http://mycorp/cluster ext:http://mycorp/server
in the "XML namespaces" child property.
While the "cluster" element in the source document is not written with a prefix, it is in a default namespace that must be specified just like the explicit namespaces to ensure the XPath expression matches it correctly.