2016-12-20

C# 解析 XML 字串(C# Parse XML string)

最近在介接第三方金流服務時,廠商使用 XML 回傳,久沒解析 XML,剛收到時還愣了一下,突然間想不起來該怎麼做,看來有年紀後就不適合再靠記憶力,馬上來紀錄一下。

整理 XML string

1.收到的內容

"\t\t\t\t\t\t\t\t\t\t\t\t<?xml version=\"1.0\" encoding=\"UTF-8\"?><documents><Resp><Id>486441f5-7fa6-4676-b37d-ef29cfbdb1fe</Id><accountId>yowko</accountId><orderNo>Yowko16111800018</orderNo><mtaTransId>8800000006293669</mtaTransId><transAmt>3</transAmt><result>0000</result><respCode>0</respCode><transTime>20161118143324</transTime><completeTime>20161118150716</completeTime></Resp></documents>";
  • 看起來是 XML ,但又好像不太一樣?!, 立馬驗證一下,XML Validator from w3schools

    validatorfail

  • \t 讓我覺得應該經過 html encode,所以先 html decode

2.decode xml via html decode

  • HttpUtility.HtmlDecode(xml);
  • 經過 decode 後,果然看來就正常多了

    decode decodevalidfail

  • 錯誤訊息明白的指出 XML 宣告只允許在文件開始處,接著使用 trim

3.trim

  • HttpUtility.HtmlDecode(xml).Trim();

    trim validate

開始解析 XML to object

1. 將 xml 先轉成 class

Edit --> Paste Special --> Paste XML as Classes

paste

2. xml 解析成 object

Namespace:System.Xml.Serialization

程式說明:
var reader = new StringReader(xmlstring);//xmlstring 是傳入 XML 格式的 string
var serializer = new XmlSerializer(typeof(documents));//documents 是 paste xml as class 來的類別
var instance = (documents)serializer.Deserialize(reader);
實際使用:
string xml = "\t\t\t\t\t\t\t\t\t\t\t\t<?xml version=\"1.0\" encoding=\"UTF-8\"?><documents><Resp><Id>486441f5-7fa6-4676-b37d-ef29cfbdb1fe</Id><accountId>yowko</accountId><orderNo>Yowko16111800018</orderNo><mtaTransId>8800000006293669</mtaTransId><transAmt>3</transAmt><result>0000</result><respCode>0</respCode><transTime>20161118143324</transTime><completeTime>20161118150716</completeTime></Resp></documents>";
var reader = new StringReader(HttpUtility.HtmlDecode(xml).Trim());
var serializer = new XmlSerializer(typeof(documents));
var instance = (documents)serializer.Deserialize(reader);

serilizeobject

取得特定 node 資料

1. 使用 XmlDocument

Namaspace:System.Xml

程式說明:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlstring);//xmlstring 是傳入 XML 格式的 string
doc.GetElementsByTagName("result")[0]?.InnerText;//取得第一個 result 節點內的值
實際使用:
string xml = "\t\t\t\t\t\t\t\t\t\t\t\t<?xml version=\"1.0\" encoding=\"UTF-8\"?><documents><Resp><Id>486441f5-7fa6-4676-b37d-ef29cfbdb1fe</Id><accountId>yowko</accountId><orderNo>Yowko16111800018</orderNo><mtaTransId>8800000006293669</mtaTransId><transAmt>3</transAmt><result>0000</result><respCode>0</respCode><transTime>20161118143324</transTime><completeTime>20161118150716</completeTime></Resp></documents>";

XmlDocument doc = new XmlDocument();
doc.LoadXml(HttpUtility.HtmlDecode(xml).Trim());
doc.GetElementsByTagName("result")[0]?.InnerText;

xmldocOK

2. 使用 XDocument

Namespace:System.Xml.Linq

程式說明:
XDocument doc = XDocument.Parse(xmlstring);//xmlstring 是傳入 XML 格式的 string
doc.Descendants().FirstOrDefault(e => e.Name.ToString().ToLower().Contains("result"))?.Value;//取得第一個 result 節點內的值
實際使用:
string xml = "\t\t\t\t\t\t\t\t\t\t\t\t<?xml version=\"1.0\" encoding=\"UTF-8\"?><documents><Resp><Id>486441f5-7fa6-4676-b37d-ef29cfbdb1fe</Id><accountId>yowko</accountId><orderNo>Yowko16111800018</orderNo><mtaTransId>8800000006293669</mtaTransId><transAmt>3</transAmt><result>0000</result><respCode>0</respCode><transTime>20161118143324</transTime><completeTime>20161118150716</completeTime></Resp></documents>";

XDocument doc = XDocument.Parse(HttpUtility.HtmlDecode(xml).Trim());
DOC.Descendants().FirstOrDefault(e => e.Name.ToString().ToLower().Contains("result"))?.Value;

xdoc_ok

參考資料

  1. XML Validator from w3schools
  2. XDocument 類別
  3. XmlDocument 類別

沒有留言:

張貼留言