This article is currently in the process of being translated into Chinese (~53% done).
Reading XML with the XmlDocument class
如上一章节所述,使用XmlDocument会花费更多内存,并且有可能比使用XmlReader更慢。然而在很多情况下,XmlDocument会更加易于使用,且需要更少的代码。当XML内容被读取,你就能以层级递进的方式去读取数据,就像XML本身的结构那样,一个根节点可以有多个子节点,子节点下还可以有子节点,如此递进。在之前的章节中,我们解析了来自欧洲中央银行的一段XML数据来得到当前的汇率,现在我们将使用XmlDocument来做相同的事情。
我们使用的XML数据可以通过这个URL找到(http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml)我们需要的数据存在于<cube> 节点中。如果使用一个树状结构来描述,它看起来会是这样:
<gesmes:Envelope>
[other child nodes]
<Cube>
<Cube time="2011-04-12">
<Cube currency="USD" rate="1.4470"/>
<Cube currency="JPY" rate="121.87"/>
…
gesmes:Envelope 是根节点,我们可以通过DocumentElement属性来访问它。然后我们就可以使用ChildNodes属性来访问它的子节点集合。在本例中,我们要获取比根节点低三个层级的子节点。我们可以通过如下代码来实现,它和上一章节中我们使用XmlReader所做的事情基本一样。
using System;
using System.Text;
using System.Xml;
namespace ParsingXml
{
class Program
{
static void Main(string[] args)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml");
foreach(XmlNode xmlNode in xmlDoc.DocumentElement.ChildNodes[2].ChildNodes[0].ChildNodes)
Console.WriteLine(xmlNode.Attributes["currency"].Value + ": " + xmlNode.Attributes["rate"].Value);
Console.ReadKey();
}
}
}
如你所见,我们通过逐级向下的方式获取了Cube节点。从DocumentElement(根节点)开始,我们首先取得了它的第三个子节点(下标从零开始),之后我们又获取了该子节点的第一个子节点,然后我们对当前子节点取了它所有子节点的集合。显然,只有当我们知道XML的具体结构我们才能采取这样的操作,并且当面临修改的时候这种方式既不灵活也不优雅。不过,你读取XML文档的方式很大程度取决于XML数据源和你需要取得的数据。在本例中,上述代码完全可以胜任工作,并且仅需几行代码,但在某些情况下,你也许需要使用更多的代码来增加可读性。
一旦我们获取了包含汇率数据的节点,我们就可以访问需要的2个属性并输出到控制台,这和之前章节中的例子是一样的。