Agregar etiqueta xml a través de código

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.

He probado este código:

Primero:

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();

Segundo:

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();

Tercero:

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.

preguntado el 27 de agosto de 11 a las 15:08

4 Respuestas

If your .NET version supports it, use LINQ a 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>

Respondido 27 ago 11, 20:08

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.

Pero una mejor solución podría ser usar XDocument (o 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.)

Respondido 27 ago 11, 20:08

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().

Respondido 27 ago 11, 20:08

This really helped. Thank you a lot :) - dfgj fghjk

Is there a reason you are using XmlTextWriter? I find the LINQ a 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")

Respondido 27 ago 11, 20:08

This wrote the new element in the .xml file, but erased everything else. - dfgj fghjk

if you want to load what is there use var existingEls= XElement.Load(filename) Y luego usar existingEls.Add() - kmcc049

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.