zoukankan      html  css  js  c++  java
  • xml 文件解析方法

    转载自:http://www.cnblogs.com/zhangyf/archive/2009/06/03/1495459.html

    内容提要

    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;

    接下来就是加载文档了

    View Code
     1 protected void LoadXmlFile(FileInfo xmlFile)
     2         {
     3             if (xmlFile == null || !xmlFile.Exists)
     4             {
     5                 throw new FileNotFoundException(string.Format("要解析的文件不存在{0}。",xmlFile.FullName));
     6             }
     7             //加载文件
     8             this.doc = new XmlDocument();
     9             doc.Load(xmlFile.FullName);
    10             //准备读取文件
    11             root = doc.DocumentElement;
    12             string nameSpace = root.NamespaceURI;
    13             nsmgr = new XmlNamespaceManager(doc.NameTable);
    14             nsmgr.AddNamespace("ns", nameSpace);
    15         }

    这里有几行要注意。

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

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

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

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

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

     

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

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

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

    View Code
     1 protected string GetNodeValue(string prefixPath, string xRelativePath)
     2         {
     3             if (doc == null)
     4             {
     5                 LoadXmlFile(XmlFileInfo);
     6             }
     7             string xPath = string.Empty;
     8             if (!string.IsNullOrEmpty(xRelativePath))
     9             {
    10                 if (!string.IsNullOrEmpty(prefixPath))
    11                 {
    12                     xPath = prefixPath + xRelativePath;
    13                 }
    14                 else
    15                 {
    16                     xPath = xRelativePath;
    17                 }
    18             }
    19             xPath = xPath.Replace("/", "/ns:");
    20             XmlNode node = root.SelectSingleNode(xPath, nsmgr);
    21             if (node == null)
    22             {
    23                 return null;
    24             }
    25             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]的标识方式。  

    View Code
     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <Root xmlns="urn:ClassNameSpace">
     3 <Class>
     4 <ClassID>1234</ClassID>
     5 </Class>
     6 <Students>
     7 <Student>
     8 <ID>01</ID><Name>Name01</Name>
     9 </Student>
    10 <Student>
    11 <ID>02</ID><Name>Name02</Name>
    12 </Student>
    13 </Students>
    14 </Root>

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

  • 相关阅读:
    彻底弄懂三段式状态机
    关于verilog的有符号数与无符号数的转换
    关于win10系统安装vivado 2017.1 .2 .3 报runtime error 问题解决办法 亲测有效
    python的列表拷贝
    PYTHON
    保存linux下当前目录下所有文件的相对路径
    Git 命令及使用经验
    讯飞SDK的使用
    DE4加DVI子板实现静态图片显示
    HDL代码风格建议(2)乘法器和DSP推断
  • 原文地址:https://www.cnblogs.com/daidaigua/p/2511998.html
Copyright © 2011-2022 走看看