C# XmlReader:从起始元素读取属性

3
我将尝试保存游戏状态到一个xml文件中,以便在玩家重新加载游戏时,可以恢复上一次的游戏状态。我对xml不太熟悉,但是我成功地使用了XmlWriter将游戏状态存储到了xml文件中。问题出现在我尝试读取这个文件时。以下是由我的程序创建的文件开头:
<?xml version="1.0" encoding="utf-16"?>
<level width="25" height="25">
  <count>0</count>
  <row>
    <tile type="ROOM" />
    <tile type="ROOM" />
    <tile type="ROOM" />
    <tile type="ROOM" />
    <tile type="ROOM" />
    <!-- More tiles and rows are defined, but the file is somewhat large to entirely copy-paste here-->

元素在文件末尾关闭,这是应该的。 现在我尝试使用XmlReader对象从该文件中读取数据:

public void LoadFromFile()
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.IgnoreWhitespace = true;
        settings.IgnoreComments = true;

        using(XmlReader reader = XmlReader.Create(new StreamReader("Content/Saves/SaveFile.xml", Encoding.UTF8), settings))
        {
            reader.MoveToContent();
            reader.ReadStartElement("level");
            reader.MoveToAttribute("width");
            int w = int.Parse(reader.Value);
            reader.MoveToNextAttribute();
            int h = int.Parse(reader.Value);
            // More to be read when I understand this first part.
        }
    }

我不断遇到的异常是width属性的值要么为null,要么格式错误。
1:之前我没有使用reader.MoveToContent()方法,当我执行reader.ReadStartElement()时发现读取器没有读取到“level”。读取器没有值。2:添加了reader.MoveToContent()方法后,它确实找到了level元素。但是,当我使用reader.GetAttribute("width")时,我并没有获得width属性,而是一个空格。因此,3:我添加了settings.IgnoreWhitespace = true。现在我不再得到空格,但得到了更奇怪的结果。我没有读取“width”属性,而是“count”元素。
下面是每个点在上一段中读取器拥有的值(从Visual Studio调试窗口中读取):
1:{无}
2:{空格,Value=”\n ”}
3:{元素,Value=”count”}
我期望点3将给我类似这样的值:{属性,Value=”width”}或类似的内容。
为什么读取器没有读取属性,却读取了下一个元素?能否给我一个易于理解的分步示例,说明如何从xml文件中读取属性和内容?
由于我没有足够的时间来学习XML的所有概念,所以我尽可能地保持简单。当我阅读节点和节点读取器的相关定义时感到非常困惑,因此如果可能的话,我希望避免它们。只是属性、元素和内容。

1
除非您的 XML 文件非常庞大(多个 MB),否则您会发现使用 LINQ to XML 或 XmlSerializer 会更容易进行 XML 反序列化。对于后者,您可以上传您的 XML 到 http://xmltocsharp.azurewebsites.net/ 并让它为您生成 C# 类。 - dbc
我通常将数据放入 DataTable 中,这样使用 ReadXML() 和 WriteXML() 方法读写数据就变得非常简单。 - jdweng
1个回答

3
在执行reader.ReadStartElement("level")之后,你的读取器会移动到“level”之后的下一个元素,“count”,该元素没有预期的属性。(请参阅文档:https://msdn.microsoft.com/library/y7e4769a(v=vs.110).aspx)如果你想以这种方式进行序列化,请删除此行:
using(XmlReader reader = XmlReader.Create(new StreamReader("Content/Saves/SaveFile.xml", Encoding.UTF8), settings))
{
    reader.MoveToContent();
    reader.MoveToAttribute("width");
    int w = int.Parse(reader.Value);
    reader.MoveToNextAttribute();
    int h = int.Parse(reader.Value);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接