5

我正在做一个项目,该项目需要我在单独的数据库中构建游戏的房间、物品和 NPC。我选择了 XML,但有些东西阻止了我在 C# 代码中正确解析 XML。我究竟做错了什么?

我的错误是:

System.xml.xmlnode does not contain a definition for HasAttribute 

(这GetAttribute也适用)并且没有扩展方法接受'HasAttribute'接受类型的第一个参数System.Xml.XmlNode

这也适用GetParentNode,我的最后一行

string isMoveableStr = xmlRoom.GetAttribute("isMoveable");

不知何故:

the name xmlRoom does not exist in the current context

这是方法:

public void loadFromFile()
    {
        XmlDocument xmlDoc = new XmlDocument();              // create an xml document object in memory.
        xmlDoc.Load("gamedata.xml");                         // load the XML document from the specified file into the object in memory.

        // Get rooms, NPCs, and items.
        XmlNodeList xmlRooms = xmlDoc.GetElementsByTagName("room");
        XmlNodeList xmlNPCs = xmlDoc.GetElementsByTagName("npc");
        XmlNodeList xmlItems = xmlDoc.GetElementsByTagName("item");

        foreach(XmlNode xmlRoom in xmlRooms) {               // defaults for room:

        string roomID = ""; 
        string roomDescription = "this a standard room, nothing special about it.";                  

        if( !xmlRoom.HasAttribute("ID") )                   //http://msdn.microsoft.com/en-us/library/acwfyhc7.aspx
        {              
        Console.WriteLine("A room was in the xml file without an ID attribute. Correct this to use the room"); 
        continue;                                       //skips remaining code in loop 

            } else {
             roomID = xmlRoom.GetAttribute("id");           //http://msdn.microsoft.com/en-us/library/acwfyhc7.aspx
            }

        if( xmlRoom.hasAttribute("description") )              
        {
            roomDescription = xmlRoom.GetAttribute("description");
        }

        Room myRoom = new Room(roomDescription, roomID); //creates a room
        rooms.Add(myRoom); //adds to list with all rooms in game ;)

            } foreach(XmlNode xmlNPC in xmlNPCs)
            { bool isMoveable = false;

        if( !xmlNPC.hasAttribute("id") )
        {
            Console.WriteLine("A NPC was in the xml file, without an id attribute, correct this to spawn the npc");
            continue; //skips remaining code in loop
        }

        XmlNode inRoom = xmlNPC.getParentNode();
        string roomID = inRoom.GetAttribute("id");

        if( xmlNPC.hasAttribute("isMoveable") )
        {
            string isMoveableStr = xmlRoom.GetAttribute("isMoveable");
            if( isMoveableStr == "true" )
            isMoveable = true;
            }

        }
    }
4

3 回答 3

6

System.Xml.XmlElement 具有您正在寻找的功能。您正在获取 XMLNode。您需要将节点强制转换为 XmlElement 才能获得该功能。

xmlElement = (System.Xml.XmlElement)xmlRoom;
于 2012-12-11T20:00:53.710 回答
2

这与您的问题并没有特别密切的关系,而是对@ChaosPandion 的建议和您在评论中的问题的回应,这是您使用 Linq to XML 的代码示例:

var xdoc = XDocument.Load("gamedata.xml");
var xRooms = xdoc.Descendants("room");
List<Room> rooms;

//If an element doesn't have a given attribute, the Attribute method will return null for that attribute
//Here we first check if any rooms are missing the ID attribute
if (xRooms.Any( xRoom => (string)xRoom.Attribute("ID") == null )) {
    Console.WriteLine("A room was in the xml file without an ID attribute...");
} else {
    rooms = (
        from xRoom in xRooms
        select new Room(
            xRoom.Attribute("description") ?? "this a standard room, nothing special about it.",
            (int)xRoom.Attribute("ID")
        )
    ).ToList();
}

var xNPCs = xdoc.Descendants("npc");
if (xNPCs.Any( xNPC => (string)xNPC.Attribute("id") == null )) {
    Console.WriteLine("A NPC was in the xml file, without an id attribute, correct this to spawn the npc");
} else {
    var npcs = (
        from xNPC in xNPCs
        let inRoom = xNPC.Parent
        select new {
            xNPC,
            inRoom,
            isMoveable = (string)xNPC.Attribute("isMoveable") != null &&
                         (string)inRoom.Attribute("isMoveable") == true
        }
    ).ToList();
}

foreach然后你可以在npcs集合上使用一个简单的:

foreach (var npc in npcs) {
    Console.WriteLine(inRoom.Attribute("ID"));
    Console.WriteLine(npc.IsMoveable);
}

OTOH,因为此代码使用该Descendants方法,该方法返回XElement(对应于 XML 元素的类型)而不是XNode(对应于 XML 节点的类型)的集合,所以节点对象没有属性的整个问题被巧妙地回避了.

于 2012-12-11T21:32:59.793 回答
1

XmlNode 没有方法 HasAttribute 或 GetAttribute。如果您查看 XmlNode 的 MSDN 条目,您会看到它可用的方法。

http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.aspx

如果您使用 XmlNode.Attributes["ATTRIBUTE_NAME"] 或在您的情况下使用 xmlRoom.Attributes["ID"],您应该能够找到您正在寻找的属性。也就是说,如果您想继续使用 XmlNodes。

以下链接有一个示例,说明如何从 XmlNode 中按名称检索属性:http: //msdn.microsoft.com/en-us/library/1b823yx9.aspx

于 2012-12-11T19:59:43.060 回答