Master_T
Master_T

Reputation: 7987

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.

Upvotes: 2

Views: 612

Answers (2)

Steven Doggart
Steven Doggart

Reputation: 43743

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.

Upvotes: 1

Robert Snyder
Robert Snyder

Reputation: 2409

I would suggest looking into the XElement and XDocument found in the System.Xml.Linq namespace. It offers exactly what you are looking for a basic idea is of what you want is like this

XElement root = new XElement("RelativeLayout,
            new XAttribute("android:layout_width", ""),
            new XAttribute("fill_parent", "") //etc
            );
root.Add(XElement.Parse(s));

Note that I didn't test this code, but I do use code very close to this frequently so the syntax is close.

Upvotes: 0

Related Questions