简体   繁体   中英

Adding xml tag via code

I'm writing an application in C#. I already an .xml file that is not empty and I want to add new values to it, without deleting the existing values.

I have tried this code:

First:

FileStream docNewUser = new FileStream(@"C:\\MyApp\\MySubDir\\Data\\" + pr + ".xml", FileMode.Open);
XmlTextWriter xmlNewUser = new XmlTextWriter(docNewUser, null);
xmlNewUser.WriteStartDocument();

xmlNewUser.WriteStartElement("RootEl");//root 

xmlNewUser.WriteStartElement("Zapis");

xmlNewUser.WriteStartElement("Name");
xmlNewUser.WriteString(txtEnterName.Text);
xmlNewUser.WriteEndElement();

xmlNewUser.WriteEndElement();//end of zapis                

this.Close();

Second:

FileStream docNewUser = new FileStream(@"C:\\MyApp\\MySubDir\\Data\\" + pr + ".xml", FileMode.Open);
XmlTextWriter xmlNewUser = new XmlTextWriter(docNewUser, null);
xmlNewUser.WriteStartDocument();

xmlNewUser.WriteStartElement("RootEl");//root-ot

xmlNewUser.WriteStartElement("Zapis");

xmlNewUser.WriteStartElement("Name");
xmlNewUser.WriteString(txtEnterName.Text);
xmlNewUser.WriteEndElement();

xmlNewUser.WriteEndElement();//end of zapis                

xmlNewUser.WriteElementString("Ime", null, txtEnterName.Text);

this.Close();

Third:

FileStream docNewUser = new FileStream(@"C:\\MyApp\\MySubDir\\Data\\" + pr + ".xml", FileMode.Open);
XmlTextWriter xmlNewUser = new XmlTextWriter(docNewUser, null);
xmlNewUser.WriteStartDocument();

xmlNewUser.WriteStartElement("Zapis");

xmlNewUser.WriteStartElement("Name");
xmlNewUser.WriteString(txtEnterName.Text);
xmlNewUser.WriteEndElement();

xmlNewUser.WriteEndElement();//end of zapis                

xmlNewUser.WriteElementString("Ime", null, txtEnterName.Text);

this.Close();

I think the problem is that the stream doesn't know where to put the new value. some more information: the root element is already entered.

If your .NET version supports it, use LINQ to XML . (Caveat: I'm not an expert, and there's probably a more elegant way to write this.)

// Without error handling
var root = XElement.Load(@"C:\Users\TrueWill\Downloads\Foo.xml");

var product =
    (from item in root.Elements("item")
    where item.Element("name").Value == "Product1"
    select item)
    .Single();

product.Add(new XElement("size", "small"));

root.Save(@"C:\Users\TrueWill\Downloads\FooCopy.xml");

My test file (before):

<?xml version="1.0" encoding="utf-8"?>
<test>
<item><name>Product1</name></item>
<item><name>Product2</name></item>
</test>

My test file copy (after) (I copied rather than replacing):

<?xml version="1.0" encoding="utf-8"?>
<test>
  <item>
    <name>Product1</name>
    <size>small</size>
  </item>
  <item>
    <name>Product2</name>
  </item>
</test>

When you write XML to a file this way, it always overwrites what was in the file before. If you want to write to it using XmlTextWriter , you would have to copy the current content first, and write the new elements at the proper position. Don't forget that you can't read from and write to the same file at the same time, so you have to use a temporary file and overwrite the original with it. Or you read the whole file into a string first. Or write your result into a string first.

But a better solution might be to use XDocument (or XmlDocument ) to load the whole document, modify it and then save it. (Doing this is not a good idea if the XML file is huge.)

Use XmlDocument:

XmlDocument doc = new XmlDocument();
doc.Load("filepath");
XmlNode node = doc["MainNode"]["subnode1"]["subnode2"]; //to fetch the node after which you'd like to add something.
XmlElement stuffToAdd = doc.CreateNode("nodename");
stuffToAdd.InnerText = "the value of your added node";
node.AddChild(stuffToAdd);
doc.Save("filepath");

I'm doing this out of memory, so the names of the methods are aproximate.

As said in another answer, loading big XML files using XmlElement can be costy, because it is fully loaded in memory when you call Load() .

Is there a reason you are using XmlTextWriter? I find the LINQ to XML alternatives much easier.

your code would be something like below;

XElement el = new XElement("Zapis");
el.Add(new XElement("Name",txtEnterName.Text))
el.Save(@"C:\\MyApp\\MySubDir\\Data\\" + pr + ".xml")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM