C # - Невозможно сохранить настроенный файл linq-to-xml с новыми элементами в нем? - PullRequest
2 голосов
/ 29 октября 2011

Я создаю новый 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-файл, он также не будет настраивать, поэтому проблема в сохранении файла?

1 Ответ

3 голосов
/ 29 октября 2011

На самом деле вы никогда не делаете ничего, чтобы изменить какие-либо элементы в пределах XDocument, к которым относится doc:

  • Если вы найдете элемент с существующим именем, вы изменяете список , но это не изменит документ. Вы, вероятно, хотите использовать 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();
...