是否存在将OO对象与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(或实际上其他任何文本线格式)的内容。从根本上讲,它们都必须解决描述结构和内容的相同问题,并且如果要可读的话,wireformat将必须使用具有含义和表示范围的符号的关键字。在线格式中的功能越多,所需的关键字和符号的数量就越大。因此膨胀是不可避免的。

通过使用空格而不是符号,可以使线形看起来不那么肿胀(就像Python一样)。但是那时不会是XML。

人们还可以想象一种线格式,其中“ Element”和“ Instance”被“ E”和“ I”等代替,但是您将成为二进制线格式的一部分。也用二进制表示形式替换类型和值,然后...

工具

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

可悲的是,对于许多开发人员来说,这些问题中的第一个似乎很少出现,并且我认为当CPU周期,网络带宽和存储容量如此便宜时,这是不可避免的。在必须解决这个问题之前,您必须变得非常强大,这确实是Google开发Google Protocol Buffers的原因。 GPB具有讽刺意味的是,那里已经有了解决方案,Google的工程师从未使用过自己的搜索引擎来寻找它...

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

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

可视编辑器

这些太棒了;实际上,从一个已编写的序列化模式开始,Visual Editor会创建一个GUI(可扩展树),该GUI允许用户以明智的方式浏览,搜索和编辑内容。例如,如果结构中的字段是具有约束值的INTEGER,则在对象树的某处有一个框,您可以在其中输入值,并且不允许输入超出约束的值。对于文本,浮点数,二进制字符串等也是如此。

我的观点是,关于膨胀,可读性,外观,文本线格式的关注都只是绕开了一个更根本的问题;缺乏专门用来完成这项工作的工具。在ASN.1世界中,确实存在这些工具(需要付费)。与将折叠文本编辑器用于相同目的相比,这是一个更好的体验。

这些工具在通信世界(ASN.1的来源)中也非常有用,因为它们以线格式大小向您显示模式的结果,并向您显示线格式中每个特定字段的外观(是BER,u / a / c PER,JSON,XML,DER等)。如果您希望减少使用的位数(通常在无线链路上使用的位数),那么这确实是提高生产力的方法。您永远不会真正欣赏ASN.1的约束和uPER多么巧妙,直到您看到它需要多少位来打包信息。对于1980年代还不错。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-