4

I want to add xmlns attribute to the root node only, however when i add a namespace to the root element, all subsequent child elements also get the same xmlns attribute. How do I add xmlns attribute to a single node but not any of its children ? CODE:

public String toXml() {

        Document document = DocumentHelper.createDocument();
        Element documentRoot = document.addElement("ResponseMessage");
        documentRoot.addNamespace("",getXmlNamespace())
                .addAttribute("xmlns:xsi", getXmlNamespaceSchemaInstance())
                .addAttribute("xsi:schemaLocation", getXmlSchemaLocation())
                .addAttribute("id", super.getId());

        Element header = documentRoot.addElement("Header");
        buildHeader(header);

        Element body = documentRoot.addElement("Body");
        buildProperties(body);

        body.addElement("StatusMessage").addText(this.getStatusMessage().getMessage());

        return document.asXML();


    }
Phoenix
  • 8,695
  • 16
  • 55
  • 88
  • It is not clear what you mean. Do you see this namespace declaration on all child elements when serialized to XML? How do you add the namespace attribute? Do you have some code and result to show? – forty-two Oct 18 '11 at 19:08
  • Yes I see an empty (xmlns="") on all the child elements of the root element when serialized to xml .. – Phoenix Oct 18 '11 at 21:23

2 Answers2

6

OK, new answer.

If you want your elements to belong to a certain namespace, be sure to create them in that namespace. Use the methods that have Qname as one of its arguments. If you create an element with no namespace, DOM4J will have to add namespace declarations to accommodate to your (unwillingly) specification.

Your example slightly edited. I didn't use QName, but gave each element a namespace uri:

public static String toXml() {

    Document document = DocumentHelper.createDocument();
    Element documentRoot = document.addElement("ResponseMessage",
            getXmlNamespace());
    documentRoot.addAttribute(QName.get("schemaLocation", "xsi", "xsi-ns"),
            "schema.xsd").addAttribute("id", "4711");

    Element header = documentRoot.addElement("Header");

    Element body = documentRoot.addElement("Body", getXmlNamespace());
    // buildProperties(body);

    body.addElement("StatusMessage", getXmlNamespace()).addText("status");

    return document.asXML();

}

private static String getXmlNamespace() {
    return "xyzzy";
}

public static void main(String[] args) throws Exception {

    System.out.println(toXml());
}

produces as output:

<?xml version="1.0" encoding="UTF-8"?>
<ResponseMessage xmlns="xyzzy" xmlns:xsi="xsi-ns" xsi:schemaLocation="schema.xsd" id="4711">
<Header/><Body><StatusMessage>status</StatusMessage></Body>
</ResponseMessage>

UPDATE 2:

Note also, that I changed the way how the schemaLocation attribute is declared. You really never have to manually manage the namespace declarations--this will be taken care of by the library.

However, there is one case where it might be useful to add a namespace delaration: If you have a document with predominantly namespace X elements, and some child elements with namspace Y spread out in the document, declaring a namesapce binding for Y at the root element, may save a lot of repeating name space declarations in the child elements.

forty-two
  • 12,204
  • 2
  • 26
  • 36
2

Heres how. Its a bit of a hack, but it does what you want:

public static String toXml() {

Document d = DocumentHelper.createDocument();
Namespace rootNs = new Namespace("", DEFAULT_NAMESPACE); // root namespace uri
Namespace xsiNs = new Namespace("xsi", XSI_NAMESPACE); // xsi namespace uri
QName rootQName = QName.get(rootElement, rootNs); // your root element's name

Element root = d.addElement(rootElement);
root.setQName(rootQName);
root.add(xsiNs);
root.addAttribute("xsi:schemaLocation", SCHEMA_LOC)
.addAttribute("id", super.getId());

Element header = documentRoot.addElement("Header");

Element body = documentRoot.addElement("Body", getXmlNamespace());
// buildProperties(body);

body.addElement("StatusMessage", getXmlNamespace()).addText("status");

return document.asXML();

}
Jeshurun
  • 22,940
  • 6
  • 79
  • 92