Alex Rivera | Logout

Java+DOM: How do I set the base namespace of an (already created) Document?

Asked 2009-09-29T13:11:11.627
22

I am dealing with an already created Document object. I have to be able to set it's base namespace (attribute name "xmlns") to certain value. My input is DOM and is something like:

<root>...some content...</root>

What I need is DOM which is something like:

<root xmlns="myNamespace">...some content...</root>

That's it. Easy, isn't it? Wrong! Not with DOM!

I have tried the following:

1) Using doc.getDocumentElement().setAttribute("xmlns","myNamespace")

I get a document with empty xmlns (it works on any other attribute name!)

<root xmlns="">...</root>

2) Using renameNode(...)

First clone the document:

Document input = /*that external Document whose namespace I want to alter*/;

DocumentBuilderFactory BUILDER_FACTORY_NS = DocumentBuilderFactory.newInstance();
BUILDER_FACTORY_NS.setNamespaceAware(true);
Document output = BUILDER_NS.newDocument();
output.appendChild(output.importNode(input.getDocumentElement(), true));

I'm really missing document.clone(), but perhaps it's just me.

Now rename the root node:

output.renameNode(output.getDocumentElement(),"myNamespace",
    output.getDocumentElement().getTagName());

Now isn't that straightforward? ;)

What I get now is:

<root xmlns="myNamespace">
    <someElement xmlns=""/>
    <someOtherElement xmlns=""/>
</root>

So (as all of us have expected, right?), this renames the namespace only of the the root node.

Curse you, DOM!

Is there any way to do this recursively (without writing an own recursive method)?

Please help ;)

Please don't adv

Edit
Report

2 Answers

0

If you are ok with using the Xerces classes, you can create a DOMParser that replaces the URI of attributes and elements with your fixed up URIs:

import org.apache.xerces.parsers.DOMParser;

public static class MyDOMParser extends DOMParser {
    private Map<String, String> fixupMap = ...;

    @Override
    protected Attr createAttrNode(QName attrQName)
    {
        if (fixupMap.containsKey(attrQName.uri))
            attrQName.uri = fixupMap.get(attrQName.uri);
        return super.createAttrNode(attrQName);
    }

    @Override
    protected Element createElementNode(QName qName)
    {
        if (fixupMap.containsKey(qName.uri))
            qName.uri = fixupMap.get(qName.uri);
        return super.createElementNode(qName);
    }       
}

The elsewhere, you can parse the

DOMParse p = new MyDOMParser(...);
p.parse(new InputSource(inputStream));
Document doc = p.getDocument();
answered 2013-02-13T19:50:40.233
0

Let's say you've got your Document instance..

import org.dom4j.*;

{

    static final String         YOUR_NAMESPACE_PREFIX =   "PREFIX"; 
    static final String         YOUR_NAMESPACE_URI    =   "URI"; 

    Document document = ...

    //now get the root element
    Element element = document.getRootElement();
    renameNamespaceRecursive(element);
    ...

    //End of this method
}

//the recursive method for the operation
void renameNamespaceRecursive(Element element) {
    element.setQName(new QName(element.getName(), DocumentHelper.createNamespace(YOUR_NAMESPACE_PREFIX, YOUR_NAMESPACE_URI)));
    for (Iterator i  = element.elementIterator(); i.hasNext();) {
        renameNamespaceRecursive((Element)i.next());
    }
}

That should do.

answered 2013-04-22T16:38:14.403

Your Answer