JavaWeb--XML的解析(2)

一、DOM4J是什么

  1. DOM4J是针对Java开发人员专门提供的XML文档解析规范,它不同与DOM,但与DOM相似。DOM4J针对Java开发人员而设计,所以对于Java开发人员来说,使用DOM4J要比使用DOM更加方便。
  2. DOM4J同时对DOM和SAX提供了支持。

二、DOM4J依赖jar包

​ 因为DOM4J并非JavaSE中的API,因此使用Dom4j开发,需下载dom4j相应的jar文件。

三、DOM4J获得Document对象的方式

1.读取XML文件,获得document对象            
     SAXReader reader = new SAXReader();             
     Document document = reader.read(new File("input.xml"));

2.解析XML形式的文本,得到document对象.
      String text = "<members></members>";  
      Document document = DocumentHelper.parseText(text);

3.主动创建document对象.
      Document document = DocumentHelper.createDocument();       

四、DOM4J解析XML文件实例

现有如下xml文件:

<?xml version="1.0" encoding="UTF-8"?>

<person> 
  <p1 id="aaa"> 
    <name>zhangsan</name>  
    <age>300</age>  
    <gender>m</gender> 
  </p1>  
  <p1> 
    <name>lisi</name>  
    <age>30</age>  
    <gender>男</gender> 
  </p1> 
</person>

操作一:获取所有name标签中的文本值

public static void selectAll() throws Exception{
		//获取解析器
		SAXReader reader = new SAXReader();
		//获取document对象
		Document doc = reader.read("src/zuobiao/testDom4j/person.xml");
		//获取根标签
		Element root = doc.getRootElement();
		//获取所有的p1标签
		List<Element> p1s = root.elements("p1");
		//获取所有p1下面的name标签
		Element name = null;
		for(Element p1:p1s){
			name = p1.element("name");
			//获取name标签的文本值
			System.out.println(name.getText());
		}
}

所用方法:

SAXReader():通过调用该构造方法,来创建一个解析器对象
read():解析器调用该方法来获取解析后的文档
getRootElement():获取该xml文件的根标签
elements("标签名"):父标签调用该方法,获取所有指定标签名的子标签,返回一个List对象
element(("标签名"):父标签调用该方法,获取指定标签名的子标签,返回一个Element对象
getText():标签调用此方法,获取该标签的文本值

操作二:在第一个p1的最后添加一个gender标签

public static void addElementTest() throws Exception{
		//获取解析器对象
		SAXReader reader = new SAXReader();
		//获取解析后的document对象
		Document doc = reader.read("src/zuobiao/testDom4j/person.xml");
		//获取root
		Element root = doc.getRootElement();
		//获取第一个p1
		Element p1 = root.element("p1");
		
		//添加gender标签
		Element gender = p1.addElement("gender");	//在末尾加的时候,不用手动创建标签
		//给gender标签的文本值设置为男
		gender.setText("男");
		
		//回写操作
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);		
		//格式为:XMLWriter(OutputStream out, OutputFormat format) 
		writer.write(doc);
		writer.close();			//涉及到流的操作,一定要记得关闭
}

所用方法:

addElement("标签名"):父标签调用该方法,创建指定名称的标签,并将此标签添加进来
setText("文本内容"):标签调用此方法,设置自己的文本值
OutputFormat format = OutputFormat.createPrettyPrint():创建输出到XML后的格式
new XMLWriter(参数1, 参数2):创建回写对象
	- 参数1:输出流
	- 参数2:输出格式对象
write(文档对象):回写对象调用该方法,将修改后的文档对象写回到XML文件
writer.close():关闭输出流

操作三:第二个p1标签下的age标签前面添加school标签

public static void addBefore() throws Exception{
		//创建解析器对象
		SAXReader saxReader = new SAXReader();
		//获取解析后的document对象
		Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
		//获取root对象
		Element root = doc.getRootElement();
		//获取第二个p1标签
		List<Element> p1s = root.elements("p1");
		Element p1 = p1s.get(1);
		//获取p1标签下面的所有标签,返回为list
		List<Element> eles = p1.elements();
    
		//创建school标签
		Element school = DocumentHelper.createElement("school");
		//给school标签设置文本值
		school.setText("HUFE");
		//list调用add(int index, E element)方法插入标签
		eles.add(1, school);
    
		//写回
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
		xmlWriter.write(doc);
		xmlWriter.close();
}

所用方法:

DocumentHelper.createElement("标签名"):根据给定的标签名创建标签,并返回该标签对象
eles.add(1, school):此处是list调用add(int index, E element)方法在指定位置插入指定标签
注意:
	- 如果是在父标签末尾添加标签,则直接使用addElement("标签名")方法即可;
	- 但是如果实在父标签中的指定位置添加标签,则需要使用DocumentHelper.createElement("标签名")方法。因为需要 获取Element对象

操作四:修改第一个p1下面的age标签的文本值

private static void modifyAge() {
		//创建解析器对象
		SAXReader saxReader = new SAXReader();
		//获取解析后的document对象
		Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
		//获取根节点
		Element root = doc.getRootElement();
		//获取第一个p1
		Element p1 = root.element("p1");
		//获取age
		Element age = p1.element("age");
		//修改age标签的文本值
		age.setText("300");
		//回写
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
		xmlWriter.write(doc);
		xmlWriter.close();
}

使用方法:

setText("文本内容"):标签调用此方法,设置自己的文本值

操作五:删除第一个p1下面的school标签

public static void delSch(){
		//创建解析器对象
		SAXReader saxReader = new SAXReader();
		//获取解析后的document对象
		Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
		//得到root
		Element root = doc.getRootElement();
		//获取p1
		Element p1 = root.element("p1");
		//得到school
		Element school = p1.element("school");
		//删除
		p1.remove(school);
		//写回
		OutputFormat format = OutputFormat.createPrettyPrint();
		XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
		xmlWriter.write(doc);
		xmlWriter.close();
}

使用方法:

remove(标签对象):父标签调用此方法,删除指定子标签

操作六:获取第一个p1的id属性

private static void getValue() {
		//创建解析器对象
		SAXReader saxReader = new SAXReader();
		//获取解析后的document对象
		Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
		//得到root
		Element root = doc.getRootElement();
		//获取p1
		Element p1 = root.element("p1");
		//获取属性值
		String str = p1.attributeValue("id");
		System.out.println(str);
	}

所用方法:

attributeValue("属性名"):标签调用此方法获取指定属性名的属性值

五、DOM4J对XPath的支持

(一)什么是XPath

​ 要从 XML 文档中提取信息,最快捷简单的办法就是在程序中嵌入 XPath 表达式。XPath是一种为查询 XML 文档而设计的查询语言。

(二)XPath选择节点时常用的路径表达式

第一种形式
	/AAA/DDD/BBB: 表示一层一层的,AAA下面的DDD下面的BBB
第二种形式
	//BBB: 表示第二层中只要名称是BBB,都得到
第三种形式
	/*: 所有元素
第四种形式
	BBB[1]: 表示第一个BBB元素
	BBB[last()]:表示最后一个BBB元素
第五种形式
	//BBB[@id]: 表示第二层中只要BBB元素上面有id属性,都得到
第六种形式
	//BBB[@id='b1'] 表示第二层中名称是BBB,上面有id属性,并且id的属性值是b1的标签

(三)在DOM4J里面提供了两个方法,用来支持XPath

selectNodes("xpath表达式"):获取多个节点
selectSingleNode("xpath表达式"):获取一个节点

(四)DOM4J和XPath结合的实例(需要外部jar包)

操作一:获取所有的name标签

public static void selectAllName() {
		//创建解析器对象
		SAXReader saxReader = new SAXReader();
		//获取解析后的document对象
		Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
		
		//document对象使用selectNodes()
		List<Node> names = doc.selectNodes("//name");	//因为XPath也可以获取属性,所以返回值统一为Node
		
		//获取每个name标签的文本值
		for(Node name:names){
			System.out.println(name.getText());
		}
}

操作二:获取第一个p1标签下面的name标签的文本值

public static void selectSingleName(){
		//创建解析器对象
		SAXReader saxReader = new SAXReader();
		//获取解析后的document对象
		Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
		//获取第一个p1标签下面的name标签
		Node name = doc.selectSingleNode("//p1[@id='aaa']/name");
		//获取文本值
		System.out.println(name.getText());
}

Java新手,若有错误,欢迎指正!

posted @ 2020-04-10 18:16  跑调大叔!  阅读(129)  评论(0编辑  收藏  举报