zoukankan      html  css  js  c++  java
  • C#解析XML文件

    内容提要

    1.解析Xml文件有哪些方法?各有什么优缺点?

    2.如何用XPath解析xml文档的要点。 

         

    先来看看解析xml文件的方法都有哪些吧,本段文字来自网络,可以帮助大家对这个问题有个概要的了解。

    在程序中访问并操作XML文件一般有两种模型:流模型和DOM(文档对象模型)。流模型中有两种变体——“推”模型和“拉”模型。 

     “推”模型也就是常说的SAX,SAX是一种靠事件驱动的模型。它每发现一个节点就用“推”模型引发一个事件,而我们必须编写这些事件的处理程序,很麻烦。

    .NET中使用的是基于“拉”模型的实现方案。 “拉”模型在遍历文档时会把感兴趣的文档部分从读取器中拉出,不需要引发事件,允许我们以编程的方式访问文档,这大大的提高了灵活性,“拉”模型可以选择性的处理节点。在.NET中,“拉”模型通过XML阅读器(XMLTextReader类)来实现的。该类提供Xml文件读取的功能,它可以验证文档是否格式良好,如果不是格式良好的Xml文档,该类在读取过程中将会抛出XmlException异常。任何时候在内存中只有当前节点,但它是只读的,向前的,不能在文档中执行向后导航操作。 

    DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据,可以使用XPath查询。但是,DOM的缺点在于它需要一次性的加载整个文档到内存中,对于大型的文档,这会造成资源问题。在.NET中使用XML DOM分析器(XMLDocument)实现DOM模型。

    因此,.NET Framework完全支持XML DOM模式,但它不支持SAX模式。.NET Framework支持两种不同的分析模式:XML DOM分析器(XMLDocument类)和XML阅读器(XMLTextReader类),不支持SAX分析器, 但这并不意味着它没有提供类似SAX分析器的功能。通过XML阅读器可以将SAX的所有的功能很容易的实现及更有效的运用。

    在项目中,我们选用xpath的方式来解析xml文档。这是基于以下的几点原因:

    1, 文件大小。要处理的文件不大,一般都在几百K到1M。

    2,  XPath的灵活性。不需要获取文档的全部数据,只需要获取大部分想要的数据。

    3,  学习代价低。符合一般的思维习惯,通过Path获取结果。

    通过XPath的方式解析xml文档,需要先加载文档,然后再读取想要的节点值。

    xml文档

    protected XmlDocument doc = null;

    xml文档的根元素(节点)

    protected XmlElement root = null;

     xml文档的名空间管理器 

    protected XmlNamespaceManager nsmgr = null;

    接下来就是加载文档了

     


            protected void LoadXmlFile(FileInfo xmlFile)
            {
                if (xmlFile == null || !xmlFile.Exists)
                {
                    throw new FileNotFoundException(string.Format("要解析的文件不存在{0}。",xmlFile.FullName));
                }
                //加载文件
                this.doc = new XmlDocument();
                doc.Load(xmlFile.FullName);
                //准备读取文件
                root = doc.DocumentElement;
                string nameSpace = root.NamespaceURI;
                nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("ns", nameSpace);
            }

     

    这里有几行要注意。

          这两行是取得xml文档的名空间

                root = doc.DocumentElement;
                string nameSpace = root.NamespaceURI;

          这两行是建立xml文档的名空间管理器

                nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("ns", nameSpace);

          如果你的xml文档有名空间,则这部分的代码是必不可少的。

     

       接下来就是读取文档节点的值了

          这里两个传入参数prefixPath是节点的上级节点路径,xRelativePath是要读取的节点名称。

    另外,变量XmlFileInfo是要加载的xml文件。


            protected string GetNodeValue(string prefixPath, string xRelativePath)
            {
                if (doc == null)
                {
                    LoadXmlFile(XmlFileInfo);
                }
                string xPath = string.Empty;
                if (!string.IsNullOrEmpty(xRelativePath))
                {
                    if (!string.IsNullOrEmpty(prefixPath))
                    {
                        xPath = prefixPath + xRelativePath;
                    }
                    else
                    {
                        xPath = xRelativePath;
                    }
                }
                xPath = xPath.Replace("/", "/ns:");
                XmlNode node = root.SelectSingleNode(xPath, nsmgr);
                if (node == null)
                {
                    return null;
                }
                return node.InnerXml;
            }

       可能有的朋友要问,为什么要设置两个参数prefixPath和xRelativePath呢,其实这个没有多大的关系,我只是为了自己觉得方便,你也可以在方法外确定了这个XPath,在方法中只设置一个传入参数,效果是一样的。

       注意这一行:

          xPath = xPath.Replace("/", "/ns:");

       如果你的xml文档带名空间,则这行是比不可少的,否则会出现找不到节点,无法解析的情况。

       这里还有一个不得不说的问题,就是关于XPath的。

       对 于这样一个xml文档,要查找第一个节点下的学生的Name时(ID=01),其XPath应该是"/ns:Root/ns:Students /ns:Student[1]/ns:Name"。xml对于重复的节点名称,是按照顺序1,2,3...的方式遍历的,也就是说如果要找第N个 Student节点的下的节点之,那么应使用Student[N]的标识方式。  


    <?xml version="1.0" encoding="UTF-8" ?>
    <Root xmlns="urn:ClassNameSpace">
    <Class>
    <ClassID>1234</ClassID>
    </Class>
    <Students>
    <Student>
    <ID>01</ID><Name>Name01</Name>
    </Student>
    <Student>
    <ID>02</ID><Name>Name02</Name>
    </Student>
    </Students>
    </Root>

       当然,这里也可以获取节点属性的值,查找满足特定值的节点等等,这些和上面获取节点值的过程是类似的。这里推荐一篇介绍xpath的文章XPath 教程,大家不妨看看,关于xpath的常见问题都可以得到解决。

  • 相关阅读:
    cinder支持nfs快照
    浏览器输入URL到返回页面的全过程
    按需制作最小的本地yum源
    创建可执行bin安装文件
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    惠普IPMI登陆不上
    Linux进程状态——top,ps中看到进程状态D,S,Z的含义
    openstack-neutron基本的网络类型以及分析
    openstack octavia的实现与分析(二)原理,架构与基本流程
    flask上下文流程图
  • 原文地址:https://www.cnblogs.com/ChengDong/p/2567438.html
Copyright © 2011-2022 走看看