使用 Linq 更新 XML 文件

发布于 2024-12-16 20:30:13 字数 1246 浏览 0 评论 0原文

我在尝试使用新值更新 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 循环中,如何检查该人的姓名是否已存在,然后检查描述是否是“无描述”以外的内容,如果是,用新信息更新它?

I'm having trouble trying to update my xml file with a new value. I have a class Person, which only contains 2 strings, name and description. I populate this list and write it as an XML file. Then I populate a new list, which contains many of the same names, but some of them contains descriptions that the other list did not contain. How can I check if the name in the current XML file contains a value other than "no description", which is the default for "nothing"?

Part of the xml file:

<?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>

And this is the method for writing the list to the xml file:

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");
}

In the foreach loop how do I check if the person's name is already there, and then check if the description is something other than "no description", and if it is, update it with the new information?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦罢 2024-12-23 20:30:13

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

您可以将所有 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;
}

I'm not sure I understand properly what you want, but I'm assuming you want to update the description only when the name is already there and the description is currently No description (which you should probably change to an empty string, BTW).

You could put all the Persons into a Dictionary based by name:

var doc = …;

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

and then query it:

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

That is, if you care about performance. If you don't, you don't need the dictionary:

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;
}
爺獨霸怡葒院 2024-12-23 20:30:13

您可以使用节点方法 在 XElement 上并手动检查。

但我建议您使用 XPathEvaluate-Extension Method

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

You can use the Nodes-Method on XElement and check manually.

But i will advise you to use the XPathEvaluate-Extension Method

For XPath expression take a look at:
How to check if an element exists in the xml using xpath?

摘星┃星的人 2024-12-23 20:30:13

我认为您可以创建一个人员列表,其中仅包含不在 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); 

I think you could create a peoplelist which only contains people not in the xml.

like ↓

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

so that , you would no need to change anything with your exist method ...

just call it after..

SaveAllNames(result); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文