xml - 是否有将 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>
满足需要,但显得异常臃肿。我觉得这个问题必须有一个我缺少的非常标准的解决方案。
解决方案
恐怕我没有答案,只有观察。
您的最后一段“满足需求,但似乎异常臃肿”,几乎说明了有关 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 年代来说还不错。
推荐阅读
- amazon-web-services - logstash 是从 s3 下载日志还是在不下载的情况下读取?
- ios - 调整大小时,SwiftUI Image 组件会缩小
- java - 如何在调用 postgresql 函数时获得动态结果集
- batch-file - 如何修复 RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters 1, True 不是每次都更新
- firebase - 使用 Firebase 电子邮件验证的动态/深度链接?
- port - nmap默认扫描的1000个端口是多少?
- android - 在 Android-ndk 中,如何在调用 dlclose( ) 时调用 _fini( )?
- php - 如何根据首字母对数据进行排序
- ruby-on-rails - 为什么 elasticserach-rails 突然提高 Faraday::ConnectionFailed (执行过期)?
- javascript - 如何在数组对象中获取检查的元素