Jonas
Jonas

Reputation: 128837

How to set namespace only on first tag with XOM?

I am using XOM to build XML documents in Java.

I have created a simple XML document, and I want an XML namespace. But when I set the namespace on the first tag, an empty namespace is set on the childs like xmlns="", how can I get rid of this behaviour? I only want xmlns on the first tag.

I want this XML:

<request xmlns="http://my-namespace">
    <type>Test</type>
    <data>
        <myData>test data</myData>
    </data>
</request>

But this is the XML document output from XOM

<request xmlns="http://my-namespace">
    <type xmlns="">Test</type>
    <data xmlns="">
        <myData>test data</myData>
    </data>
</request>

This is my Java XOM code:

String namespace = "http://my-namespace";
Element request = new Element("request", namespace);

Element type = new Element("type");
type.appendChild("Test");

request.appendChild(type);

Element data = new Element("data");
request.appendChild(data);

Element myData = new Element("myData");
myData.appendChild("test data");
data.appendChild(myData);

Document doc = new Document(request);
doc.toXML();

Upvotes: 2

Views: 1972

Answers (4)

jakobum
jakobum

Reputation: 16

In XOM you can add a namespace declaration to the root element.

Here's a short example with three different namespaces:

final String NS_XLINK = "http://www.w3.org/1999/xlink";
final String NS_OTHER = "http://other.com";
Element root = new Element("root", "http://root.com");
root.addNamespaceDeclaration("xlink", NS_XLINK);
root.addNamespaceDeclaration("other", NS_OTHER);
root.addAttribute(new Attribute("xlink:href", NS_XLINK, "http://somewhere.com"));
root.appendChild(new Element("other:alien", NS_OTHER));
Document doc = new Document(root);
System.out.println(doc.toXML());

which produces this result (with additional line breaks inserted for readability):

  <?xml version="1.0"?>
  <root
    xmlns="http://root.com"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:other="http://other.com"
    xlink:href="http://somewhere.com">
    <other:alien />
  </root>

Upvotes: 0

Elliotte Rusty Harold
Elliotte Rusty Harold

Reputation: 991

Don't confuse namespaces and namespace declarations. The namespace is an intrinsic property of each element. The namespace declaration is the `xmlns' attribute. They are not the same thing, although they are connected. When you create an element, you set its namespace, not its namespace declaration.

In the XOM data model namespaces are not attributes. They are an intrinsic property of the element itself. There is no rule in XML that requires children of an element to be in the same namespace as the parent. Indeed theoretically every element in the document could be in a different namespace.

In XOM you specify the namespace of an element or attribute at the same time you specify the local name. When you create an element, the element initially has no parent so there's no way for XOM to default to giving the element the same namespace as its parent, even if that's what was wanted (and it's not).

When the document is serialized the namespaces are represented by xmlns and xmlns:*prefix* attributes. XOM figures out where to put these elements to match the namespaces you've assigned to each element. Just specify the namespace you want for each element in your code, and let XOM figure out where to put the namespace declarations.

Upvotes: 1

bovineone
bovineone

Reputation: 303

I ran into the same problem, and Google lead me here.

@Michael - That's what it says in the javadoc, yes, but unfortunately, that's not how it works when you implement it. The child elements will continue to get blank xmlns attributes unless you do Catchwa's implementation.

Catchwa's implementation works just fine. Only the element I tell it to have a namespace, has a namespace. All empty xmlns attributes are gone. It's strange.

Is it a bug? I can't seem to figure that part out. Or is it just the way XOM works?

Upvotes: 2

Catchwa
Catchwa

Reputation: 5855

This works for me. However, I'm a bit puzzled as to why the Element objects don't inherit the namespace of their parents, though. (Not an XML nor XOM expert)

Code:

String namespace = "http://my-namespace";
Element request = new Element("request", namespace);

Element type = new Element("type", namespace);
type.appendChild("Test");

request.appendChild(type);

Element data = new Element("data", namespace);
request.appendChild(data);

Element myData = new Element("myData", namespace);
myData.appendChild("test data");
data.appendChild(myData);

Document doc = new Document(request);
System.out.println(doc.toXML());

Output:

<?xml version="1.0"?>
<request xmlns="http://my-namespace">
  <type>Test</type>
  <data>
    <myData>test data</myData>
  </data>
</request>

Upvotes: 8

Related Questions