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

摘要:
上一节描述了XML的结构以及如何创建它。其中提到,XML可以作为一个简单的文本来存储数据、存储数据并以XML形式传输数据。在接收XML时,必须对其进行解析,检索有效数据,或者以节点的形式将第三方数据填充到该XML中。无论如何,XML不能与解析分离。XML有通用类型和不同类型。本节介绍如何解析这些XML。带有名称空间和soap格式的XML,例如A˂?

      上一节介绍了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(四)

免责声明:文章转载自《XML系列之--解析电文格式的XML(二)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Web DNS 实战List拆分成多个集合下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

主题:android之XmlResourceParser类使用实例 转

http://www.iteye.com/topic/1122056 android开发过程会经常使用XML文件,下面提供小实例,看看XmlResourceParser类是怎么样解析XML文件的。 XML文件名称为test.xml。内容如下: Xml代码 <?xmlversion="1.0"encoding="utf-8"?> <...

Gradle里配置jetty实现静态资源的热部署

通过Gradle我们可以很方便的使用内置jetty启动我们的web程序,在本地进行调试。但是在使用的过程中,我发现了几个问题,导致本地调试的效率大受影响。 如果使用gradle jettyRun启动jetty服务器后,项目里的静态资源(jsp,html,JavaScript文件)都被锁定了,导致无法实时修改这些静态资源。 既然无法实时修改这些静态资源,...

玩转Spring Boot 自定义配置、导入XML配置与外部化配置

玩转Spring Boot 自定义配置、导入XML配置与外部化配置       在这里我会全面介绍在Spring Boot里面如何自定义配置,更改Spring Boot默认的配置,以及介绍各配置的优先级顺序。Spring Boot使用一个全局的配置文件application.properties,Spring Boot 支持使用YAML语言的配置文件,...

Mybatis中接口和对应的mapper文件位置配置深入剖析

首先要说明的问题是,Mybatis中接口和对应的mapper文件不一定要放在同一个包下,放在一起的目的是为了Mybatis进行自动扫描,并且要注意此时java接口的名称和mapper文件的名称要相同,否则会报异常,由于此时Mybatis会自动解析对应的接口和相应的配置文件,所以就不需要配置mapper文件的位置了。 1. 接口和文件在同一个包中 1.1...

jquery中ajax的dataType属性包括哪几项

参考ajax api文档:http://www.w3school.com.cn/jquery/ajax_ajax.aspdataType类型:String预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML。在 1.4 中,JSON 就会生成一个 JavaSc...

C# 序列化与反序列化之xml通过实现IXmlSerializable进行序列化的解决方案

新建控制台console项目,添加XmlPersonIXmlSerializable类,和AddressIXmlSerializable类(实现IXmlSerializable)以及AddressIXmlSerializable子类USAddressIXmlSerializable 代码如下: using System; using System.Col...