`
pangwu86
  • 浏览: 115996 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

XBlink中关于XML/JSON格式中引用对象的路径的实现思路

阅读更多

在将一个对象序列化过程中,引用对象的处理是一个常见问题。


随着新版本XBlink的即将推出,这个老大难问题就需要慎重解决。


在0.7.0版中,引用虽然已经能够正确处理,但是实现方式是采用了对象出现先后顺序为标记,采用数字的方式来实现引用。


例如 A包含B,B包含C,C包含A,C也包含B。生成的XML如下:



<A>
  <B>
    <C>
      <A ref="1"/><!-- A是第一个序列化的对象,ID设置为1 -->
      <B ref="2"/><!-- B是第二个序列化的对象,ID设置为2 -->
    </C>
  </B>
</A>

 

这个摸样虽然没错,但是在难以阅读。(毕竟序列化为XML的优点之一就是其可读性好,如果不好,那还不如用其他格式)


新版本的开发决定彻底解决这个问题,让引用路径可以清楚表示出其对象位置。


思考后,解决方式就是生成常见的两种路径:相对路径 绝对路径


在这个实现过程中,看了下Fastjson与XStream的实现方式,发现以下几点问题:


首先说说温少的Fastjson的实现方式


这里有温少的一个思路最终实现


这里的路径感觉有稍许混乱,有的是相对路径,例如使用..来引用上级对象,但也有几个特殊符号,使得有的路径又变成了绝对路径,例如使用对于根节点使用$来表示,自身使用@来表示。


个人认为这样会产生一个问题,例如上面那个ABC的例子,可以有两种表现形式


<A>
  <B>
    <C>
      <A ref="$"/>
      <B ref="../.."/>
    </C>
  </B>
</A>
<!-- 下面这种也是正确的 -->
<A>
  <B>
    <C>
      <A ref="../../.."/>
      <B ref="$.B"/>
    </C>
  </B>
</A>

 

像例子中关于B节点就有两种不同的表示方式,一个文件中会混杂这两种格式,这就是个人觉得有稍许混乱的原因。


代码的话查看com.alibaba.fastjson.serializer.SerialContext

还有com.alibaba.fastjson.serializer.JSONSerializer的writeReference方法


里面实现是优先判断是否属于那几个特殊符号使用范围,不行再计算路径。


路径是通过一个链表形式存放的,不断查找父节点,拼装路径,具体的还是看源码吧。


再谈谈XStream的实现方式


XStream采用了常见的相对路径来表示位置关系(个人比较喜欢这个)。


代码看com.thoughtworks.xstream.io.path包。


简单分析下几个类的作用:


Path 就是封装路径用的对象,里面有着计算相对路径的方法。


PathTracker 名字都告诉你了,Tracker!里面有一个栈,进去一个节点,把节点名称压入栈中,退出这个节点,弾栈,也就是说记录当前路径信息,通过它可以获得你当前所在节点的绝对路径。


PathTrackingWriter 一个包装类,里面实际工作的是HierarchicalStreamWriter也就是用来写XML文件的,在写节点开始标签时,调用PathTracker记录那个节点名称,写节点结束标签时,再调用PathTracker 删掉那个节点名称。


PathTrackingReader 与PathTrackingWriter 功能类似,反序列时用的。


最后说下XBlink的实现思路,其实跟XStream差不多,基本就是参考它的,做了一些简化与改进。


详情见org.xblink.core.path包(里面几个类也是借鉴了XStream,哈哈,谁叫XStream是XBlink的老师来)



讲下思路,首先在开始写XML时,生成一个PathTracker实例。

实现一个引用缓存,例如一个key是对象,value是绝对路径的Map,用来记录对象与其绝对路径的关系。

首先一个对象序列化,先去这个缓存查看一下,是否已经存在了,如果没有,那就开始写一个节点,记录下这个节点名称,放入PathTracker中。当你发现有个节点是可以被引用的(可能被引用,后面是不是真的被引用还不知道),就通过PathTracker生成当前这个节点的绝对路径,将这个类与路径记录引用缓存中,然后序列化下一个对象。

当发现要某个对象是要在缓存中存在的了,那就生成当前路径(也是一个绝对路径),通过一个算法,将此路径与缓存中那个对象的绝对路径进行比较,生成相对路径


在代码上如果变通一下的话,你可以设置一个开关,关于引用是采用相对路径还是绝对路径(这两者你都可以拿到)

这样不但你让用户多了一个选择(更人性化),如果使用绝对路径,还能减少一次计算路径的开销,提高了效率。


以上就是一些个人想法,欢迎大家提出意见探讨。

 

2
8
分享到:
评论
2 楼 han0917 2013-12-09  
我想问下我使用XBlink序列化对象为xml的时候,对某字段A设置了“”,空串。序列化后xml格式为<A/> ,有没有办法变成<A></A>这样呢?
1 楼 rodoke 2013-06-06  
最近使用XBlink生成xml 出现了个问题,因为有多层嵌套,不同的集合中有相同的对象,就出现了很多ref的引用,反序列化的时候就直接失败,经过测试 如果没有这么复杂的嵌套,类似这种:
  <?xml version="1.0" encoding="UTF-8" ?>
- <testUser>
- <userList>
- <user>
  <userName>kkk</userName>
  <userSex>sss</userSex>
  </user>
  <user ref="../user" />
  </userList>
  </testUser>
这样的反序列化是没问题的,请问这样的问题要怎么解决

相关推荐

    xblink 关键代码

    * 任意你想要的文档格式名称,例如JSON或者XML * @return 对象 */ public static Object fromAny(CharSequence cs, String docTypeName) { return XBlinkHelper.fromAny(IOUtil.createReader(cs), ...

    XBlink工作流程简介

    NULL 博文链接:https://pangwu86.iteye.com/blog/893887

    Java swing + socket + mysql 五子棋网络对战游戏FiveChess.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    纯C语言实现的控制台有禁手五子棋(带AI)Five-to-five-Renju.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    setuptools-57.1.0.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    setuptools-59.1.1.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    空载损耗计算软件.zip

    空载损耗计算软件

    贪吃蛇.cpp

    贪吃蛇.cpp

    Gobang Game programmed by C(五子棋游戏)Gobang.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    单片机C语言Proteus仿真实例用DS1302与数码管设计的可调电子表

    单片机C语言Proteus仿真实例用DS1302与数码管设计的可调电子表提取方式是百度网盘分享地址

    二叉树的遍历hahahha

    二叉树的遍历hahahha

    setuptools-3.8.1.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    基于linux开发C语言编程五子棋小游戏inset.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    Linux下,C语言实现五子棋程序Linux-Wuziqi.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    飞机大战pygame_demo.zip

    五子棋游戏想必大家都非常熟悉,游戏规则十分简单。游戏开始后,玩家在游戏设置中选择人机对战,则系统执黑棋,玩家自己执白棋。双方轮流下一棋,先将横、竖或斜线的5个或5个以上同色棋子连成不间断的一排者为胜。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【技术】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    K210SD卡掉电存储的人脸识别

    K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210SD卡掉电存储的人脸识别K210

    setuptools-47.3.2.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    复制粘贴功能,简单实用

    复制粘贴功能,简单实用,非常好用

    绝缘子缺陷数据集,输电线路巡检

    绝缘子缺陷数据集,总共四类,分别为绝缘子,绝缘子破损,绝缘子闪络,防震锤,总共1688张图片

    Python源码-泰坦尼克之灾.py

    Python源码-泰坦尼克之灾

Global site tag (gtag.js) - Google Analytics