【问题标题】:None of the XML parsing methods work for meXML 解析方法都不适合我
【发布时间】: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 中提取什么信息?我可以指导你或帮助你如何进行。

标签: c# xml parsing xpath


【解决方案1】:

好的,我已经用@Corak提供的方法了:

XDocument Document = XDocument.Load("Cards.xml");
var xns = XNamespace.Get("http://tempuri.org/CardSchema.xsd");
var Elements = Document.Root.Elements(xns + "Card");
foreach (var Card in Elements)
{
    // Process card information here

    foreach (var item in Card.Elements())
    {
        Console.WriteLine("{0}: {1}", item.Name.ToString(), item.Value);
    }
}

Console.ReadKey();

这将为我提供我需要的文件中的所有信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2020-08-27
    • 2018-01-17
    相关资源
    最近更新 更多