xml序列化和反序列化(一)

wqlyanan發表於2018-05-12

  最近專案中需要呼叫第三方webservice,入參和出參採用xml格式,大致如下:

  入參:

<?xml version=”1.0″ encoding=”utf-8″?>

<RequestParams> 
  <PatientsName/> 
  <PatientsID/> 
</RequestParams>

出參:

<?xml version=”1.0″ encoding=”utf-8″?>

<PacsResult>
<successe>true</successe>
<msg>成功</msg>
<reports>
   <report>
     <PatientsSex></PatientsSex>
     <PatientsName></PatientsName>
   </report>
</reports>
</PacsResult>

關於入參,專案中封裝的有入參實體,實體類如下:

public class rep
{
public string PatientsName { get; set; }
public string PatientsID { get; set; }

}

現在就需要怎麼將入參實體轉換為xml格式字串,程式碼如下:

   /// <summary>
    /// 序列化
    /// </summary>
    /// <param name="T">泛型t</param>
    /// <returns></returns>
    public static string XmlSerializerSR<T>(T t)
    {
        MemoryStream Stream = new MemoryStream();
        XmlSerializer xml = new XmlSerializer(typeof(T));
        try
        {
            //序列化物件
            xml.Serialize(Stream, t);
        }
        catch (InvalidOperationException)
        {
            throw;
        }
        Stream.Position = 0;
        StreamReader sr = new StreamReader(Stream);
        string str = sr.ReadToEnd();

        sr.Dispose();
        Stream.Dispose();

        return str;
    }

測試結果:

<?xml version="1.0"?>
<RequestParams xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
  <PatientsName>Cui Jian Hong</PatientsName>  
  <PatientsID>P57748</PatientsID> 
</RequestParams>

有些人看到覺得這和入參不一樣,

<?xml version="1.0"?>少了utf-8,<RequestParams》多了個xmlns(xml名稱空間,我這裡不作過多介紹)這個玩意;強迫症犯了,要求必須和入參一摸一樣,我就嘗試用另外一種方法:
public static string XmlSerializerXTW<T>(T t)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            //Add an empty namespace and empty value
            ns.Add("", "");
             XmlTextWriter textWriter = new XmlTextWriter(ms, Encoding.GetEncoding("UTF-8"));
            //StreamWriter streamWriter = new StreamWriter(ms, Encoding.GetEncoding("utf-8"))效果一樣;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            serializer.Serialize(textWriter, t, ns);

            string xmlMessage = Encoding.UTF8.GetString(ms.GetBuffer());
            xmlMessage = System.Text.RegularExpressions.Regex.Replace(xmlMessage, "^[^<]", "");
            ms.Close();
            textWriter.Close();
            return xmlMessage;
        }
    }

看到程式碼裡為什麼多了個正規表示式替換呢,原因是因為如果不加這個,序列化後是這樣的

?<?xml version="1.0" encoding="utf-8"?>
<RequestParams>
  <PatientsName>Cui Jian Hong</PatientsName>
  <PatientsID>P57748</PatientsID>
</RequestParams>

注意第一個字元,不是貼上錯誤,哈哈,實際就是多個問號;蛋疼了,網上找了半天,最後就這麼解決了,哪位大神知道為什麼,請告之。

寫到這裡有些人覺得,這麼搞有點牽強,不完美,怎麼辦呢,還有終極殺招,自定義xml,無非就是拼接唄:可以這麼搞:

 /// <summary>
    /// 拼接入參
    /// </summary>
    /// <param name="inParams"></param>
    /// <returns></returns>
    public static string CreateInParams(Dictionary<string, string> inParams,string inParamName)
    {
        string ret = string.Empty;
        XmlDocument doc = new XmlDocument();
        doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));

        XmlElement xnIn = doc.CreateElement(inParamName);
        doc.AppendChild(xnIn);
        foreach (var de in inParams)
        {
            XmlElement xn = doc.CreateElement(de.Key);
            xn.InnerText = de.Value;
            xnIn.AppendChild(xn);
        }
        ret = doc.OuterXml;
        return ret;
    }

當然程式碼裡是入參Dictionary<string, string>,不過這個可以任意定義,實體也行,陣列也行。。。我這裡只提供一個思路。

關於出參解析,請看下篇介紹

相關文章