Search code examples
xmlvb.netxmldocument

c# / vb.net - Add XML text to XmlDocument


I'm trying to add a piece of Xml text that I have prepared to an existing document in vb.net, I'm using the XmlDocument class. Here is my code (simplified to explain the problem):

Dim s As String = "<RelativeLayout android:layout_width=""fill_parent"" android:layout_height=""fill_parent"" android:layout_weight=""1.0"" />"
Dim tempdoc = New XmlDocument()
tempdoc.LoadXml("<doc />")
ns = New XmlNamespaceManager(tempdoc.NameTable)
ns.AddNamespace("android", "http://schemas.android.com/apk/res/android")
tempdoc.DocumentElement.SetAttribute("xmlns:android", "http://schemas.android.com/apk/res/android")
Dim frag = tempdoc.CreateDocumentFragment()
frag.InnerXml = s

The last instruction generates an XmlException that reads "android prefix is undeclared" I was under the impression that either XmlNamespaceManager (lines 4-5) or writing the namespace attribute directly (line 6) would take care of this, but apparently not.

What am I doing wrong?

I know I could just write the element manually with the createelement method, but the example I gave is simplified to explain the problem. In reality the string "s" is a big piece of Xml with lots of attributes and subnodes, writing it all by hand in code would be a pain. What I want to do is add the whole piece of Xml to the document, if possible.


Solution

  • When you set the InnerXml property, it does not use the context in the namespace manager. Instead, it assumes that all of the namespaces will be explicitly defined inside the XML fragment that is given to it. Therefore, this simplest solution is to just include the namespace declaration in the fragment, like this:

    Dim s As String = "<RelativeLayout xmlns:android=""http://schemas.android.com/apk/res/android"" android:layout_width=""fill_parent"" android:layout_height=""fill_parent"" android:layout_weight=""1.0"" />"
    

    If you can't do that in the fragment string, you could always load that fragment at run-time and add the namespace declaration attribute to it via the SetAttribute method. Then you could use that modified fragment to give to the InnerXml property.

    Alternatively, you could resort to using the CreateElement method, which would allow you to utilize the namespace manager.