【发布时间】:2015-08-24 08:38:17
【问题描述】:
我在业余时间一直在做一个愚蠢的小纸牌游戏,并决定使用 XML 来存储卡片信息,因为我最近完成了一个 XML 类。
问题是,课堂上使用的方法突然似乎不再起作用,我在这里看到的替代方法也不起作用。他们都没有抛出异常,他们都可以看到文件,但拒绝从中提取任何东西。
XDocument、XmlDocument 和 XPathDocument 看到文件就好了,所以问题不存在。但是,XPathNavigator.Select() 和 XDocument.XPathSelectElements() 什么都不返回。
我当前的 Cards.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Cards xmlns="http://tempuri.org/CardSchema.xsd">
<Card>
<Name>Emperor Heavy Tank</Name>
<Type>Attack</Type>
<Colour>Red</Colour>
<Distinctions>
<Distinction>Weapon</Distinction>
<Distinction>Machine</Distinction>
</Distinctions>
<Health>25</Health>
<Power>12</Power>
<Ability>
<Name>Repair Crew</Name>
<Description>Heal for 4 HP, and apply 2 armour on the card if it is lacking. Increase turn wait for both skills by 1.</Description>
<PowerUse>1</PowerUse>
<TurnWait>1</TurnWait>
</Ability>
<Ability>
<Name>High Caliber</Name>
<Description>Deals 6 dmg to target, +2 if target is a Machine. If any adjacent cards are of the same colour, they recieve 3 spill damage, 1 otherwise. 4 turn wait.</Description>
<PowerUse>5</PowerUse>
<TurnWait>4</TurnWait>
</Ability>
</Card>
<Card>
<Name>Flamethrower</Name>
<Type>Attack</Type>
<Colour>Red</Colour>
<Distinctions>
<Distinction>Machine</Distinction>
<Distinction>Weapon</Distinction>
</Distinctions>
<Health>13</Health>
<Power>20</Power>
<Ability>
<Name>Roar of the Wheels</Name>
<Description>All player ATK cards (besides Flamethrower) recieve +1 POW if the enemy doesn't have a red card in play. 1 turn wait.</Description>
<PowerUse>2</PowerUse>
<TurnWait>1</TurnWait>
</Ability>
<Ability>
<Name>Flame Artillery</Name>
<Description>Deals 7 dmg to non-red target. If target is red, deals 3 dmg, and does 2 dmg to both adjacent cards. 3 turn wait.</Description>
<PowerUse>5</PowerUse>
<TurnWait>3</TurnWait>
</Ability>
</Card>
</Cards>
尝试 #1:
XmlDocument Document = new XmlDocument();
Document.Load("Cards.xml");
var Navigator = Document.CreateNavigator();
var Expression = Navigator.Compile("/Cards/Card");
var Iterator = Navigator.Select(Expression);
while (Iterator.MoveNext()) // nothing to iterate through, so it just skips to the next statement immediately
{
var HelpNavigator = Iterator.Current.Clone();
Console.WriteLine(HelpNavigator.Value);
}
Console.ReadKey();
尝试 #2:
XPathDocument Document = new XPathDocument("Cards.xml");
var Navigator = Document.CreateNavigator();
var Expression = XPathExpression.Compile("//Card/*");
var Iterator = Navigator.Select(Expression);
do
{
var InnerIterator = Iterator.Current.SelectChildren(XPathNodeType.Text);
do
{
Console.WriteLine(InnerIterator.Current.Value);
} while (InnerIterator.MoveNext());
} while (Iterator.MoveNext());
Console.ReadKey();
尝试 #3:
XDocument Document = XDocument.Load("Cards.xml");
var Elements = Document.XPathSelectElements("//Card/child::*");
foreach (var item in Elements) // and again, nothing
{
Console.WriteLine("{0}: {1}", item.Name.ToString(), item.Value);
}
Console.ReadKey();
我什至轮换了一些 XPath 样式,以防万一 - 但它们应该都实现相同的目标。
【问题讨论】:
-
您在所有尝试中都忽略了 xml 命名空间
http://tempuri.org/CardSchema.xsd:) -
我确实尝试使用 XmlNamespaceManager 每次都将“tempuri.org/CardSchema.xsd”或“tempuri.org”添加到文档中,但这并没有什么不同。而且我们还在 XML 类中使用了模式,但命名空间从来都不是我们必须处理的事情。
-
在您的
XDocument示例(尝试#3)中,添加var xns = XNamespace.Get("http://tempuri.org/CardSchema.xsd");,然后使用var cardElements = Document.Root.Elements(xns + "Card");读取卡片,然后从那里开始。 -
我已经使用过很多 XML,我不建议您使用 Navigator,除非您有特定的理由这样做。如果您的 XML 文件包含 cmets,导航器有时也会出现问题。而是使用 XElement,我发现它是解析 XML 中最好的之一。您希望从此 XML 中提取什么信息?我可以指导你或帮助你如何进行。