3

When creating a document with a default namespace <root xmlns="....">using DOM4J, I get the following output on writing to file.

<?xml version="1.0" encoding="UTF-8"?>

<root xmlns="http:/foo.bar">
  <foo xmlns="">bar</foo> <!-- unwanted xmlns="" on foo -->
</root>

What I expected (and want) is for foo to be <foo> not <foo xmlns="">. Here is some demo code

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class App {

    public static void main(String[] args) throws Exception {
        Namespace xmlns = DocumentHelper.createNamespace("", "http:/foo.bar");
        Element root = DocumentHelper.createElement("root");
        root.add(xmlns);

        Document document = DocumentHelper.createDocument();
        document.setRootElement(root);

        Element child = DocumentHelper.createElement("foo");
        child.setText("bar");
        root.add(child);

        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter( System.out, format );
        writer.write( document );
    }
}

How do I remove the extra attribute from <foo>? I'm happy to use a different library if that would be easier.

SOLUTION

The answer below together with this question helped solve my issue. I have also included the corrected code below:

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class App {

    public static void main(String[] args) throws Exception {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("root");

        Namespace xmlns = Namespace.get("http:/foo.bar");
        root.add(xmlns);

        root.addElement("foo", "http:/foo.bar")
                .addText("bar");

        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter( System.out, format );
        writer.write( document );
    }
}
Community
  • 1
  • 1
Romski
  • 1,912
  • 1
  • 12
  • 27

1 Answers1

2

Are you saying that you want every node in the tree to be in the same namespace?

The code posted above clearly directs the library to put the child element foo in a different namespace (in this case, the default or null namespace) from its parent. So the serialized XML reflects this fact! If you want "foo" to be in the same namespace you'll have to assign it properly.

If you just want a single namespace, I suggest looking into assigning the default namespace in dom4j.

chrisinmtown
  • 3,571
  • 3
  • 34
  • 43
  • I tried JDom and found the same behaviour, so I expect this reflects my lack of understanding of the expected behaviour. I found a similar question on SO for JDom and the answer was to pass the namespace to the constructor of every element in the document which has worked for me. was this what you meant? I've not tried it with Dom4J yet as I need to move on while I've got working code, but I expect it will. – Romski Feb 24 '15 at 02:55
  • Essentially yes - somehow you must tell each element its namespace. Also please revise your post to be a SSCCE (not an excerpt). – chrisinmtown Feb 24 '15 at 02:59
  • What would you like to see for an edit (this was what I though to be the least amount of code to demonstrate the problem, less the imports and enclosing main method). – Romski Feb 24 '15 at 03:23
  • Personally I want self-contained: I can copy the code, paste to my eclipse, set a breakpoint, click Debug, then concentrate on the issue -- not waste time reconstructing a test harness. – chrisinmtown Feb 24 '15 at 10:34