`
piecehealth
  • 浏览: 47592 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

XML比较。

阅读更多
最近帮别人写了一个XML的比较的小程序,分享一下

module XMLTool

	class Node
		
		attr_reader :nodes, :name, :text, :attributes
		
		def initialize name, text, attributes = {}, ancestor_nodes = []
			@name = name
			@attributes = attributes
			@text = text
			@ancestor_nodes = ancestor_nodes.clone
			@nodes ||= {}
		end
		
		def ancestor_nodes
			@ancestor_nodes.clone
		end
		
		
		def add_node node
			@nodes[node.name] ||= []
			@nodes[node.name] << node
		end
		
		# blk params: node name, node array
		def each &blk
			@nodes.each &blk
		end
		
		
		def has_children?
			!@nodes.empty?
		end
				
		def compare_with a_node, failed_nodes = [], passed_nodes = []#, *ignore_nodes
			#puts "Current Node: #{self.name}, Compared Node: #{a_node.name}"
			#failed_nodes = failed_nodes.clone
			pass_fg = true
			if has_children?
				if a_node.has_children?					
					each do |name, children_nodes|
						if a_node.nodes[name].nil?
							#puts "Not Found. Node: #{name}, #{attributes}, #{text}"
							pass_fg = false
							break
						else
							children_nodes.each do |child_node|
								ps_fg = false
								a_node.nodes[name].each do |a_child|
									if child_node.attributes == a_child.attributes
										if child_node.compare_with(a_child, failed_nodes, passed_nodes)[0]
											ps_fg = true
											break
										end
									end
								end
								if ps_fg
									next
								else
									pass_fg = false
									break
								end
							end							
						end
					end
					#puts "Not Found. Node: #{name}, #{attributes}, #{text}" if !pass_fg
				else
					# "Structure Error."
					pass_fg = false
				end				
			else
				if a_node.has_children?
					# "Structure Error: Node :#{name}, #{a_node.name}"
					pass_fg = false
				else
					if a_node.name != name || a_node.attributes != attributes || a_node.text != text
						#puts %Q{Node Error: 
						#Node Name:#{name}, #{a_node.name}
						#Attributes: #{attributes}, #{a_node.attributes}
						#Value: #{text}, #{a_node.text}
						#}
						pass_fg = false
					end
				end
			end
			#puts error_msg.join("\n") if !error_msg.empty?
			if pass_fg
				#puts self.name
				passed_nodes << self
				failed_nodes.delete(self) if failed_nodes.include?(self)
			else
				failed_nodes << self if !passed_nodes.include? (self)
			end
			return([pass_fg, failed_nodes])
		end
	
	end

end


module XMLTool
	
	class Tree
		
		attr_reader :root
		
		def initialize xml_file
			require 'rexml/document'
			File.open(xml_file) do |file|
				doc = REXML::Document.new(file)
				@root = parse_xml(doc.root, Node.new(doc.root.name, doc.root.text, doc.root.attributes))
			end
		end
	
		def compare_with another_tree, *ignore_nodes
			
		end
		
		def self.filter_failed_nodes failed_nodes
			rets = []
			failed_nodes.each do |node|
				ancestor_chain = node.ancestor_nodes << node
				rets << ancestor_chain if rets.empty?
				rets.each do |ret|
					if (ret & ancestor_chain) == ret
						rets.delete ret
						rets << ancestor_chain
					else
						if (ret & ancestor_chain) != ancestor_chain
							rets << ancestor_chain
						end
					end
				end
			end
			return rets
		end
		
		private
		# Fill Node according element
		def parse_xml element, node			
			#puts element.name
			#puts node.ancestor_nodes
			if element.has_elements?
				element.elements.each do |sub_ele|
					ancestor_nodes = node.ancestor_nodes << node
					if sub_ele.has_elements?
						child_node = Node.new(sub_ele.name, sub_ele.text, sub_ele.attributes, ancestor_nodes)
						node.add_node(parse_xml(sub_ele, child_node))
					else
						node.add_node(Node.new(sub_ele.name, sub_ele.text, sub_ele.attributes, ancestor_nodes))
					end
				end
			end
			node
		end
		
	
	end

end

测试代码
$LOAD_PATH << File.dirname(__FILE__) unless $LOAD_PATH.include? File.dirname(__FILE__)
require 'xmltool'


include XMLTool
root1 = Tree.new('Completion090_MsgValue_XML.xml').root
root2 = Tree.new('Completion090_MsgValue_XML5.xml').root


#tree.nodes[0].nodes[0].nodes[0].nodes.each do |e|
#	puts e.tag_name
#	puts e.text
#end

ret = root1.compare_with(root2)
#ret = root2.compare_with(root1)
puts ret[0]
Tree.filter_failed_nodes(ret[1]).each do |ancestor_chain|
	ancestor_chain.each_with_index do |node, i|
		puts "#{"\s" * 2 * i}#{node.name} #{node.attributes} ->"
	end
	puts ancestor_chain.last.text
	puts "------------------"
end

#puts ret[1][0].name
#puts ret[1][0].attributes
#puts ret[1][1].name
#puts ret[1][1].attributes


之前都没做过XML的东西,nokogiri看了一下不会用,就用rexml解析xml,目前可能还有点bug,不过能凑合用,由于时间跟观众太少的关系,就不解释了。
分享到:
评论

相关推荐

    json和xml比较

    JSON 和 XML 比较 JSON 和 XML 是两种常用的数据交换格式,它们之间有很多相似之处,也有许多不同之处。下面我们将从多方面对比 JSON 和 XML。 可读性和可扩展性 JSON 和 XML 都是文本表示的数据格式,可以跨平台...

    java-xml.rar_xml_xml 比较

    在"java中四种操作xml方式的比较.txt"文件中,你可能会找到关于这四种方法的详细比较,包括它们的实现代码示例、性能测试结果以及各种情况下如何选择最佳方法的建议。而"www.pudn.com.txt"文件可能是下载来源或附加...

    xmlunit1.6 官网下载的 xml比较是否相同的jar 包

    xmlunit1.6 官网下载的 xml比较是否相同的jar 包,xmlunit1.6 官网下载的 xml比较是否相同的jar 包

    xml文件比较器下载

    Eclipse的版本控制插件可以方便地比较代码文件的差异,而XML比较器则专门针对XML格式的数据进行高效比较。 “解压就可用”表明这是一个可直接运行的压缩包,无需安装,用户只需下载并解压缩后即可开始使用。这为...

    QT中读取XML文件三种方式 的实例

    XML(eXtensible Markup Language)是一种通用的文本格式,被广泛运用于数据交换和数据存储(虽然近年来 JSON 盛行,大有取代 XML 的趋势,但是对于一些已有系统和架构,比如 WebService,由于历史原因,仍旧会继续...

    两个架构一样的XML,比较其记录条数,并标志为增,删改

    2. **XML比较**:比较两个XML文件,主要对比它们的节点结构和值。可以遍历每个文件的根节点,然后递归地比较子节点。节点的比较包括节点名、属性、文本内容等。如果两个文件的节点结构相同,但值不同,则可能发生了...

    XML比较工具ExamXML Pro注册版.rar

    ExamXML Pro是一款专门用于XML/CSV文档的比较工具,可视化的操作方式使用起来更简单,能够以树形结构来显示XML文档,能够从任何数据源中读取并进行比较,另外还可以合并XML文档,比较SQL SERVER数据以及网页等。...

    oxygen xml editor 17.0 keygen

    7. **XML比较**:提供文档差异比较功能,方便用户检查和合并不同版本的XML文档。 8. **XML预览**:实时预览XML文档,以便于理解和调整文档格式。 二、Oxygen XML Editor 17.0新特性 17.0版本可能包含以下改进或...

    ExamXML 一款可视化的XML文档比较工具

    ExamXML 一款可视化的XML文档比较工具,可用于比较XML、CSV文档,合并XML文档,读取和比较SQL servers的数据, 网页等等。ExamXML以树状结构显示XML文档,并可以插入、修改XML元素。可直接从FTP或网页上下载文件进行...

    XMLSpy2006

    8. **其他特性**:还包括XML与JSON互转、SOAP接口测试、XML比较、XML编码和解码等功能,进一步增强了XML处理的全面性。 XMLSpy2006因其丰富的功能和友好的用户界面,成为了XML开发者的重要工具。无论是初学者还是...

    jcommon-xml-1.0.13.jar

    此外,它还包含了一些实用工具类,如XML比较器,用于验证两个XML文档的结构一致性。 4. **与其他jcommon组件的集成**: 作为jcommon的一部分,jcommon-xml可以无缝集成到使用jcommon其他组件的项目中。这使得...

    altova xmlspy2013中文版下载.rar

    7. **其他功能**:还包括XML比较、XML地图、图表生成等功能,帮助开发者全面管理和分析XML数据。 在提供的压缩包中,除了XMLSpy 2013的安装文件外,还包含了一个名为"CCleaner.exe"的程序,这通常是CCleaner的安装...

    xml文件对比

    XML(eXtensible Markup Language)是一种用于存储和传输数据的标记语言,它以其结构化、可扩展性和易于解析的特点广泛应用于Web服务、配置...同时,这也可以作为一个起点,根据具体需求进一步定制和扩展XML比较功能。

    XML文档比较工具

    《XML文档比较工具》(A7Soft ExamXML PRO)v5.15[压缩包]

    pugixml读写XML示例

    pugixml是一款轻量级、高性能的C++库,专为XML解析和操作而设计。这个库由Artemev开发,提供了简单易用的API,使得在C++项目中处理XML文档变得非常便捷。本示例将详细介绍如何使用pugixml进行XML的读取和写入操作。 ...

    tinyxml与tinyxml2

    TinyXML和TinyXML2是两个小型的开源库,专门用于解析和操作XML(eXtensible Markup Language)文档。这两个库都是用C++编写的,为C++开发者提供了方便的接口来读取、写入和操作XML数据。下面将详细介绍这两个库的...

    v5-XML-Compare:每日 XML 比较和与 MIUI v5 的差异

    每日XML比较可能涉及到以下几个关键知识点: 1. **XML解析**:XML文件需要被解析才能理解其内容。解析器可以是DOM(Document Object Model)解析器,它一次性加载整个XML文档到内存中;或者是SAX(Simple API for ...

    xml2axml反编译AndroidManafest文件

    使用java工具xml2axml.jar反编译AndroidManafest文件 通过xml2axml.jar工具反编译AndroidManafest文件 还原AndroidManafest.xml详细过程: 1、获取到apk 2、解压获取里面的AndroidManifest.xml文件 3、在xml2axml....

    pb下读写xml文件的例子.rar_pb_pb 读取xml_pb 读取xml文件_pb9 xml_pb下读写xml文件的例子

    在PowerBuilder(简称PB)这个强大的开发环境中,处理XML文件是一项常见的任务。XML(Extensible Markup Language)是一种用于存储和传输数据的通用格式,尤其在跨平台和网络应用中广泛使用。本示例主要探讨如何在...

Global site tag (gtag.js) - Google Analytics