• XML系列之--解析电文格式的XML(二)


          上一节介绍了XML的结构以及如何创建。讲到了XML可作为一种简单文本存储数据,把数据存储起来,以XML的方式进行传递。当接收到XML时,必不可少的就是对其进行解析,捞取有效数据,或者将第三方数据以节点的形式填充至此XML。无论如何,都离不开对XML的解析,XML有一般的,同样也有二般的,这一节就来介绍如何对这些XML进行解析。

    1. 普通XML

    <?xml version="1.0" encoding="utf-8"?>
      <Sudent>
        <StudentID>0000</StatusCode>
        <StudentName>張三</StatusDesc>
      </Sudent>
      <StudentTec>魏老師</StudentTec>

    对于一般的XML,只需要读取加载,然后遍历就可以获取某个标签对的值,遍历的方法有很多

      #region 遍历基本的XML
       XElement root = XElement.Load(@"D:	est.xml");         
       //根據Elements 遍歷
        foreach (XElement item in root.Elements("StudentID"))
         {
            Console.WriteLine(item);
         }
       //根據Lambda 遍歷
          var query = root.Elements().Select(u => u);
          foreach (var q in query)
          {
            Console.WriteLine(q);
          }
        //根據Nodes 遍歷
          foreach (var item in root.Nodes())
          {
             if (item.NextNode.ToString() == "StudentName")
               {
                 Console.WriteLine(item.Document);
               }
                 Console.WriteLine(item);
          } 
     #endregion

    2.  实际在项目中,往往需要操作较为复杂的XML。像带命名空间的且为 soap格式的XML,如A

    <?xml version="1.0" encoding="UTF-8"?>
    <ns0:Envelope xmlns:x0="http://www.w3school.com.cn/Envelope" 
    xmlns:x1="http://www.w3school.com.cn/Header" >
      <x1:Header>
        <x1:Type>ICC</x1:dType>
        <x1:Version>01</x1:Version>
      </x1:Header>
      <x2:Body 
         xmlns:x2="http://www.w3school.com.cn/Body" 
         xmlns:x3="http://www.w3school.com.cn/IBBC/01" 
         xmlns:x4="http://www.w3school.com.cn/ICCB/01">
        <x3:SecondInform>
          <x4:Status>
            <x4:StatusCode>0000</x4:StatusCode>
          </x4:Status>        
        </x3:SecondInform>
      </x2:Body>
    </x0:Envelope>

    所谓soap格式,就是含有Envelope、Header、Body的标签对,如上,一般body和header之间还存在子命名空间,不管怎么写的繁琐,思路和2中一样,读取其中某个标签对中的值,带上其对应的命名空间即可。

    或者如这中层级结构明显的XML,如B

    <?xml version="1.0" encoding="utf-8"?>
    <x0:Envelope xmlns:x0="http://www.w3school.com.cn/Envelope">
      <x1:Header xmlns:x1="http://www.w3school.com.cn/Header">
        <x1:Type>ICC</x1:dType>
        <x1:Version>01</x1:Version>
      </x1:Header>
      <x1:Body xmlns:x1="http://www.w3school.com.cn/Body">
        <x2:IBBC xmlns:x2="http://ns.chinatrust.com.tw/XSD/CTCB/BC/Message/IBBC/01">
           <x2:SecondInform>
          <x2:Status>
            <x2:StatusCode>0000</x4:StatusCode>
          </x2:Status>        
        </x2:SecondInform>
      </x1:Body>
    </x0:Envelope>

    不管是A还是B,对于常规的解析方案,即DOM 解析,获取指定标签值: 命名空间+标签对

    public string ReadXMl(string xmlurl) 
    {           
     XmlDocument xml = new XmlDocument();
     xml.Load(xmlurl);        
     var xmlnsm = new XmlNamespaceManager(xml.NameTable);
     xmlnsm.AddNamespace("x0", @"http://www.w3school.com.cn/Envelope");
     xmlnsm.AddNamespace("x2", @"http://www.w3school.com.cn/Body");
     xmlnsm.AddNamespace("x3", @"http://www.w3school.com.cn/IBBC/01");
     xmlnsm.AddNamespace("x4", @"http://www.w3school.com.cn/ICCB/01");
     
     //对A中元素取值
     string laa = xml.SelectSingleNode("x0:Envelope/x2:Body/x3:SecondInform/x4:Status/x4:StatusCode", xmlnsm).InnerText; 
     //对B中元素取值
     string lab = xml.SelectSingleNode("x0:Envelope/x2:Body/x2:IBBC/x2:SecondInform/x2:Status/x2:StatusCode", xmlnsm).InnerText;
    
    //修改XML中的值 
    //xelement.SetAttributeValue(namespacehaif + Labelname, "50000"); // xml.Save(xmlurl); 
     return lab; 
     }

    上面是常規的解析XML的方法,如果我们要获取XML中所有标签的属性值,就需要加载XML中所有的标签对,也就是说,我们需要写N个类似于

    "x0:Envelope/x2:Body/x2:IBBC/x2:SecondInform/x2:Status/x2:StatusCode" 的指定属性值所有的前缀层级。有没有其他解决方法呢?其实还有一种方法,用Linq的思想。

    如下,选择Linq to xml 

    public string ReadXMl(string xmlurl) 
    {           
     XElement xml = XElement.Load(xmlpath);        
     XNamespace x0 = @"http://www.w3school.com.cn/Envelope"; 
     XNamespace x2 = @"http://www.w3school.com.cn/Body";
     XNamespace x3 = @"http://www.w3school.com.cn/IBBC/01";
     XNamespace x4 = @"http://www.w3school.com.cn/ICCB/01";
     
     //对A中元素取值
     string laa = xml.Descendants(x4+"StatusCode").FirstOrDefault().Value.ToString(); 
     //对B中元素取值
     string lab = xml.Descendants(x2+"StatusCode").FirstOrDefault().Value.ToString(); 
    
     return lab; 
     }

    可以得知,当用Linq解析XML的时候,用的同样是 命名空间+指定标签 的思想,但是不需要指定目的标签层级之前的所有前缀,相对来说简洁不少,其实Linq的功能是非常强大的,个人推荐,当需要其数个标签对的属性值时,一般的处理方式是,写一个Dictionnay<string,string>, 采取键值对的方式将XML的属性名和属性值进行存储,当需要某个值时,只需要New一个对象带入键名,便可得到其对应的属性值。

    XML系列之--创建电文格式的XML(一)

    XML系列之--解析电文格式的XML(二)

    XML系列之--对电文格式XML的简单操作(三)

    XML系列之--Linq操作带属性的XML(四)

  • 相关阅读:
    给入门程序员的一些学习建议(一定要看)
    拦截器工作原理
    Struts 2中如何解决中文乱码问题?
    struts1与struts2的区别。
    MVC是什么?
    spring MVC工作原理
    C#中,子类构造函数调用父类父类构造函数的正确方式
    泛型的优点
    jsp的page、request、session、application四个作用域的作用
    jsp转发与重定向的区别
  • 原文地址:https://www.cnblogs.com/Sientuo/p/6022939.html
Copyright © 2020-2023  润新知