Although we usually like to enforce strict rules on our data, sometimes we just like to loosen it up a little. Don't get me wrong, namespaces definitely have a place and we use them to enforce contracts on our data. But sometimes, we don't need (and thus, want) that layer of complexity.
It took me a while to understand why it isn't possible to just unset the namespace for an XML node. Since a namespace is an integral part of a node's qualified name, node A with namespace XYZ is really a different entity than node A with namespace ABC. Thus, we need to rename the node. The Document
(org.w3c.dom.Document
) class conveniently provides a method renameNode(Node n, String namespaceURI, String qualifiedName)
. Supplying null
as namespaceURI
effectively removes the namespace for the node. You'll probably want to apply the change to your entire subtree, so it should be recursive:
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
...
/**
* Recursively renames the namespace of a node.
* @param node the starting node.
* @param namespace the new namespace. Supplying <tt>null</tt> removes the namespace.
*/
publicstatic void renameNamespaceRecursive(Node node, String namespace) {
Document document = node.getOwnerDocument();
if (node.getNodeType() == Node.ELEMENT_NODE) {
document.renameNode(node, namespace, node.getNodeName());
}
NodeList list = node.getChildNodes();
for(int i = 0; i < list.getLength(); ++i) {
renameNamespaceRecursive(list.item(i), namespace);
}
Recently I read about the Rule of Three, which led me to believe I should share this solution. Here are the three problems I solved using it: