dom4j 解析xml文件(涉及知识点:dom4j,XPath,递归)


涉及知识点 :dom4j, XPath, 递归

知识点:

节点是比元素更大一层的概念, 元素节点仅仅是节点中的一种.

元素,属性,名字空间,注释,文本内容,处理指令,还有整个文档(即看成根节点),这7种都是节点。那么元素节点仅仅是其中的一种。

XML解析:

    * 解析xml可以做:
        * 如果xml作为配置文件:读取
        * 如果xml作为传输文件:写,读
    * xml解析思想:
        * DOM:将文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为一些对象。
            * 优点:因为,在内存中会形成dom树,可以对dom树进行增删改查。
            * 缺点:dom树非常占内存,解析速度慢。
        
            Document
            Element
            Text
            Attribute
            Comment
        * SAX:逐行读取,基于事件驱动
            * 优点:不占内存,速度快
            * 缺点:只能读取,不能回写
        
    * xml常用的解析器:
        * JAXP:sun公司提供的解析。支持dom和sax。
        * JDOM:
        * DOM4Jdom for java民间方式,但是是事实方式。 非常好。   支持dom
            1.导入jar包 dom4j.jar
            2.创建解析器
                SAXReader reader = new SAXReader();
            3.解析xml 获得document对象
                Document document = reader.read(url);
    * XPATH: 基于路径的解析,  ----->  专门用于查询
                * 定义了一种规则。
                * 使用的方法:(只有两个)
                    * selectSingleNode():
                    * selectNodes():
            使用步骤:
                1、注意:要导包 jaxen...jar
                2、创建解析器
                    SAXReader reader = new SAXReader();
                3、解析xml 获得document对象
                    Document document = reader.read(url);


注意:

使用Dom4j需要到1个依赖 dom4j

Jaxen is a universal Java XPath engine.
使用XPath,要导两个依赖 dom4j  和  jaxen


----------------------------------------------------------------------------------------------------------------------------------------------------



本案例使用maven构建一jar工程:


pom文件只添加了两个依赖:

  	<dependency>
  		<groupId>dom4j</groupId>
  		<artifactId>dom4j</artifactId>
  		<version>1.6.1</version>
  	</dependency>
  	
	<dependency>
	    <groupId>jaxen</groupId>
	    <artifactId>jaxen</artifactId>
	    <version>1.1.6</version>
	</dependency>


素材:books.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<books group="pager">
      <!--第一本书-->
      <book id="1001" class="shu">
            <name>java葵花宝典</name>
            <author>张三</author>
            <price>9.9</price>
      </book>
      <!--第二本书-->
      <book id="1002" class="shu">
            <name>java葵花宝典(第二部)</name>
            <author>李四</author>
            <price>999.9</price>
      </book>
      That's all!
</books>


测试类TestDom4jParse:

测试方法:testPath:-->测试XPath的用法

	/**
	 * 获得第二本书的作者
	 * @throws DocumentException
	 */
	@Test
	public void testXPath() throws DocumentException {
		//创建SAX读取器
		SAXReader reader=new SAXReader();
		//获得document对象
		Document document = reader.read("src\\test\\resources\\books.xml");
		Node node = document.selectSingleNode("/books/book[2]/author");// path(节点基于路径化去找)
		System.out.println(node.getText());
	}

测试结果:

李四

测试方法:testPath2:-->测试XPath的用法

	/**
	 * 遍历所有开始标签
	 * @throws DocumentException
	 */
	@Test
	public void testXPath2() throws DocumentException {
		SAXReader reader=new SAXReader();
		Document document = reader.read("src\\test\\resources\\books.xml");
		List nodes = document.selectNodes("//*");
		for (int i = 0; i < nodes.size(); i++) {
			Node node=(Node) nodes.get(i);
			System.out.println(node.getName()+"="+node.getText());
		}
	}
运行结果:




测试方法:testGetAll() --->前戏: 证明节点和Element不是姨妈事

	@Test
	public void testGetAll() throws DocumentException {
		//创建SAX读取器
		SAXReader reader=new SAXReader();
		//获得document对象
		Document document = reader.read("src\\test\\resources\\books.xml");
		//获得根元素
		Element rootElement = document.getRootElement();
		
		System.out.println(rootElement.attributeCount()); //0
		//遍历根元素的属性
		for (int i = 0; i < rootElement.attributeCount(); i++) {
			Attribute attribute = rootElement.attribute(i);
			System.out.println(attribute.getName()+"="+attribute.getValue());
		}
		System.out.println("rootElement:"+rootElement.getName()+"="+rootElement.getText().trim());//去两头空白
		
		System.out.println("----------------------------------------");
		System.out.println(rootElement.nodeCount()); //9
		System.out.println(rootElement.elements().size());  //2
		System.out.println("--------------可见node和element是有区别的---------------");
		List elements = rootElement.elements();
		for (int i = 0; i < elements.size(); i++) {
			Element childElement = (Element) elements.get(i);
			System.out.println("childElement:"+childElement.getName()+"="+childElement.getText());
		}
	}

测试结果:



测试方法:testGetAll2() --->正式开始 (用到了递归)

	@Test
	public void testGetAll2() throws DocumentException {
		//创建SAX读取器
		SAXReader reader=new SAXReader();
		//获得document对象
		Document document = reader.read("src\\test\\resources\\books.xml");
		//获得根元素
		Element rootElement = document.getRootElement();
		//根元素的文本内容
		System.out.println("rootElement的文本内容:"+rootElement.getName()+"="+rootElement.getText().trim());
		List attributes = rootElement.attributes();
		if (attributes.size()>0) {
			for (int i = 0; i < attributes.size(); i++) {
				// 返回值类型 Object
				Attribute attribute=(Attribute) attributes.get(i);
				System.out.println("rootElement:"+attribute.getName()+"="+attribute.getValue());
			}
		}
		
		treewalk(rootElement);
		
		
	}
	
	//元素递归
	public void treewalk(Element element) {
		if (element.elements().size()>0) {
			List elements = element.elements(); 
			for (int i = 0; i < elements.size(); i++) {
				//返回值类型 Object
				Element childElement=(Element) elements.get(i);
				System.out.println("childElement的文本内容:"+childElement.getName()+"="+childElement.getText().trim());
				List attributes = childElement.attributes();
				if (attributes.size()>0) {
					for (int j = 0; j < attributes.size(); j++) {
						//返回值类型 Object
						Attribute attribute = (Attribute) attributes.get(j);
						System.out.println(attribute.getName()+"="+attribute.getValue());
					}
				}
				if (childElement.elements().size()>0) {
					treewalk(childElement);
				}
			}
		}else {
			// 结束 ---- 递归结束条件
		}
	}	

测试结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值