使用Linq更新XML文件

本文关键字:文件 XML 更新 Linq 使用 | 更新日期: 2023-09-27 18:15:27

我在尝试用新值更新xml文件时遇到了麻烦。我有一个类Person,它只包含两个字符串,名称和描述。我填充这个列表并将其写成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循环中,我如何检查该人的姓名是否已经在那里,然后检查描述是否不是"无描述",如果是,用新信息更新它?

使用Linq更新XML文件

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

您可以根据名称将所有Person s放入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;
}

您可以在XElement上使用node - method并手动检查。

但是我建议你使用xpathevalue - extension方法

看一下XPath表达式:如何检查一个元素是否存在于使用xpath的xml ?

我认为你可以创建一个只包含xml中没有的人的peoplelist

像↓

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

这样,您就不需要使用exist方法更改任何内容…

在…之后调用它

SaveAllNames(result);