天天看點

GB28181---XML解析

前段時間比較忙,沒有更新gb28181的相關技術介紹,過年放假回家比較空,繼續沒完成的工作,把gb28181的過檢的技術經驗分享給大家。這一篇介紹xml的解析。

gb28181裡面的message消息攜帶的封包内容是以Xml形式。需要涉及到的技能包括把字元串拼接成XML以及提取XML的元素。最開始,我傻傻的嘗試了用字元串拼接以及字元串解析來處理XML。後來漸漸的發現走進了一個死胡同,工作量太大。比如國标裡面有的字段必須填寫,有的字段又是選填的,每一個字段是判斷和處理。而且,各種不同的指令,xml的結構又是不一樣的,針對不同的指令都要去寫一個xml的解析,費時費勁。後來采用了xml序列化和反序列化的思路,把所有xml的拼接和解析統一到一起,我們上層應用層更多的關注業務邏輯。可以說采用了這項技能,對于XML這一塊基本上沒話費過時間和經曆了。

序列化和反序列化思路是通過一個類來映射XML,XML裡面的元素,都被映射到類的成員變量。 業務處理不直接面對XML,而是面對類進行操作。反序列化是指把XML解析出來的類,序列化是指把類轉換成XML字元串。是以我們的XML解析隻需要寫出兩個函數就搞定了,一個是把類轉出XML字元串的函數,一個是把XML字元串的函數轉換成類的函數。

XML序列化函數如下(我是用C#開發的開發環境VS2017):

public static string XMLSerialize<T>(T obj)
        {
            string xmlMessage = string.Empty;

            try
            {
                //Serialize the object with our own namespaces (notice the overload)
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                //Add an empty namespace and empty value
                ns.Add("", "");

                XmlSerializer serializer = new XmlSerializer(typeof(T));
                using (MemoryStream ms = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(ms, Encoding.GetEncoding("gb2312")))
                    {
                        serializer.Serialize(writer, obj, ns);
                        xmlMessage = Encoding.GetEncoding("gb2312").GetString(ms.GetBuffer()).TrimEnd('\0');
                    }
                }
                var strIndex = xmlMessage.IndexOf("?>");
                if (strIndex > 0)
                {
                    xmlMessage = xmlMessage.Insert(strIndex, " standalone=\"yes\"");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("{0}", ex.Message);
                return null;
            }

            return xmlMessage;
        }
           

XML反序列化函數如下(我是用C#開發的):

public static bool TryXMLDeserialize<T>(string xmlStr, out T obj)
            where T : new()
        {
            obj = new T();
            try
            {

                XmlSerializer serializer = new XmlSerializer(typeof(T));
                using (MemoryStream writer = new MemoryStream(
                    Encoding.Default.GetBytes(xmlStr)))
                {
                    obj = (T)serializer.Deserialize(writer);
                }

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("{0}", ex.Message);
                Console.WriteLine(xmlStr);
            }

            return false;
        }
           

類的定義執行個體

#region CuRegister
    //sip注冊
    [Serializable]
    [XmlRootAttribute("request")]
    public class CuRegister_request
    {
        [XmlAttribute]
        public string command = "CuRegister";

        public CuRegister_parameters parameters { get; set; }

    }
    [Serializable]
    [XmlRootAttribute("response")]
    public class CuRegister_response
    {
        [XmlAttribute]
        public string command = "CuRegister";
        public CuRegister_parameters parameters { get; set; }
    }
    public class CuRegister_parameters
    {
        public string cuPassword { get; set; }
        public string cuUserId { get; set; }
        public string cuIp { get; set; }
        public string cuPort { get; set; }
        public string version { get; set; }
        public string cuId { get; set; }
        public string keepAlivePeriod { get; set; }
        public string currentTime { get; set; }
    }
    #endregion
           

調用執行個體:

class Program
    {
        static void Main(string[] args)
        {
            CuRegister_request cr = new CuRegister_request()
            {
                parameters = new CuRegister_parameters()
                {
                     cuId ="1",
                     cuPassword  ="2",
                     cuIp="3",
                     cuPort="4",
                     cuUserId="5",
                     currentTime="6",
                     keepAlivePeriod="7",
                     version ="8"
                }
            };
            string strXml = XMLSerialize(cr);
            Console.WriteLine(strXml);
            if(TryXMLDeserialize(strXml,out CuRegister_request ocr))
            {
                Console.WriteLine(ocr.parameters.keepAlivePeriod);
            }
            Console.ReadLine();
        }
           

完整的示例位置:

XML序列化反序列化示例

繼續閱讀