2
votes

I came across a problem similar to this:

How to prevent blank xmlns attributes in output from .NET's XmlDocument?

Except I'm creating a new node and then setting it's InnerXml property to a string of XML.

    Dim ns As String = "http://test"
    Dim doc As XmlDocument = New XmlDocument
    doc.LoadXml(String.Format("<data xmlns=""{0}""></data>", ns))

    Dim newElement As XmlElement = doc.CreateElement("new", ns)
    newElement.InnerXml = "<person><name>Joe</name></person>"

    Dim result As String = newElement.OuterXml

What I expected is:

<data xmlns="http://test">
  <new>
    <person>
      <name>Joe</name>
    </person>
  </new>
</data>

What it actually created:

<data xmlns="http://test">
  <new>
    <person xmlns="">
      <name>Joe</name>
    </person>
  </new>
</data>

According to the MSDN, the parsing is done in the current namespace context. I expected the current namespace context would have been the default namespace for not only newElement but all imported child nodes. I have experienced the same issue using CreateDocumentFragment().

Is there any way to prevent the child node immediately under newElement from showing up with an empty Namespace when importing a string of xml?

1

1 Answers

3
votes

The statement:

The parsing is done in the current namespace context.

means that any namespace prefixes that your XML string might contain will be interpreted in the context of the namespace prefixes that the document defines.

This causes that the following thing works:

Const ns As String = "http://test"
Const ns_foo As String = "http://www.example.com"

Dim doc As XmlDocument = New XmlDocument()
doc.LoadXml(String.Format("<data xmlns=""{0}"" xmlns:foo=""{1}""></data>", ns, ns_foo))

Dim newElement As XmlElement = doc.CreateElement("new", ns)
doc.DocumentElement.AppendChild(newElement)

newElement.InnerXml = "<foo:person><foo:name>Joe</foo:name></foo:person>"

and results in

<data xmlns:foo="http://www.example.com" xmlns="http://test">
   <new>
      <foo:person>
         <foo:name>Joe</foo:name>
      </foo:person>
   </new>
</data>

However, nodes that don't have a prefix are in no particular namespace by definition. They are in the default namespace.

There is no way you can influence the default namespace when setting InnerXml. It will always be assumed that the default namespace is the empty namespace.