序列化压缩XML
本文关键字:XML 压缩 序列化 | 更新日期: 2023-09-27 18:24:01
我有一个包含四个字段(DateTime、Enum、string、string)的类。我想以紧凑的方式将它序列化到XML元素或一系列XML元素,并从中序列化。例如,我可能会将其序列化为以下内容:
<i t='234233' a='3'><u>Username1</u><s1>This is a string</s1></i>
<i t='234233' a='4'><u>Username2</u><s1>This is a string</s1></i>
<i t='223411' a='1'><u>Username3</u><s1>This is a string</s1></i>
其中"i"是每个类实例,"t"是DateTime刻度,"a"是枚举值,元素是字符串。
我希望没有根元素,但如果我有,我希望它尽可能小。
我已尝试将XmlSerializer与XmlWriterSettings类一起使用,但无法摆脱命名空间和根元素。
做这件事最好的方法是什么?我不是保存到文件中,而是读取和写入内存中的字符串。
System.Xml.Linq
XElement xElem = new XElement("r");
for (int i = 0; i < 3; i++)
{
xElem.Add(
new XElement("i",
new XAttribute("t", "234233"),
new XAttribute("a", "3"),
new XElement("u", "UserName"),
new XElement("s1", "This is a string")
)
);
}
var str = xElem.ToString();
并读取
XElement xElem2 = XElement.Load(new StringReader(str));
foreach(var item in xElem2.Descendants("i"))
{
Console.WriteLine(item.Attribute("t").Value + " " + item.Element("u").Value);
}
PS:
您不需要将xElem
转换为字符串就可以在内存中使用该xml
如果您的数据如此简单,您可以直接使用XmlWriter
:
class Data {
public DateTime Date { get; set; }
public int Code { get; set; }
public string First { get; set; }
public string Last { get; set; }
}
static void Main() {
var sb = new StringBuilder();
var xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = false;
var elements = new[] {
new Data { Date = DateTime.Now, First = "Hello", Last = "World", Code = 2}
, new Data { Date = DateTime.UtcNow, First = "Quick", Last = "Brown", Code = 4}
};
using (var xw = XmlWriter.Create(sb, xws)) {
xw.WriteStartElement("root");
foreach (var d in elements) {
xw.WriteStartElement("i");
xw.WriteAttributeString("t", ""+d.Date);
xw.WriteAttributeString("a", "" + d.Code);
xw.WriteElementString("u", d.First);
xw.WriteElementString("s1", d.Last);
xw.WriteEndElement();
}
xw.WriteEndElement();
}
Console.WriteLine(sb.ToString());
}
运行此程序会产生以下输出(为了清晰起见,我添加了换行符;它们在输出中是而不是):
<root>
<i t="2/9/2012 3:16:56 PM" a="2"><u>Hello</u><s1>World</s1></i>
<i t="2/9/2012 8:16:56 PM" a="4"><u>Quick</u><s1>Brown</s1></i>
</root>
如果您想读回信息,则需要该根元素。最方便的方法是使用LINQ2XML:
var xdoc = XDocument.Load(new StringReader(xml));
var back = xdoc.Element("root").Elements("i").Select(
e => new Data {
Date = DateTime.Parse(e.Attribute("t").Value)
, Code = int.Parse(e.Attribute("a").Value)
, First = e.Element("u").Value
, Last = e.Element("s1").Value
}
).ToList();
我个人只想使用StringBuilder
。
如果大小是您最关心的问题,请考虑json
或yaml
,而不是XML。
我相信,您需要实现自己的序列化程序,这将是一件痛苦的事情。或者,您可以在序列化后手动剥离不需要的内容,这可能会起作用。
如果大小是您关心的问题,那么应该使用BinaryFormatter
将其序列化为二进制。如果需要将其存储为字符串,则可以始终对其进行base-64编码。(BinaryFormatter
的工作原理几乎与XmlSerializer
一样,只是输出是原始二进制文件,而不是格式良好的XML。)