首页 > 解决方案 > 是否有将 OO 对象与 XML 相互转换的标准?

问题描述

我希望在 .net 中实现 XML 序列化,但手动编码对象以确保我可以管理版本控制。

对象往往具有子对象的单独实例,以及它们的数组、字典和元组,每一个似乎都改变了它们的理想存储结构。从对象开始A

Class A
  Private b as B
  private c as C
  private d as B
  private e as List(Of B)
  private f as Dictionary(of Integer, C)
End Class

组成:

Class B
  dim x as Integer
End Class

Class C
  dim y as String
End Class

B序列化时可能显示为:

<B x=1/>

并且C作为

<C y="Foo"/>

B在列表中可能会受益于索引号

<B id=23 x=1/>

C在字典中的键

<C key="Bar" y="Foo"/>

现在A有两个 B 实例,因此这些实例可以使用实例名称:

<A>
  <B instanceName="b" x=1/>
  <C instanceName="c" y="Foo"/>
  <B instanceName="d" x=2/>
  <List type="B" instanceName="e">
    <B id=0 x=3/>
    <B id=1 x=4/>
  </List>
  <Dictionary keyType="Integer" valueType="C" instanceName="f">
    <C key=0 y="Bar"/>
    <C key=14 y="Baz"/>
  </Dictionary>
</A>

在对“对象”进行编码的每个地方,都需要不同的属性来识别它,而我希望每个对象都有自己封装的 XML 定义,同时又不会过于庞大。我已经想象了一些其他的序列化方式,例如:

<InstanceName type=typeName attributes...>

但是,这对数组效果不佳:

  <List type="B" instanceName="e">
    <0 type="B" x=3/>
    <1 type="b" x=4/>
  </List>

因为元素名称现在是索引号。就像是:

<A>
  <Instance name="b">
    <B x=1/>
  </Instance>
  <Instance name="c">
    <C y="Foo"/>
  </Instance>
  <Instance name="d">
    <B x=2/>
  </Instance>
  <Instance name="e">
    <List type="B" instanceName="e">
      <Element id=0>
        <B x=3/>
      </Element>
      <Element id=0>
        <B x=4/>
      </Element>
    </List>
  </Instance>
  <Instance name="f">
    <Dictionary keyType="Integer" valueType="C">
      <Element>
        <Key>0</Key>
        <Value>
          <C y="Bar"/>
        </Value>
      </Element>
      <Element>
        <Key>14</Key>
        <Value>
          <C y="Baz"/>
        </Value>
      </Element>
    </Dictionary>
  </Instance>
</A>

满足需要,但显得异常臃肿。我觉得这个问题必须有一个我缺少的非常标准的解决方案。

标签: xmlvb.netserializationversioning

解决方案


恐怕我没有答案,只有观察。

您的最后一段“满足需求,但似乎异常臃肿”,几乎说明了有关 XML(或任何其他文本线格式)的所有内容。从根本上说,它们都必须解决描述结构和内容的相同问题,如果要使其可读,则线格式将不得不使用具有含义的关键字和表示范围的符号。有线格式中的功能越多,所需的关键字和符号的数量就越多。所以膨胀几乎是不可避免的。

可以通过使用空格而不是符号来制作一种看起来不那么臃肿的线形(就像 Python 所做的那样)。但它不会是 XML。

人们还可以想象一种线格式,其中“元素”和“实例”被“E”和“I”等替换,但随后你就成为了二进制线格式的一部分。也用二进制表示替换类型和值,并且......

工具

文本线格式中膨胀的令人反感的性质源于两个问题:计算机处理所有这些文本看起来效率低下,并且不得不在文本编辑器中手动浏览它是很痛苦的。

遗憾的是,对于许多开发人员来说,第一个问题似乎很少成为问题,我认为当 CPU 周期、网络带宽和存储容量如此便宜时,这是不可避免的。在你被迫解决这个问题之前,你必须变得非常大,这确实是谷歌开发谷歌协议缓冲区的原因。GPB 具有讽刺意味的是,已经有一个解决方案,谷歌的工程师从未使用他们自己的搜索引擎去寻找它......

第二个,文本编辑器中的数据外观,更有趣。人们已经开发出可以处理例如 XML 范围的折叠式文本编辑器。有用,但仍然相当臃肿、笨重等。

很少有开发人员能体验到 ASN.1 的商业工具(Google 在开发 GPB 之前没有听说过的东西)。我有,两个主要供应商都提供了数据查看应用程序,或用于线格式的可视化编辑器(嗯,所有 ASN.1 线格式,包括 XER,它是一种 XML 表示形式和 JSON)。

视觉编辑器

这些都很棒;实际上,根据已编写的序列化模式,可视化编辑器创建了一个 GUI(可解释的树),允许人们以合理的方式探索、搜索和编辑内容。例如,如果结构中的字段是具有约束值的 INTEGER,则在对象树的某处有一个可以输入值的框,它不允许您输入约束之外的值。文本、浮点数、二进制字符串等也是如此。

我的观点是,对臃肿、可读性、外观、文本线格式的担忧都只是在绕过一个更基本的问题。缺乏旨在正确完成工作的工具。在 ASN.1 世界中,这些工具确实存在(有偿)。这比出于相同目的使用折叠式文本编辑器要好得多。

这些工具在通信世界(ASN.1 的来源)中也非常有用,因为它们向您展示了模式在有线格式大小方面的结果,向您展示了每个特定字段在有线格式中的样子(即 BER 、u/a/c PER、JSON、XML、DER 等)。如果您希望最小化使用的位数(通常在无线电链路上使用的位数),那么这是一个真正的生产力助推器。你永远不会真正体会到 ASN.1 的约束和 uPER 是多么聪明,除非你看到它需要多少位来打包信息。对 1980 年代来说还不错。


推荐阅读