码迷,mamicode.com
首页 > Windows程序 > 详细

C#操作XML(一)

时间:2015-06-15 12:31:43      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:

一、使用XML DOM的方式读取XML

本节要点:

  • 加载XML的几种方式
  • 读取没有Namespace的XML
  • 使用XPath进行过滤,选出需要的节点
  • 读取有Namespace的XML

XML DOM方式是最原始的一种操作XML的途径,从.Net Framework 1.0开始就开始支持DOM方式。

1. 如何用XML DOM的方式读取XML?

  要读取XML首先要加载XML,加载的方式有两种,一种是从流或类似Reader加载,另一种就是加载字符串。

  a. 从流或者Reader加载,Load方法有五个重载

XmlDocument doc = new XmlDocument();

doc.Load("D:\\Test.xml");
using (FileStream stream = File.OpenRead("D:\\Test.xml"))
{
      doc.Load(stream);
}
using (TextReader reader = File.OpenText("D:\\Test.xml"))
{
      doc.Load(reader);
}
using (XmlReader reader = XmlReader.Create("D:\\Test.xml"))
{
      doc.Load(reader);
}

  b. 从字符串加载

XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<?xml version=""1.0"" encoding=""UTf-16""?>
<data>
    <item>abc</item>
    <item>123</item>
    <item>vwxyzh</item>
</data>");

2. 读取无namespace的XML

  XML已经准备好,下面就开始读取这个XML。

  a. 现在希望读取data节下面所有item的text:  

foreach (XmlElement item in doc.ChildNodes[1].ChildNodes)
{
    Console.WriteLine(item.InnerText);
}

  结果:

  abc

  123

  vwxyzh

  b. 使用XPath进行过滤

     上面的写法问题有很多,例如在data节点中有非item的节点,这样访问,也就被无差别的把非item项也写出来了。

     例如:  

<?xml version="1.0" encoding="UTf-8"?>
<data>
    <item>abc</item>
    <item>123</item>
    <other>!@#</other>
    <item>vwxyzh</item>
</data>

    结果:

    abc

    123

    !@#

    vwxyzh

    显然"!@#"也被选择出来了,这不是我们所希望的,所以,改用XPath的方式访问:

foreach (XmlElement item in doc.SelectNodes("/data/item"))
{
    Console.WriteLine(item.InnerText);
}

    结果:other项被排除在外了

    abc 

    123

    vwxyzh

3. 读取有namespace的XML

  和C#一样XML也有namespace,并且namespace在XML中的作用巨大。

  我们先来加载一个XML片段:

doc.LoadXml(@"<?xml version="1.0" encoding="UTf-8"?>
<v:data xmlns:v="urn:vwxyzh">
    <v:item>abc</v:item>
    <v:item>123</v:item>
    <v:other>!@#</v:other>
    <v:item>vwxyzh</v:item>
    <v:item>2009/10/18</v:item>
</v:data>");

  这里我们准备了一个namespace—urn:vwxyzh,并缩写为v。

  现在按照原来的XPath执行以下程序,会发现没有任何一个元素被选中。为什么会这样?

  因为原来的"/data/item"中的data节是没有namespace的data,所以这个XPath根本定位不到任何节点。

  必须要修改部分代码才能达到我们的目的,怎么办呢?

  a. 先来看看SelectNodes方法有哪些重载吧:      

public XmlNodeList SelectNodes(string xpath);
public XmlNodeList SelectNodes(string xpath, XmlNamespaceManager nsmgr);

     第一个重载就是之前使用的那个;

     第二个重载,需要提供一个XmlNamespaceManager实例,一看名字就知道,这个实例是用来管理Xml的Namespace的。

   b. 再来查看一下XmlNamespaceManager这个类,可以发现创建这个实例需要一个类型为XmlNameTable的实例做参数,那么谁能提供XmlNameTable的实例呢?

技术分享

  c. XmlDocument本身就提供了这个XmlNameTable:

技术分享

  d. 修改代码:  

XmlNamespaceManager xnmgr = new XmlNamespaceManager(doc.NameTable);
xnmgr.AddNamespace("v", "urn:vwxyzh");
foreach (XmlElement item in doc.SelectNodes("/v:data/v:item", xnmgr))
{
    Console.WriteLine(item.InnerText);
}

    先创建一个XmlNamespaceManager的实例,然后使用AddNamespace方法,把"v"设置为"urn:vwxyzh"。然后修改XPath,把dat修改为v:data,item修改为v:item,这样就可以了。

     运行就可以看到结果为:

   abc

   123

         vwxyzh

   2009/10/18

      

C#操作XML(一)

标签:

原文地址:http://www.cnblogs.com/sunshineground/p/4576538.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!