使用XmlWriter将现有的XML文件追加内容

9
我已经使用以下代码创建了一个XML文件:
```

我已经使用以下代码来创建一个XML文件:

```
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.NewLineOnAttributes = true;
using (XmlWriter xmlWriter = XmlWriter.Create("Test.xml", xmlWriterSettings))
{
   xmlWriter.WriteStartDocument();
   xmlWriter.WriteStartElement("School");
   xmlWriter.WriteEndElement();
   xmlWriter.WriteEndDocument();
   xmlWriter.Close();
 }

我需要动态插入节点,创建以下结构:
<?xml version="1.0" encoding="utf-8"?>
<School />
   <Student>
      <FirstName>David</FirstName>
      <LastName>Smith</LastName>
   </Student>
   ...
   <Teacher>
      <FirstName>David</FirstName>
      <LastName>Smith</LastName>
   </Teacher>
   ...
</School>

我该怎么做?“FirstName”和“LastName”的值应该从键盘读取,并且可以随时输入这些值,当然是在已有的情况下。


1
大多数人会使用XmlDocument、XDocument或序列化来完成这样的操作。选择XmlWriter有点奇怪。 - Tony Hopkinson
5个回答

22

您可以使用 Linq Xml

XDocument doc = XDocument.Load(xmlFilePath);
XElement school = doc.Element("School");
school.Add(new XElement("Student",
           new XElement("FirstName", "David"),
           new XElement("LastName", "Smith")));
doc.Save(xmlFilePath);

编辑

如果您想向现有的<Student>元素中添加元素,只需在其前面添加属性即可。

school.add(new XElement("Student",
           new XAttribute("ID", "ID_Value"),
           new XElement("FirstName", "David"),
           new XElement("LastName", "Smith")));

然后您可以通过搜索 - 获取 - 添加,为现有的<Student>添加更多细节。

XElement particularStudent = doc.Element("School").Elements("Student")
                                .Where(student => student.Attribute("ID").Value == "SearchID")
                                .FirstOrDefault();
if(particularStudent != null)
    particularStudent.Add(new XElement("<NewElementName>","<Value>");

但是你的代码创建了一个新元素。OP想要将新元素添加到现有元素中。 - Selman Genç
我想每次需要时添加新元素。 - user3105160
很抱歉,我有点困惑。这是我第一次使用 XML。 - user3105160
确实 :) 感谢您的帮助,如果您帮我完成这一步骤,我将非常感激 ;) - user3105160

15

终于成功了 :)

if (!File.Exists("Test.xml"))
{
   XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
   xmlWriterSettings.Indent = true;
   xmlWriterSettings.NewLineOnAttributes = true;
   using (XmlWriter xmlWriter = XmlWriter.Create("Test.xml", xmlWriterSettings))
   {
      xmlWriter.WriteStartDocument();
      xmlWriter.WriteStartElement("School");

      xmlWriter.WriteStartElement("Student");
      xmlWriter.WriteElementString("FirstName", firstName);
      xmlWriter.WriteElementString("LastName", lastName);
      xmlWriter.WriteEndElement();

      xmlWriter.WriteEndElement();
      xmlWriter.WriteEndDocument();
      xmlWriter.Flush();
      xmlWriter.Close();
   }
}
else
{
   XDocument xDocument = XDocument.Load("Test.xml");
   XElement root= xDocument.Element("School");
   IEnumerable<XElement> rows = root.Descendants("Student");
   XElement firstRow= rows.First();
   firstRow.AddBeforeSelf(
      new XElement("Student",
      new XElement("FirstName", firstName),
      new XElement("LastName", lastName)));
   xDocument.Save("Test.xml");
}

7
XDocument会将整个文件读入内存,这通常不是问题,但需要知道此情况。 - Banshee

3
我有一个建议,下次可以这样做:
string nameFile = "Test.xml";
bool newFile = false;


if (!File.Exists(nameFile))
{
    newFile = true;
    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
    xmlWriterSettings.Indent = true;
    xmlWriterSettings.NewLineOnAttributes = true;

    xmlWriter.WriteStartDocument();
    xmlWriter.WriteStartElement("School");

    xmlWriter = XmlWriter.Create("Test.xml", xmlWriterSettings))
}
else
{
    doc = new XmlDocument();
    doc.Load(nameFile);

    // Create a XPathNavigator
    // You can go where you want to add
    // In this case it is just after last child of the roor
    XPathNavigator navigator = doc.CreateNavigator();     

    navigator.MoveToChild("School", "");
    xmlWriter = navigator.AppendChild();
}

// From here you can work only with xmlWriter,
// One will point on a file and the other on the stream of xmlDocument
// So you will need to save the document in the second choise

xmlWriter.WriteStartElement("Student");
xmlWriter.WriteElementString("FirstName", firstName);
xmlWriter.WriteElementString("LastName", lastName);
xmlWriter.WriteEndElement();


// End document / close or save. 
if (newFile)
    xmlWriter.WriteEndDocument();

xmlWriter.Close();

if (!newFile)
    doc.Save(nameFile);

应该可以正常工作。:)

3

让我给您提个建议。在创建您的xml文件时,为学生添加一个唯一的id,如下所示:

// to store the id variable, if you create more than one student you can increase it
count = 0; 

xmlWriter.WriteStartElement("School");
xmlWriter.WriteAttributeString("ID",count.ToString());
xmlWriter.WriteEndElement();

然后当你需要给这个学生添加信息时,你可以获取IDFirstnameLastname,并且你可以像这样使用LINQ to XML编辑你的XML文件:

int id = Convert.ToInt32(txtStudentId.Text);
XDocument xDoc = XDocument.Load("Test.xml");
XElement student = xDoc.Descendants("Student").Where(x => (string) x.Attribute("ID") == id).FirstOrDefault();

if (student != null)
{
   string firstName = txtFirstName.Text;
   string lastName = txtLastName.Text;
   XElement first = new XElement("FirstName", firstName);
   XElement last = new XElement("LastName", lastName);
   student.Add(first);
   student.Add(last);
   xDoc.Save("Test.xml");
}

3

我知道你要求使用XmlWriter,但我相信你可以通过使用XDocument来更少的代码实现这个功能。以下是我的解决方案:

var filePath = "path/XmlFile.xml";
var xmlDoc = XDocument.Load(filePath);
var parentElement = new XElement("Student");
var firstNameElement = new XElement("FirstName", firstNameVariable);
var lastNameElement = new XElement("LastName", lastNameVariable);

parentElement.Add(firstNameElement);
parentElement.Add(lastNameElement);

var rootElement = xmlDoc.Element("School");
rootElement?.Add(parentElement);

xmlDoc.save();

这基于以下的XML结构,将追加到...中:
<School>
  <Student>
    <FirstName>John</FirstName>
    <LastName>Johnson</LastName>
  </Student>
...
</School>

希望这可以帮助到您!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接