C#中的XML - hasAttribute,getAttribute不存在?为什么?

时间:2012-12-11 19:52:19

标签: c# xml parsing

我正在开展一个项目,要求我在一个单独的数据库中构建游戏的房间,物品和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;
            }

        }
    }

3 个答案:

答案 0 :(得分:6)

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

xmlElement = (System.Xml.XmlElement)xmlRoom;

答案 1 :(得分: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节点),没有属性的节点对象的整个问题被巧妙地回避了。

答案 2 :(得分: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