37

I have an XmlDocument that already exists and is read from a file.

I would like to add a chunk of Xml to a node in the document. Is there a good way to create and add all the nodes without cluttering my code with many .CreateNote and .AppendChild calls?

I would like some way of making a string or stringBuilder of a valid Xml section and just appending that to an XmlNode.

ex: Original XmlDoc:

<MyXml>
   <Employee>
   </Employee>
</MyXml>

and, I would like to add a Demographic (with several children) tag to Employee:

<MyXml>
   <Employee>
      <Demographic>
         <Age/>
         <DOB/>
      </Demographic>
   </Employee>
</MyXml>

6 Answers 6

93

I suggest using XmlDocument.CreateDocumentFragment if you have the data in free form strings. You'll still have to use AppendChild to add the fragment to a node, but you have the freedom of building the XML in your StringBuilder.

XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(@"<MyXml><Employee></Employee></MyXml>");

XmlDocumentFragment xfrag = xdoc.CreateDocumentFragment();
xfrag.InnerXml = @"<Demographic><Age/><DOB/></Demographic>";

xdoc.DocumentElement.FirstChild.AppendChild(xfrag);
3
  • what if there are quotes (") like as in attributes in the fragment?
    – Raulp
    Commented Nov 12, 2014 at 12:19
  • It does not load an existing xml file. Commented Sep 30, 2016 at 17:15
  • At first i thouht this wouldn't work because it still replaced <> with : &gt; and &lt but i used inntertext instead of innerxml
    – Pieter
    Commented Apr 28, 2021 at 15:05
14

Try this:

employeeNode.InnerXml = "<Demographic><Age/><DOB/></Demographic>";

Alternatively (if you have another XML document that you want to use):

employeeNode.AppendChild(employeeNode.OwnerDocument.ImportNode(otherXmlDocument.DocumentElement, true));
5

As an alternative, this is how you could do it in a more LINQy 3.5 manner:

 XDocument doc = XDocument.Load(@"c:\temp\test.xml");
 XElement demoNode = new XElement("Demographic");
 demoNode.Add(new XElement("Age"));
 demoNode.Add(new XElement("DOB"));
 doc.Descendants("Employee").Single().Add(demoNode);
 doc.Save(@"c:\temp\test2.xml");
3

Consider using an XmlWriter for building your fragments on a StringBuilder as this will provide validation and character substitution for you.

1
  • @ffpf: +1 good advice, but namespaces and XmlWriter always have me going back to MSDN.
    – user7116
    Commented Oct 7, 2008 at 17:58
0

None of this was working for me so i played around abit and here is my solution.

First load up a text field(you can put it to visible = false in public version) load the data in to the text field like so.

string Path = Directory.GetCurrentDirectory() + "/2016";
            string pathFile = Path + "/klanten.xml";
            StreamReader sr = new StreamReader(pathFile);
            txt.Text = sr.ReadToEnd();
            sr.Close();

on the save button load up the text field en save it. Dont forget u will have to refresh the text field after that, if u want to add multiple addresses/names, i have not included that part.

string name = Globals.s_Name;
        string klanten = txt.Text;
        string s = klanten;
        XmlDocument xdoc = new XmlDocument();

        string klant = "<voornaam>" + naamBox1.Text + "</voornaam>";
        xdoc.LoadXml(s);
        XmlDocumentFragment xfrag = xdoc.CreateDocumentFragment();
        xfrag.InnerXml = klant;
        xdoc.DocumentElement.FirstChild.AppendChild(xfrag);
        xdoc.Save(name + "/klanten.xml");
0

All that I do is creating a new dataset object and open the xml file using ReadXML myDataset.ReadXML(path and file name).

Then add or remove the rows that I need and save the document again using myDataset.WriteXML(path and file name).

Bye.

Not the answer you're looking for? Browse other questions tagged or ask your own question.