浏览 1700 次
锁定老帖子 主题:用连连看的方法比较XML文档
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-10
1.xml <xml/><a><b>bb</b><c k='11'></c></a> 2.xml <xml/><a><c k='11'></c><b>bb</b></a> 排列有些不同,但内容还是一样的. 如果用DOM比较的话,算法基本上就是, 1 解析第一个文档,构成一个结点树 2 遍历第二个文档结点,搜索第一个文档树,找到对应的结点,比较。 但问题是怎么找到对应的结点,首先是结点位置的层次问题,其次怎么确定对应关系。 对于层次问题,我们可以标记,在同一级的兄弟结点上比较。 但就算我们缩小了范围,对于没有特殊标记的结点,比如<li>这样的标签,还是很难确定对应关系,就算是想排序都没有关键字。 虽然我也知道,基于树都可以做递归,去简化设计,但真没想出来:< 最后还是连连看的灵感。打碎再比较. 基本的思路, 把结点分成两类,有BODY的和没有BODY的. 比如上面的XML文件, 就可以分成有BODY的<b>bb</b>;没有BODY的<xml/>, <a></a>, <c k='11'></c>,这几个结点.最终的目标就是比较这些打碎的TAG. 同时流式解析两个XML文件,,并为每一个文件生成相应的一个TAG栈. 把一个TAG压进栈,要分两次进行,第一次,压进<xx>,如果有BODY的话,把BODY也压进去.第二次,压入</xx>. 这样我们还需要一个指针栈,标记未完全压入栈的TAG. 同时把完全压入栈的元素,放到一个比较队列里.,每完全压入一个元素,就比较两个栈的比较队列.如果相同,就删除这个TAG.如果两个XML文件,基本相似的话,比较队列的SIZE都会保持比较小的值.节省很多的遍历开支. 完成XML的解析后,只要比较两个栈中比较队列的大小,如果都为空,那么这两个XML就是内容相等的. 但这个的算法,忽略了结点的位置信息. 比如,<a></a><a></a>和<a><a></a></a>也会被等同. 这里做了一个简单的扩展.为每一个TAG加一个ID属性, 第一个压入未完全压入栈的TAG的ID值为该TAG的<xx>和BODY字符串的hashCode值. 以后入栈的TAG的ID值是未完全压入栈栈顶元素ID值+该TAG的<xx>和BODY的hashCode值.比较时,先比较一个ID然后再比较内容. 目前只完成了一个很简单的实现.还不能比较不同排列的属性,但对于我的需求来说,已经足够了. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |