1

I want to set the namespace of the root element in a XML file which works:

XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "no"));
XNamespace ns = @"http://mynamespace.de/test";
doc.Add(new XElement(ns + "RootElement"));
doc.Root.Add(new XElement("SomeChildElement"));

But the direct child elements do have an empty xmlns attribute. How can I avoid that? I only want the namespace set in the root element.

1

2 Answers 2

3

But the direct child elements do have an empty xmlns attribute. How can I avoid that?

You specify the namespace for the child elements as well:

doc.Root.Add(new XElement(ns + "SomeChildElement"));

The point is that elements inherit the closest xmlns=... namespace specification. When you just use new XElement("SomeChildElement") that's actually creating an element with an empty namespace URI, so the xmlns="" would be required in order to give it the right namespace. If you want:

<RootElement xmlns="http://mynamespace.de/test">
  <SomeChildElement />
</RootElement>

Then you really want a SomeChildElement element with the same namespace as the root element - which is what the code at the top of my answer will give you.

Note that you don't need the verbatim string literal for the namespace, by the way - a regular string literal is fine, as the URI doesn't contain any backslashes or new lines:

XNamespace ns = "http://mynamespace.de/test";
Sign up to request clarification or add additional context in comments.

2 Comments

I forgot to mention that I want the namespace only set in the root element.
@juergend: I suspect you don't understand namespace defaulting then. Either you want the child element in the same namespace as the root element (in which case it will inherit it without needing xmlns=...) or you don't want it in any namespace (in which case your document will correctly include xmlns="").
0

I know it's question about C#, but since it's the first question that is coming in the google, I will answer for Java.

In my case, I was using Jackson2XmlMessageConverter.

After I added

@XmlRootElement(name = "root", namespace = "http://namespace")

to my root element, I had same issue for the children.

Thanks to the accepted answer, I understood that I had to annotate fields with

@XmlElement(namespace = "http://namespace")

(and do it recursively for their children) and it resolved the issue.

Example test:

class MyMessageParserTest {
    // initialize the converter in your preferred way: Autowire, manually in @BeforeEach, ...
    private Jackson2XmlMessageConverter converter;
    private static MyMessage createMyMessage(){
    // create your object here
}

private static String createRawXml() {
    // create expected xml
}

@Test
public void fromObjectToXml_OK() {
    //given
    String expectedXml = createRawXml();
    MyMessage object = createMyMessage();
    MessageProperties messageProperties = new MessageProperties();
    messageProperties.setContentType("application/xml");
    Message message = converter.toMessage(object, messageProperties);
    //when
    String result = new String(message.getBody(), Charset.defaultCharset());
    //then
    assertThat(result).isXmlEqualTo(expectedXml); //might be deprecated, 
}
@Test
public void fromXmlToObject_OK() {
    //given
    MyMessage expectedObject = createMyMessage();
    String rawXml = createRawXml();
    MessageProperties messageProperties = new MessageProperties();
    messageProperties.setContentType("application/xml");
    Message message = new Message(rawXml.getBytes(), messageProperties);
    //when
    MyMessage result = (MyMessage) converter.fromMessage(message, new ParameterizedTypeReference<MyMessage>() {
    });
    //then
    assertEquals(expectedObject, result);
}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.