前段时间比较忙,没有更新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();
}
完整的示例位置: