Java – Dom4j xmlns attribute
I want to add only the xmlns attribute to the root node, but when I add a namespace to the root element, all subsequent child elements will get the same xmlns attribute How do I add the xmlns attribute to a single node without adding any child nodes?
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(); }
Solution
OK, new answer
If you want elements to belong to a namespace, be sure to create them in that namespace Use a method with QName as one of its parameters If you create an element without a namespace, Dom4j will have to add namespace declarations to suit your (reluctant) specification
Your example is 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()); }
Generate 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:
Also note that I changed the declaration of the schemalocation attribute You really never have to manage namespace declarations manually - this will be handled by the library
However, there is a case where adding namespace delays can be useful: if you have a document that mainly contains namespace x elements and expand some child elements with namespace y in the document, a name binding y element is declared in the root directory to save a large number of duplicate namespace declarations in the child elements