<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ToddLin

      路漫漫其修遠(yuǎn)

      博客園 首頁(yè) 新隨筆 聯(lián)系 訂閱 管理

      本文首次發(fā)表在博客[C#之XML反序列化的一些坑]

      背景

      我們?cè)?net平臺(tái)反序列化一份xml文檔的時(shí)候經(jīng)常性的會(huì)遇到一些很奇怪的問(wèn)題,要么在反序列化過(guò)程中拋出各種異常,要么沒(méi)有發(fā)生異常,可結(jié)果卻不是我們想要的。拋異常的情況倒是比較容易解決,根據(jù)異常信息自己找MSDN文檔或者Google搜索,一般都能找到解決辦法。麻煩的是沒(méi)有異常結(jié)果卻不理想的情況,這種情況往往需要一步步調(diào)試跟蹤代碼,但是微軟的底層已經(jīng)封裝,調(diào)試起來(lái)很困難。

      下面是我在反序列化的時(shí)候遇到過(guò)的一些坑。先上一段需要反序列化的代碼。

      目標(biāo)XML
      <?xml version='1.0' encoding='UTF-8'?>
      <soapenv:Envelope
          xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
          <soapenv:Body>
              <xsd:DestinationListResponse
                  xmlns:xsd="http://response.example.com/xsd">
                  <xsd:success>true</xsd:success>
                  <xsd:country xsd1:id="1933312" xsd1:name="Afghanistan" xsd1:nameEn="Afghanistan" xsd:isoCode="AF"
                      xmlns:xsd1="http://types.example.com/xsd">
                      <xsd:city xsd1:id="1934162" xsd1:name="Kabul" xsd1:nameEn="Kabul" xsd:isoCode="KBL" xsd:latitude="34.53333282470703" xsd:longitude="69.16666412353516"/>
                  </xsd:country>
                  <xsd:country xsd1:id="1933313" xsd1:name="Albania" xsd1:nameEn="Albania" xsd:isoCode="AL"
                      xmlns:xsd1="http://types.example.com/xsd">
                      <xsd:city xsd1:id="31959649" xsd1:name="Durres" xsd1:nameEn="Durres" xsd:isoCode="TIA" xsd:latitude="41.31666564941406" xsd:longitude="19.450000762939453"/>
                      <xsd:city xsd1:id="50001732" xsd1:name="Pogradec" xsd1:nameEn="Pogradec" xsd:isoCode="" xsd:latitude="40.900001525878906" xsd:longitude="20.649999618530273"/>
                  </xsd:country>
              </xsd:DestinationListResponse>
          </soapenv:Body>
      </soapenv:Envelope>
      

      這一段XML,相信大家都能看懂。這里涉及到幾個(gè)XML的概念如下:聲明、名稱(chēng)空間、前綴、元素、屬性。對(duì)這幾個(gè)概念不了解的自行Google。了解這幾個(gè)概念之后,構(gòu)建C#實(shí)體類(lèi)就很簡(jiǎn)單了,復(fù)雜元素構(gòu)建成類(lèi),簡(jiǎn)單元素和屬性作為類(lèi)的字段。我創(chuàng)建了對(duì)應(yīng)的實(shí)體類(lèi)之后開(kāi)始反序列化就遇到了一些問(wèn)題。

      一、獲取SOAP中Body里的內(nèi)容報(bào)錯(cuò)或者為空

      我這里需要獲取DestinationListResponse元素反序列化成我建的對(duì)應(yīng)的C#實(shí)體DestinationListResponse類(lèi)的對(duì)象。代碼如下:
      XmlDocument doc = new XmlDocument();
      doc.LoadXml(xml);
      var node = doc.SelectSingleNode("http://Body");
      var innerXml = node.InnerXml;

      這樣沒(méi)有報(bào)錯(cuò),但是獲取到node的值=null。然后我把var node = doc.SelectSingleNode("http://Body");這句代碼改成var node = doc.SelectSingleNode("http://soapenv:Body");之后再調(diào)試。這句代碼直接就拋出異常了,提示類(lèi)似缺少名稱(chēng)空間之類(lèi)的信息。然后我發(fā)現(xiàn)SelectSingleNode正好有個(gè)參數(shù)類(lèi)型是管理名稱(chēng)空間的,我就在這句代碼之前把所有名稱(chēng)空間全部加上,最后完整的代碼就長(zhǎng)這樣:

      XmlDocument doc = new XmlDocument();
              doc.LoadXml(xml);
       XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
              nsmgr.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
              nsmgr.AddNamespace("xsd", "http://response.example.com/xsd");
              nsmgr.AddNamespace("xsd1", "http://types.example.com/xsd");
              var node = doc.SelectSingleNode("http://soapenv:Body");
              var innerXml = node.InnerXml;
      

      這下,終于node終于有值了。然后我藏尸著不把名稱(chēng)空間全部加上,少一個(gè)或者兩個(gè),SelectSingleNode方法都會(huì)拋異常。我又嘗試著把這句代碼改成var node = doc.SelectSingleNode("http://Body");,node的值還是null。

      以上得出:

      1. XML有名稱(chēng)空間時(shí)必須把所有名稱(chēng)空間通過(guò)XmlNamespaceManager管理起來(lái)傳入方法SelectSingleNode中。
      2. xml節(jié)點(diǎn)有前綴時(shí),獲取節(jié)點(diǎn)必須帶前綴,如doc.SelectSingleNode("http://soapenv:Body")而不能是doc.SelectSingleNode("http://Body")
      二、反序列化XML之后,集合元素對(duì)應(yīng)的字段的值為空

      如目標(biāo)XML中city元素是多個(gè)一組的,我稱(chēng)之為集合元素。對(duì)應(yīng)的實(shí)體類(lèi)型的字段也應(yīng)該是集合類(lèi)型的,我首先想到的就是使用數(shù)組,給字段標(biāo)記XmlArray特性,如下:

      [XmlArray]
      [XmlArrayItem(ElementName ="city")]
      public CityClass[] CityArr { get; set; }
      

      但是,這樣定義的字段在反序列化XML之后CityArr的值是null的,必須改成下面這樣的才能正確的得到city元素的內(nèi)容

      [XmlElement(ElementName = "city")]
      public CityClass[] CityArr { get; set; }
      
      三、反序列化XML之后,含前綴的元素的屬性對(duì)應(yīng)的字段的值為空

      出現(xiàn)這種情況,大概率有2個(gè)原因。

      1. 實(shí)體類(lèi)沒(méi)有指定名稱(chēng)空間
      2. 實(shí)體類(lèi)字段沒(méi)有指定強(qiáng)制使用名稱(chēng)空間前綴

      如目標(biāo)XML所有元素都有前綴,而且前綴還不一樣,有xsdxsd1。前綴和名稱(chēng)空間是一一對(duì)應(yīng)的,目標(biāo)XML中xsd前綴對(duì)應(yīng)http://response.example.com/xsd名稱(chēng)空間,xsd1前綴對(duì)應(yīng)http://types.example.com/xsd名稱(chēng)空間。如city元素的前綴是xsd。那么它對(duì)應(yīng)的實(shí)體就要像下面這樣加上名稱(chēng)空間。

      [Serializable]
      [XmlType(Namespace = "http://response.example.com/xsd")]
      public class CityClass
      {
          [XmlAttribute(Form = XmlSchemaForm.Qualified)]
          public string isoCode { get; set; }
          ......
      }
      

      這段代碼中isoCodeXmlAttribute特性加了一句代碼Form = XmlSchemaForm.Qualified 它的作用就是強(qiáng)制使用名稱(chēng)空間前綴的意思。如果xml文檔的元素或者元素屬性有前綴,那么加上這句就可以正確的反序列化了。不過(guò),如果是元素的化,好像不加這句也沒(méi)有什么影響。

      以上所有提及的序列化反序列化均是指使用微軟.net平臺(tái)System.Xml.Serialization命名空間中的類(lèi)實(shí)現(xiàn)的操作。

      posted on 2018-09-18 21:37  ToddLin  閱讀(2128)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 99午夜精品亚洲一区二区| 午夜高清福利在线观看| 日韩人妻无码一区二区三区| 亚洲免费人成在线视频观看| 色欲综合久久中文字幕网| 亚洲色婷婷一区二区三区| 成人精品天堂一区二区三区| 国产自产对白一区| 漂亮人妻被修理工侵犯| 丝袜美腿视频一区二区三区| 一区二区三区放荡人妻| 欧美亚洲另类自拍偷在线拍| 成人看的污污超级黄网站免费 | 亚洲国产韩国欧美在线 | 不卡一区二区三区视频播放| 亚洲日韩av无码一区二区三区人 | 色综合天天色综合久久网| 爱情岛亚洲论坛成人网站| 日本免费观看mv免费版视频网站| 在线日韩日本国产亚洲| 亚洲国产欧美一区二区好看电影| 国产黄色精品一区二区三区| 国产午夜福利视频在线观看| 在线观看特色大片免费网站| 人妻少妇邻居少妇好多水在线| 中文字幕亚洲人妻系列| 久久精品国产一区二区三| 一色屋精品视频在线观看| 色色97| 国产v亚洲v天堂a无码99| 自拍偷拍第一区二区三区| 欧洲精品色在线观看| 国产av中文字幕精品| 一个色综合国产色综合| 看全黄大色黄大片视频| 人人爽人人爽人人片av东京热| 亚洲熟妇av一区二区三区宅男| 国产精品一线天在线播放| 99久久国产成人免费网站| 国产太嫩了在线观看| 国产精品久久久午夜夜伦鲁鲁|