使用Linq更新XML文件

时间:2011-11-20 23:02:02

标签: c# xml linq-to-xml

我在尝试使用新值更新xml文件时遇到问题。我有一个类Person,它只包含2个字符串,名称和描述。我填充此列表并将其写为XML文件。然后我填充一个新列表,其中包含许多相同的名称,但其中一些包含另一个列表不包含的描述。如何检查当前XML文件中的名称是否包含“无描述”以外的值,这是“无”的默认值?

xml文件的一部分:

<?xml version="1.0" encoding="utf-8"?>
<Names>
  <Person ID="2">
    <Name>Aaron</Name>
    <Description>No description</Description>
  </Person>
  <Person ID="2">
    <Name>Abdi</Name>
    <Description>No description</Description>
  </Person>
</Names>

这是将列表写入xml文件的方法:

public static void SaveAllNames(List<Person> names)
{
    XDocument data = XDocument.Load(@"xml\boys\Names.xml");   

    foreach (Person person in names)
    {
        XElement newPerson = new XElement("Person",
                                 new XElement("Name", person.Name),
                                 new XElement("Description", person.Description)
                             );

        newPerson.SetAttributeValue("ID", GetNextAvailableID());

        data.Element("Names").Add(newPerson);
    }
    data.Save(@"xml\boys\Names.xml");
}

在foreach循环中,如何检查该人的名字是否已经存在,然后检查描述是否不是“无描述”,如果是,请使用新信息更新它?

3 个答案:

答案 0 :(得分:2)

我不确定我是否理解你想要什么,但我假设你只想在名称已经存在并且描述当前是No description时更新描述(你可能应该更改为一个空字符串,BTW)。

您可以将所有Person放入基于名称的Dictionary

var doc = …;

var persons = doc.Root.Elements()
                      .ToDictionary(x => (string)x.Element("Name"), x => x);

然后查询它:

if (persons.ContainsKey(name))
{
    var description = persons[name].Element("Description");
    if (description.Value == "No description")
        description.Value = newDescription;
}

也就是说,如果你关心表现。如果不这样做,则不需要字典:

var person = doc.Root.Elements("Person")
                     .SingleOrDefault(x => (string)x.Element("Name") == name);

if (person != null)
{
    var description = person.Element("Description");
    if (description.Value == "No description")
        description.Value = newDescription;
}

答案 1 :(得分:0)

您可以在XElement上使用the Nodes-Method并手动检查。

但我会建议你使用the XPathEvaluate-Extension Method

对于XPath表达式,请看一下: How to check if an element exists in the xml using xpath?

答案 2 :(得分:0)

我认为您可以创建一个仅包含不在xml中的人员的人员列表。

喜欢↓

        var containlist = (from p in data.Descendants("Name") select p.Value).ToList();
        var result = (from p in peoplelist where !containlist.Contains(p.Name) select p).ToList();

因此,您无需使用现有方法更改任何内容......

在......之后调用它。

SaveAllNames(result);