【问题标题】:Update XML file with Linq使用 Linq 更新 XML 文件
【发布时间】:2012-01-02 13:54:33
【问题描述】:

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

部分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 循环中如何检查人名是否已经存在,然后检查描述是否不是“无描述”,如果是,则使用新信息更新?

【问题讨论】:

    标签: c# xml linq-to-xml


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢,我用的是这个版本,只是稍微修改了一下以满足我的需要:)
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      我认为您可以创建一个仅包含不在 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); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-02
        • 1970-01-01
        • 2012-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多