序列化紧凑 XML

发布于 2025-01-04 06:57:31 字数 626 浏览 2 评论 0原文

我有一个包含四个字段(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”是日期时间刻度,“a”是枚举值,元素是字符串。

我不想有根元素,但如果有的话,我希望它尽可能小。

我尝试将 XmlSerializer 与 XmlWriterSettings 类一起使用,但无法摆脱命名空间和根元素。

这样做的最佳方法是什么?我不是保存到文件,而是读取和写入内存中的字符串。

I have a class with four fields (DateTime, Enum, string, string). I want to serialize it to and from an XML element or a series of XML elements in a compact manner. For example, I might serialize it to something like this:

<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>

Where 'i' is each class instance, 't' is the DateTime ticks, 'a' is the enum value, and the elements are strings.

I'd prefer to not have a root element, but if I do have it, I'd like it to be as small as possible.

I've tried using XmlSerializer with the XmlWriterSettings class but I can't get rid of the namespaces and root element.

What's the best way of doing this? I'm not saving to a file, I'm reading and writing to strings in memory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

π浅易 2025-01-11 06:57:31

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

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();

and to read

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:

You don't need to convert xElem to string in order to use that xml in memory

殊姿 2025-01-11 06:57:31

如果您的数据就是这么简单,您可以直接使用 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();

If your data is that simple, you can use XmlWriter directly:

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());
}

Running this program produces the following output (I added line breaks for clarity; they are not in the output):

<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>

You need that root element if you would like to read the information back. The most expedient way would be using 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();
莫相离 2025-01-11 06:57:31

我个人只使用 StringBuilder

如果大小是您最关心的问题,请考虑 jsonyaml 而不是 XML。

I'd just use a StringBuilder, personally.

If size is your #1 concern, consider json or yaml instead of XML.

全部不再 2025-01-11 06:57:31

我相信,您需要实现自己的序列化器,这将是一个痛苦。或者您可以在序列化后手动删除不需要的内容,这可能会起作用。

如果您关心大小,则应该使用 BinaryFormatter 序列化为二进制。如果需要将其存储为字符串,则始终可以对其进行 base-64 编码。 (BinaryFormatter 的工作方式几乎与 XmlSerializer 一样,只不过输出是原始二进制文件,而不是格式良好的 XML。)

You'll need to implement your own serializer, I believe, which will be a pain. That, or you could manually strip out what you don't need after serializing, which could work.

If size is your concern, you should be serializing to binary using BinaryFormatter. You can always base-64 encode it if you need to store it as a string. (BinaryFormatter works almost just like XmlSerializer, except the output is raw binary, rather than nicely formatted XML.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文