【问题标题】:C# - Unable to save a customized linq-to-xml file, with new elements in it?C# - 无法保存自定义的 linq-to-xml 文件,其中包含新元素?
【发布时间】:2011-10-29 09:02:56
【问题描述】:

我正在创建一个新的 XDocument 并在其中插入一个根元素“配置文件”,然后保存。

if (!System.IO.File.Exists("profiles.xml"))
{
    XDocument doc = new XDocument(
        new XElement("profiles")
    );
    doc.Save("profiles.xml", SaveOptions.None);
}

然后我想接受用户输入并将配置文件添加到已经创建的 xml 文件中:

XElement profile =
        new XElement(Player.Name,
            new XElement("level", Player.Level),
            new XElement("cash", Player.Cash)
        );

XDocument doc = XDocument.Load("profiles.xml");
List<XElement> profiles = doc.Root.Elements().ToList();

for (int i = 0; i < profiles.Count; i++)
{
    if (profiles[i].Name.ToString() == Player.name)
    {
        profiles[i] = profile;
        return;
    }
}
profile.Add(profile);
doc.Save("profiles.xml", SaveOptions.None);

但由于某种原因,它永远不会添加任何新的配置文件?

编辑:另外,如果我在 xml 文件中手动创建一个新配置文件,它也不会自定义,所以问题出在保存文件中?

【问题讨论】:

    标签: c# xml linq-to-xml xelement


    【解决方案1】:

    您实际上从来没有做任何事情来更改XDocumentdoc 所指的任何元素:

    • 如果您找到具有现有名称的元素,则您正在修改 列表,但这不会修改文档。你可能想使用XElement.ReplaceWith:

      profiles[i].ReplaceWith(profile);
      

      请注意,在这种情况下,您甚至不会尝试再次保存 XML 文件(由于 return 语句),因此在这种情况下您要实现的目标并不是很清楚。

    • 如果您没有找到该元素,则将profile 元素添加到自身,这当然不会修改文档。我怀疑你想要:

      doc.Root.Add(profile);
      

      换句话说,将新的配置文件元素添加为根元素的新最终子元素。

    编辑:这是一种不同的尝试替代方法 - 我假设任何一个名称都应该只出现一次:

    XDocument doc = XDocument.Load("profiles.xml");
    var existingElement = doc.Root
                             .Elements()
                             .Where(x => x.Name.ToString() == Player.name)
                             .FirstOrDefault();
    if (existingElement != null)
    {
        existingElement.ReplaceWith(profile);
    }
    else
    {
        doc.Root.Add(profile);
    }
    doc.Save("profiles.xml", SaveOptions.None);
    

    另外,我强烈建议你不要使用玩家名字作为元素name。将其用作属性值或文本值,例如

    XElement profile =
            new XElement("player",
                new XAttribute("name", Player.Name),
                new Attribute("level", Player.Level),
                new XAttribute("cash", Player.Cash)
            );
    

    这样,如果玩家名称中有空格等,您就不会遇到问题。然后您需要将查询更改为:

    var existingElement = doc.Root
                             .Elements()
                             .Where(x => (string) x.Attribute("name)" == Player.name)
                             .FirstOrDefault();
    

    【讨论】:

    • @Mahi:我已经(两次)解释了为什么替换不起作用 - 但请参阅我的编辑,它提出了一种不同的方法,包括重组你的 XML。
    猜你喜欢
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    相关资源
    最近更新 更多