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