测试之路3——对比XML文件2

距离上一篇对比xml文件隔了很久,并不代表一直做了那么久。

其实上一次对比xml文件一直出错,其实我忽略了一个很简单的问题:我从根目录下得到的所有孩子,是这个根下的,而xml文件的组织形式如下,孩子也有可能是其他的根:

<streams>
    <stream id = "979" presetid = "-1">
        <h264>
            <profile>High</profile>
            <par_y>-1</par_y>
            <fr>source</fr>
            <cqquantizer>0</cqquantizer>
            <deviceid>0</deviceid>
            <qualitylevel>0</qualitylevel>
            <simhd>
                <deblock>0</deblock>
                <deinterlace>2</deinterlace>
                <denoise>0</denoise>
                <delight>0</delight>
                <saturation>0</saturation>
                <hue>0</hue>
            </simhd>
        </h264>
        <aac>
            <profile>LC</profile>
            <channel>1</channel>
            <bitrate>12000</bitrate>

        </aac>
    </stream>
</streams>

这里可以把streams当做所有的根,但是它下面有stream,stream下面还有h264和aac两个节点,h264又有很多节点 ,而h264本身并没有参数值。

所以我得到的children只是得到stream,我需要遍历孩子,直到它没有某个孩子不再有孩子,再返回。

这么想来,是自己以前学数据结构学的不好,我实际要做的就是遍历树的每一片叶子。于是,我开始遍历整个xml树了。

可是我该怎么遍历,还是像数据结构上说的那样,先根,中根,后根?其实,我并不需要一起去遍历两个xml树,我只要遍历一个xml树(源文件),然后去比对目标文件的xml树就可以了。因为我发现,这我这里目标文件的叶子比源文件的多;且目标文件的叶子在一般情况下都包括目标文件。所以我以源文件为参照物,去寻找目标文件是否存在该节点,如果不存在,则错误;再去比对参数,如果参数不同,则错误。

xml文件中可能存在名字相同,但是实际位置不同的节点,所以对比的节点必须相对位置也相同,所以这也降低了对比难度。所以我可以简单写出对比的测试程序:

	//简单对比方法:
	//传递参数:源文件,返回的目标文件
	//返回值:true表示XML对比一样
	//修改日期:2014.5.26  tanlee
	//对比策略:如果源文件有标签,寻找目标文件是否有对应标签,个数如果不相同
	public boolean simpleCompare(Document sourceDoc,Document targetDoc)
	{
		Element sourceRoot = sourceDoc.getDocumentElement();

		HashSet<String> sourceSet =new HashSet<String>();
		HashSet<String> sourceNames = getNodeNames(sourceRoot,sourceSet);//将所有标签元素提取出来,建立哈希表,方便寻找所有标签

		Iterator<String> sIterator=sourceNames.iterator();//迭代器去遍历

		while(sIterator.hasNext())   //遍历所有源文件的标签
		{
			String sName = sIterator.next();  //遍历迭代器得到相应的标签名字
			NodeList snodeList1 = sourceDoc.getElementsByTagName(sName);//根据名字寻找对应的子节点
			int length1 = snodeList1.getLength();
			NodeList snodeList2 = targetDoc.getElementsByTagName(sName);//根据源文件中的标签寻找对应的
			int length2 = snodeList2.getLength();;
			if(length1 < length2)//当源文件长度小于目标文件,进行判断
			{
//				System.out.println("节点的元素个数不同:" + " " + sName + " " + "源文件个数:"
//				+ length1 + "    " + "目标文件个数:" + length2 );
				for(int i = 0,j = 0;i < length1;i++) //对nodelist1进行遍历
				{
					String ssValue = new String("cao");
					String tValue = new String("cao");
					ssValue = sourceDoc.getElementsByTagName(sName).item(i).getFirstChild().getNodeValue();

					for(j =0;j < length2;j++)//内部循环对比,如果找不到和它相等的值,返回错误
					{
						tValue = targetDoc.getElementsByTagName(sName).item(j).getFirstChild().getNodeValue();
						if(ssValue != null && ssValue != null && ssValue.equals(tValue))//表示找不到
						{
							break;
						}
						else if(ssValue == null && tValue == null)
						{
							break;
						}
					}
					if(j == length2)  //到达循环次数,还是没有找到,说明没有值对应,可以返回错误
					{
						System.out.println("没有找到标签对应的值");
						return false;
					}
				}
			}
			else if(length1 == length2) //长度相同的情况下,进行对比,对比的条件是,如果目标文件能找到且值相同则返回true
			{
				for(int i = 0;i < length1;i++) //对nodelist1进行遍历
				{
					String ssValue = new String(" ");
					String tValue = new String(" ");
					//如果找不到该节点
					if(targetDoc.getElementsByTagName(sName).item(i).getFirstChild() == null )
					{
						if(sourceDoc.getElementsByTagName(sName).item(i).getFirstChild() != null )
						{
							System.out.println("源文件有该标签,而目标文件没有");
							return false; //如果源文件有节点
						}
						else
							break;
					}
					ssValue = sourceDoc.getElementsByTagName(sName).item(i).getFirstChild().getNodeValue();
					tValue = targetDoc.getElementsByTagName(sName).item(i).getFirstChild().getNodeValue();
					if(ssValue != null&&!ssValue.equals(tValue))//表示找不到
					{
//						System.out.println("Error");
						return false;
					}
					else
					{
						//System.out.println(ssValue);
					}
				}
			}
			else
			{
				System.out.println("目标文件节点长度小于源文件节点长度");
				return false ; //其他情况就是目标文件的节点长度小于源文件的节点长度,即找不到对应节点,直接返回错误
			}
		}
		return true;
	}

不过,返回的结果都是false,这让我惊呆了,难道是我又写错了?我只能把遍历到的节点输出来,果真节点都不在,这是什么原因?

老大这个时候提醒了我,解析xml的时候需要把xml文件进行格式化,我把源文件和目标文件导出来看一看,一个是3KB,另一个是5KB,很显然就算某些元素信息有差别,文件大小也不会相差如此之大,所以我打开看了一下:源文件没有空格和回车,而目标文件有很多空格和回车,我于是理解他们的格式是不一样的。

需要自己去标准化吗?好像不用了,里面已经写好了方法。是用正则,我不是很懂,至少用了再去学吧,代码如下:

	//标准化传入的XML文件的字符串
	//传递参数:源文件的String,返回的true
	//返回值:修改过的String
	//修改日期:2014.5.29  tanlee
	public String standardXML(String xml)
	{
		xml = xml.replace("\r\n", "").replaceAll("(?<=>)\\s+(?=<)", "");
		return xml;
	}

这样就基本实现了功能,终于能返回一些true了,通过人工对比发现自己的自动化测试程序虽然简单,但还是能实现功能的。

但是,问题又来了,怎么给自己的源文件添加新的标签,以适应服务器那边增加的参数?看来改进的地方还很多,只能下次再改了。

测试之路3——对比XML文件2,布布扣,bubuko.com

时间: 2024-10-21 04:03:02

测试之路3——对比XML文件2的相关文章

测试之路2——对比XML文件1

才来几天,老大又给了我一个新的任务.不像以前的建100个任务工程那么坑爹,却还是顿时让我感觉压力山大. 因为在这之前,我改了他写的例程,用于生成新的任务项目,其实任务项目就是通过XML文件进行参数传递,底层早已经封装好了.但是问题出来了,你新建任务需要传过去一个XML文件,但是服务器端生成任务还会返回一个XML文件,而我对于服务器端并不了解,我只知道服务器生成了一个XML文件,但是它生成的XML中的参数是否和我传过去的参数相同? 所以老大要我写一个方法,去比对这两份XML文件.(自己传到服务器和

測试之路2——对照XML文件1

才来几天,老大又给了我一个新的任务.不像曾经的建100个任务project那么坑爹,却还是顿时让我感觉压力山大. 由于在这之前,我改了他写的例程,用于生成新的任务项目,事实上任务项目就是通过XML文件进行參数传递,底层早已经封装好了.可是问题出来了,你新建任务须要传过去一个XML文件,可是server端生成任务还会返回一个XML文件,而我对于server端并不了解,我仅仅知道server生成了一个XML文件,可是它生成的XML中的參数是否和我传过去的參数同样? 所以老大要我写一个方法,去比对这两

Java修炼之路——读取XML文件

这次来跟记录下java下如何操作xml文件.其实用过python去爬虫的话,那么应该很容易上手.java中有一个库dom4j就跟python中的lxml类似. 这里要重点强调下,在使用dom4j库的时候,其实它还有一个依赖包,就是jaxen.不添加的可是会报错的.(dom4j和jaxen的下载链接都整理好了在底部) 这里主要就是讲讲怎么用dom4j来读取的xml文件(可以直接从网络上加载,或者本地) //这个是官网上copy的,直接从加载文件 public class Foo { public

笔记:MyBatis Mapper XML文件详解 - 映射和参数

MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码.MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好. SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序): cache – 给定命名空间的缓存配置. cache-ref – 其他命名空间缓存配置的引用. resultMap – 是最复杂也是最强大的元素,用来描述

android XML文件注释应该注意些什么

android的XML文件注释一般采用 <!--注释内容 -->的方式进行,但是有时候却不能进行注释,如 在XML中,形如    <Button           />      的表示方式,其中“/>”的含义表示这个XML中没有内文,他是一个最小组成单元,也就是说他的中间不能包含其他任何< >的代码,所以在<Button />中间注释会出现错误 对比整个XML文件,我们为什么可以在其中间注释呢,看代码 注意看到,在注释的前面有一个“>”符号,

AS3操作XML文件

好久没有写AS3程序了...马丹连个xml读取都不会了快.. 下面是一个很好的例子,自己使用Flex biulder刚写的: 代码如下: package { import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; public class TestXml extends Sprite { private var lod:URLL

Spring 3.0 学习-DI 依赖注入_创建Spring 配置-使用一个或多个XML 文件作为配置文件,使用自动注入(byName),在代码中使用注解代替自动注入,使用自动扫描代替xml中bea

文章大纲 在xml中声明bean和注入bean 在xml中声明bean和自动注入bean 自动扫描bean和自动注入bean 对自动扫描bean增加约束条件 首次接触spring请参考 Spring 3.0 学习-环境搭建和三种形式访问 1.典型的Spring XML 配置文件表头 <?xml version="1.0" encoding="UTF-8"?><!-- 一般化的Spring XML 配置 --> <beans xmlns=

android基础知识13:AndroidManifest.xml文件解析

1.重要性 AndroidManifest.xml是Android应用程序中最重要的文件之一.它是Android程序的全局配置文件,是每个 android程序中必须的文件.它位于我们开发的应用程序的根目录下,描述了package中的全局数据,包括package中暴露的组件 (activities, services, 等等),以及他们各自的实现类,各种能被处理的数据和启动位置等重要信息. 因此,该文件提供了Android系统所需要的关于该应用程序的必要信息,即在该应用程序的任何代码运行之前系统所

利用XPath读取Xml文件

之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素.可以把XPath比作文件管理路径:通过文件管理路 径,可以按照一定的规则查找到所需要的文件:同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点. 不过,由于XPath可应用于不止一个的标准,因此W3C将其独立出来作为XSLT的配套标准颁布,它是XSLT以及我们后面要讲到的XPointer的重要组成部分. 在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基