前段時間比較忙,沒有更新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序列化反序列化示例