#c# #xml #loading
#c# #xml #Загрузка
Вопрос:
Я пытаюсь сделать так, чтобы при запуске программы и нажатии кнопки Сохранить (как в видеоиграх) загружались переменные из файла сохранения. Но когда я пытаюсь загрузить переменные, появляется только окно сообщения («Сохранить загружено!»), и XML не перезаписывает мои переменные. Вот код :
private void MainWindow_Load(object sender, EventArgs e)
{
XmlReader xReader = XmlReader.Create("C:\Save\Save1.xml");
while (xReader.Read())
{
if ((xReader.NodeType == XmlNodeType.Element) amp;amp; (xReader.Name == "Variable"))
{
if (xReader.HasAttributes)
{
MessageBox.Show("Loaded a save!");
Vars.zombies = (Convert.ToDouble(xReader.GetAttribute("Variable","Zombies")));
Vars.infected = (Convert.ToDouble(xReader.GetAttribute("Variable","Infected")));
Vars.wolfs = (Convert.ToDouble(xReader.GetAttribute("Varaible","Wolfs")));
}
}
}
Это когда программа загружается после сохранения. ^
private void SaveButton_Click(object sender, EventArgs e)
{
XmlTextWriter xWriter = new XmlTextWriter("C:\Save\Save1.xml", Encoding.UTF8);
xWriter.WriteStartDocument();
xWriter.Formatting = Formatting.Indented;
xWriter.WriteStartElement("Variables");
xWriter.WriteStartElement("Variable");
xWriter.WriteAttributeString("Zombies",Vars.zombies.ToString());
xWriter.WriteEndElement();
xWriter.WriteStartElement("Variable");
xWriter.WriteAttributeString("Infected",Vars.infected.ToString());
xWriter.WriteEndElement();
xWriter.WriteStartElement("Variable");
xWriter.WriteAttributeString("Wolfs",Vars.wolfs.ToString());
xWriter.WriteEndElement();
xWriter.WriteEndElement();
xWriter.Close();
}
Это код, который сохраняет переменные ^
public static double infected = 0;
public static double zombies = 0;
public static double wolfs = 0;
И, наконец, переменные в отдельном классе ^
Кто-нибудь может сказать мне, что я делаю не так? Сохранение работает идеально, но программа просто не загружает переменные.
Комментарии:
1. Ваши статические настройки инициализированы в 0, а метод Convert возвращает 0, потому что вы переходите к нему,
null
возвращаемомуxReader.GetAttribute
. getAttribute принимает пространство имен в качестве второго параметра, поэтому вы используете его неправильно. Я полагаю, вам нужно найти узел//Variables/Variable
(уже выполненный с помощьюwhile
цикла), а затем получить его атрибуты с помощьюnode.GetAttribute("Infected")
etc. Кстати, у вас есть опечатка «Varaible» в последней строке метода загрузки.2. Хм, у меня сейчас голова кругом идет кругом, поскольку я уже некоторое время пытаюсь это исправить, не могли бы вы рассказать немного подробнее о том, что мне следует изменить?
3. @elgonzo
Convert.ToDouble
будет не исключение. «Число с плавающей запятой двойной точности, эквивалентное числу в значении, или 0 (ноль), если значение равно нулю». — согласно MSDN4. @Tommi, ты прав, ToDouble не выдает ошибку, если передана
null
ссылка.. Черт возьми, по-видимому, я больше не могу читать документацию MSDN — что со мной случилось? … 🙂5. почему бы не использовать файл настроек?
Ответ №1:
Вы можете попробовать следующий код для теста.
Vars.zombies = (Convert.ToDouble(xReader.GetAttribute("Zombies")));
Vars.infected = (Convert.ToDouble(xReader.GetAttribute("Infected")));
Vars.wolfs = (Convert.ToDouble(xReader.GetAttribute("Wolfs")));
Внутри GetAttributes вам просто нужно передать имя атрибута, значение которого вы пытаетесь получить. Второй необязательный параметр принимает URI пространства имен атрибута.
Ответ №2:
Я покажу вам очень наивный подход, который подходит для нескольких переменных. Пожалуйста, подумайте о том, чтобы использовать какую-нибудь мощную функцию, например DataContractSerializer
, если вам нужно сохранить больше данных.
Прежде всего, я бы начал переходить от атрибутов к значениям, ваша текущая реализация требует более сложного поиска в файле XML.
private static void Save()
{
var xWriter = new XmlTextWriter("Save1.xml", Encoding.UTF8);
xWriter.WriteStartDocument();
xWriter.Formatting = Formatting.Indented;
xWriter.WriteStartElement("Variables");
xWriter.WriteStartElement("Zombies");
xWriter.WriteValue(Vars.zombies);
xWriter.WriteEndElement();
xWriter.WriteStartElement("Infected");
xWriter.WriteValue(Vars.infected);
xWriter.WriteEndElement();
xWriter.WriteStartElement("Wolfs");
xWriter.WriteValue(Vars.wolfs);
xWriter.WriteEndElement();
xWriter.WriteEndElement();
xWriter.Close();
}
Здесь я использовал writeValue вместо WriteAttributeString . Это дает нам xml, подобный
<?xml version="1.0" encoding="utf-8"?>
<Variables>
<Zombies>1</Zombies>
<Infected>1</Infected>
<Wolfs>1</Wolfs>
</Variables>
Теперь мы используем прямое считывание значений для получения данных:
private static void Read()
{
XmlReader xReader = XmlReader.Create("Save1.xml");
while (xReader.Read())
{
if (xReader.NodeType == XmlNodeType.Element)
{
switch (xReader.Name)
{
case "Zombies":
Vars.zombies = xReader.ReadElementContentAsDouble();
break;
case "Infected":
Vars.infected = xReader.ReadElementContentAsDouble();
break;
case "Wolfs":
Vars.wolfs = xReader.ReadElementContentAsDouble();
break;
}
}
}
}
Вот полная демонстрация:https://dotnetfiddle.net/0rQUsD