使用Java操作xml文档

使用Java操作xml文档

DOM文档对象模型

DOM定义了访问和操作XML文档的标准方法,DOM把XML文档作文树结构来查看,能够通过DOM树来读写所有元素。

Dom4j

https://dom4j.github.io/

Dom4j是一个易用的、开源的库,用于解析XML。它应用于Java平台,具有性能优异、功能强大和极易使用的特点。

Dom4j将XML视为Document对象。

XML标签被Dom4j定义为Element对象。

xml数据hr.xml

<?xml version="1.0" encoding="UTF-8"?>
<hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="hr.xsd">
	<employee no="3309">
		<name>x1</name>
		<age>20</age>
		<salary>4000</salary>
		<department>
			<dname>会计部</dname>
			<address>XX大厦-B102</address>
		</department>
	</employee>
	<employee no="3109">
		<name>x2</name>
		<age>20</age>
		<salary>4000</salary>
		<department>
			<dname>会计部</dname>
			<address>XXX</address>
		</department>
	</employee>
	<employee no="4233">
		<name>x3</name>
		<age>22</age>
		<salary>3622</salary>
		<department>
			<dname>会计部</dname>
			<address>xx大楼-710</address>
		</department>
	</employee>
</hr>

hr.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
   <element name="hr">
<!--       complexType标签含义是复杂节点,包含子节点时必须使用这个标签-->
       <complexType>
<!--           sequence标签表示每个标签必须严格按顺序编写-->
           <sequence>
<!--            element节点最少出现一次,最多出现9999次 -->
               <element name="employee" minOccurs="1" maxOccurs="9999">
                   <complexType>
                       <sequence>
                           <element name="name" type="string"></element>
                           <element name="age">
                           <!-- 限制age的取值范围18-60 -->
                               <simpleType>
                                   <restriction base="integer">
                                       <minInclusive value="18"></minInclusive>
                                       <maxInclusive value="60"></maxInclusive>
                                   </restriction>
                               </simpleType>
                           </element>
                           <element name="salary" type="integer"></element>
                           <element name="department">
                               <complexType>
                                   <sequence>
                                       <element name="dname" type="string"></element>
                                       <element name="address" type="string"></element>
                                   </sequence>
                               </complexType>
                           </element>
                       </sequence>
<!--                       use=required表示no属性在任何employee中都是必须的-->
                       <attribute name="no" type="string" use="required"></attribute>
                   </complexType>
               </element>
           </sequence>
       </complexType>
   </element>
</schema>

读取Xml数据

package com.study.dom4j;

import java.io.File;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class HrReader {
	public void readXml() {
		File file = new File("src/hr.xml");
		SAXReader reader = new SAXReader(); 
		try {
			Document document = reader.read(file);
			//获取文档的根节点,即hr标签
			Element root = document.getRootElement();
			//elements方法用于获取指定的标签集合
			List<Element> employees = root.elements("employee");
			for(Element employee:employees) {
				//element方法用于获取唯一的子节点对象
				Element name = employee.element("name");
				//getText方法用于获取标签文本
				String empName = name.getText();
				System.out.println(empName);
				//方法2 elementText直接获取传入的标签参数文本
				System.out.println(employee.elementText("age"));
				System.out.println(employee.elementText("salary"));
				Element department = employee.element("department");
				System.out.println(department.elementText("dname"));
				System.out.println(department.elementText("address"));
				//获取属性
				Attribute att = employee.attribute("no");
				System.out.println(att.getText());
			}
			
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HrReader reader = new HrReader();
		reader.readXml();
	}

}

写入Xml数据

在写入数据的时候,不会校验dtd约束

package com.study.dom4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class HrWriter {
	public void writeXml() {
		File file = new File("src/hr.xml");
		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(file);
			Element root = document.getRootElement();
			Element employee = root.addElement("employee");
			employee.addAttribute("no", "4233");
			//方法一:创建标签添加到标签
			Element name = employee.addElement("name");
			name.setText("x3");
			//方法二:直接添加到标签中
			employee.addElement("age").setText("22");
			employee.addElement("salary").setText("3622");
			Element department = employee.addElement("department");
			department.addElement("dname").setText("会计部");
			department.addElement("address").setText("xx大楼-710");
			//结构内容定义好后写入文件,因为写入文件也需要异常检查,只需要将DocumentException的级别提示到Exception即可
			Writer writer = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
			document.write(writer);
			writer.close();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	public static void main(String[] args) {
		HrWriter writer = new HrWriter();
		writer.writeXml();
	}
}

XPath路径表达式

XPath路径表达式是XML文档中查找数据的语言。

掌握XPath可以极大的提高在提取数据时的开发效率。

学习XPath本质就是掌握各种形式表达式的使用技巧。

最常用的基本表达式

表达式 描述
nodename 选取此节点的所有子节点
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
选取当前节点的父节点。
@ 选取属性。

XPath基本表达式案例

路径表达式 结果
bookstore 选取bookstore元素的所有子节点。
/bookstore 选取根元素bookstore。注释:假如路径起始于正斜杠(/),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取所有book子元素,而不管它们在文档中的位置。
//book 选取所有book子元素,而不管它们在文档中的位置。
bookstore//book 选择属于bookstore元素的后代的所有book元素,而不管它们位于bookstore之下的什么位置。
//@lang 选取名为lang 的所有属性。

XPath谓语表达式

路径表达式 结果
/bookstore/book[1] 选取属于bookstore子元素的第一个book 元素。
/bookstore/book[last()] 选取属于bookstore子元素的最后一个book元素。
/bookstore/book[last()-1] 选取属于bookstore子元素的倒数第二个book 元素。
/bookstore/book[position()< 3] 选取最前面的两个属于bookstore元素的子元素的book元素。
//title[@lang] 选取所有拥有名为lang的属性的title元素。
//title[@lang=‘eng’] 选取所有title元素,且这些元素拥有值为eng 的lang属性。
/bookstore/book[price>35.00] 选取bookstore元素的所有book 元素,且其中的 price元素的值须大于35.00。
/bookstore/book[price>35.00]/title 选取bookstore元素中的 book元素的所有title元素,且其中的 price元素的值须大于35.00。

代码案例

package com.study.dom4j;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class XPathTestor {
	public void xpath(String xpathExp) {
		File file = new File("src/hr.xml");
		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(file);
			//返回xpathExp查询到的节点
			List<Node> nodes = document.selectNodes(xpathExp);
			for (Node node : nodes) {
				Element emp = (Element) node;
				System.out.println(emp.attributeValue("no"));
				System.out.println(emp.elementText("name"));
				System.out.println(emp.elementText("age"));
				System.out.println(emp.elementText("salary"));
				Element department = emp.element("department");
				System.out.println(department.elementText("dname"));
				System.out.println(department.elementText("address"));
				System.out.println("==================");
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		XPathTestor testor = new XPathTestor();
//		单斜杠从根节点开始,双斜杠表示从任意节点开始匹配
//		testor.xpath("/hr/employee");
//		testor.xpath("//employee");
//		指定条件筛选
//		testor.xpath("//employee[salary<4000]");
//		testor.xpath("//employee[name='x1']");
//		根据属性筛选
//		testor.xpath("//employee[@no=3309]");
//		第一个元素
//		testor.xpath("//employee[1]");
//		最后一个元素
//		testor.xpath("//employee[last()]");
//		按照范围筛选(前6个)
//		testor.xpath("//employee[position()<6]");
//		组合表达式
		testor.xpath("//employee[3] | //employee[1]");
	}

}
上一篇:Java基础——XML理解、解析、导入、导出


下一篇:Java 进阶day14XML Dom4j 工厂模式 Base64