文章出處

      上一節介紹了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:\test.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一個對象帶入鍵名,便可得到其對應的屬性值。

 

權當學習筆記

世人皆大笑,舉手揶揄之 

                                郎中令

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()