XML总结——XML解析


XML解析

一、XML解析

  • XML解析方式分为两种:dom和sax
    • dom:(Document Object Model,即文档对象模型),处理XML的一种方式
    • sax:(Simple API for XML)不是官方标准,但它是XML社区事实上的标准几乎所有的XML解析器都支持它。
  • XML解析开发包
    • Jaxp、Jdom、dom4j

1、DOM解析

DOM模型

DOM解析器在解析XMl文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。

优点:把Xml文件在内存中构造树形结构,可以遍历和修改节点

缺点:如果文件比较大,内存有压力,解析的实际时间比较长

DOM编程步骤

  • 调用DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂。

  • 调用工厂对象的newDocumentBuilder方法得到DOM解析器对象。

  • 调用DOM解析器对象的parse()方法解析XML文档,得到代表整个文档的Document对象,就可以利用DOM特性对整个XMl文档进行操作了。

代码:
MyXml.xml

<?xml version="1.0" encoding="UTF-8"?>
<employees>
	<employee id="0">
		<name>Alexia</name>
		<age>23</age>
		<sex>Female</sex>
		<weight>150</weight>
		<weight><a>160</a></weight>
	</employee>
	
	<employee id="1">
		<name height="178">Edward</name>
		<age>24</age>
		<sex>Male</sex>
	</employee>
	
	<employee id="2">
		<name>Tom</name>
		<age>20</age>
		<sex>Female</sex>
	</employee>
	
	<employee id="3">
		<name>Admin</name>
		<age>21</age>
		<sex>Male</sex>
	</employee>
</employees>

DOMXml.java

import javax.xml.parsers.*;

import org.w3c.dom.*;

/* 
 * Dom解析XML
 * 
 * @author USE
 */
public class DOMXml {
	public static void main(String[] args) throws Exception {
		//获得创建DOM解析器的工厂
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		//设置由此工厂生成的解析器,忽略注释
		dbf.setIgnoringComments(true);
		//忽略空格
		dbf.setIgnoringElementContentWhitespace(true);
		//调用工厂对象的方法获取DOM解析器对象
		DocumentBuilder builder = dbf.newDocumentBuilder();
		//调用DOM解析器对象解析XML文档,获取文档Document
		Document doc = (Document) builder.parse("src/com/MyXml.xml");
		//获得根节点
		Element root = doc.getDocumentElement();
		System.out.println(root.getTagName());
		//根据标签名获得结点
		NodeList nodeList = doc.getElementsByTagName("employee");
		System.out.println("employess节点的个数:"+nodeList.getLength());
		//遍历nodeList
		for(int i=0;i<nodeList.getLength();i++){
			Element element = (Element)nodeList.item(i);
			//获得id属性值
			String attribute = element.getAttribute("id");
			System.out.println("id:" + attribute);
			//获取第一个employee
			if(i==0){
				//获得元素下面的name文本
				System.out.println("name文本值:" + element.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
				//获得元素下面的sex文本
				System.out.println("sex文本值:" + element.getElementsByTagName("sex").item(0).getFirstChild().getNodeValue());
				//获得元素下面的age文本
				System.out.println("age文本值:" + element.getElementsByTagName("age").item(0).getFirstChild().getNodeValue());
				//获得第一个weight的文本值
				System.out.println("weight文本值:" + element.getElementsByTagName("weight").item(0).getFirstChild().getNodeValue());
				//获得第二个weight里a标签的文本值
				System.out.println("weight的a文本值:" + element.getElementsByTagName("weight").item(1).getFirstChild().getFirstChild().getNodeValue());
			}	
		}
	}
}

2、SAX解析

SAX解析

在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构架代表整个DOM树的Doucment对象,从而再对XML文档进行操作;SAX解析允许在读取文档时,即对文档进行不理,而不必等到整个文档装载完才会对文档进行处理

优点:解析可以立即开始,速度快,没有内存压力

缺点:不能对节点做修改

SAX编程步骤

  • 使用SAXParserFactory创建SAX解析工厂
    • SAXParerFactory spf = SAXParerFactory.newInstance();
  • 通过SAX解析工厂得到解析器对象
    • SAXParser sp = spf.newSAXParser();
  • 通过解析器对象得到一个XML的读取器
    • XMLReader xmlReader = sp.getXMLReader();
  • 设置读取器的事件处理器
    • xmlReader.setContentHandler(new BookParserHandler());
  • 解析xml文件
    • xmlReader.parse("book.xml");

代码:
SAXXml.java

import java.io.File;
import javax.xml.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
/**
 - 
 - @author USE
 */
public class SAXXml extends DefaultHandler{
	//在解析整个文档开始时被调用
	@Override
	public void startDocument() throws SAXException {
		System.out.println("开始文档");
	}
	//在解析整个文档结束时被调用
	@Override
	public void endDocument() throws SAXException {
		System.out.println("结束文档");
	}
	//在解析元素开始时被调用
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		System.out.println("开始解析元素:" + qName);
	}
	
	public static void main(String[] args) throws Exception{
		//创建一个sax解析工厂
		SAXParserFactory spf = SAXParserFactory.newInstance();
		//创建解析器名称
		SAXParser saxParser = spf.newSAXParser();
		//创建File指明要解析的xml
		File file = new File("src/com/MyXml.xml");
		//解析XML文件
		saxParser.parse(file, new SAXXml());
	}
	
}

3、Dom4j解析xml

Dom4j解析

  • Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
  • Dom4j是一个非常优秀的Java XML API、具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j。
  • 使用Dom4j开发,需下载dom4j相应的jar文件。

Dom4j编程-查询增加节点及属性
需要dom4j-1.6.1.jar; jaxen-1.1-beta-8.jar; jdom-1.0.jar

代码示例:
EmpList.xml

<?xml version="1.0" encoding="UTF-8"?>
<list>
	<emp id="0">
		<name>张三</name>
		<age>34</age>
		<gender></gender>
		<salary>3000</salary>
	</emp>
	<emp id="1">
		<name>王五</name>
		<age>18</age>
		<gender></gender>
		<salary>6500</salary>
	</emp>
	<emp id="2">
		<name>赵六</name>
		<age>28</age>
		<gender></gender>
		<salary>4400</salary>
	</emp>
	<emp id="3">
		<name>小明</name>
		<age>20</age>
		<gender></gender>
		<salary>3300</salary>
	</emp>
</list>

Emp.java(对象封装类)

public class Emp {
	private int id;
	private String name;
	private int age;
	private String gender;
	private double salary;
	/**
	 * 构造方法
	 */
	public Emp() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public Emp(int id, String name, int age, String gender, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.salary = salary;
	}

	
	/**
	 * get/set方法
	 * @return
	 */
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
	/**
	 * toString方法
	 */
	@Override
	public String toString() {
		return "Emp [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + "]";
	}	
}

TestDomFJ.java

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

import com.entity.Emp;

public class TestDomFJ {
	public static void main(String[] args) throws Exception {
		//创建SAXReader解析器
		SAXReader reader = new SAXReader();
		//指明解析的文件,解析文件,获得document文档
		Document doc = reader.read(new File("src/com/EmpList.xml"));
		//获得根节点
		Element root = doc.getRootElement();
		//获得根节点下所有子节点
		List<Element> elements = root.elements();
		//创建List<Emp>保存所以员工对象
		List<Emp> list = new ArrayList<Emp>();
		//遍历子节点
		for(Element element : elements){
			//获取节点的属性
			String id = element.attribute("id").getValue();
			//获得节点及节点值
			//element.elementText("name");
			String name = element.element("name").getText();
			String age = element.elementText("age");
			String gender = element.elementText("gender");
			String salary = element.elementText("salary");
			Emp emp = new Emp(Integer.parseInt(id),name,Integer.parseInt(age),gender,Double.parseDouble(salary));
			list.add(emp);
		}
		//输出list
		System.out.println(list);
	}
	/**
	 * 创建文档,添加节点
	 * 添加子节点,addElement()
	 * 添加文本值,addText()
	 * 添加子节点并设置文本,addElement().addText()
	 * 添加属性,使用addAttribute( , )
	 * 
	 * @throws Exception
	 */
	@Test
	public void testAdd() throws Exception{
		//list存放Emp对象
		List<Emp> emps = new ArrayList<Emp>();
		emps.add(new Emp(1,"张三",33,"男",9000.0));
		emps.add(new Emp(2,"李四",25,"男",5000.0));
		emps.add(new Emp(3,"王五",20,"男",4000.0));
		//创建一个文档对象
		Document doc = DocumentHelper.createDocument();
		//创建根节点
		Element root = doc.addElement("list");
		
		for(Emp emp : emps){
			//向根元素中添加名为emp的子元素
			Element ele = root.addElement("emp");
			//为emp元素添加id属性
			ele.addAttribute("id", emp.getId()+"");
			//添加子节点并设置节点中的文本值
			ele.addElement("name").addText(emp.getName());
			ele.addElement("age").addText(emp.getAge()+"");
			ele.addElement("gender").addText(emp.getGender());
			ele.addElement("salary").addText(emp.getSalary()+"");
		}
		//通过XMLWriter生成物理文件
		//创建输出流,执行输出路径
		FileOutputStream fos = new FileOutputStream("src/com/EmpList1.xml");
		XMLWriter writer = new XMLWriter();
		writer.setOutputStream(fos);
		//将文档写出到指定路径中
		writer.write(doc);
		//关闭流
		writer.close();
	}
}

dom4j编程-删除修改节点及属性

TestDomFJ.java

/**
	 * 删除节点
	 * @throws Exception
	 */
	@Test
	public void testRemove() throws Exception{
		//使用SAXReader读取文档
		SAXReader saxReader = new SAXReader();
		Document doc = saxReader.read("src/com/EmpList.xml");
		//获取根节点
		Element root = doc.getRootElement();
		Element element = (Element) root.elements().get(1);
		System.out.println(element.attribute("id"));
		//为节点删除属性
		element.remove(element.attribute("id"));
		System.out.println(element.attribute("id"));
		Element name = element.element("name");
		System.out.println(name.getText());
		//将name节点删除
		element.remove(name);
		System.out.println(element.element("name").getText());
	}
	
	/**
	 * 修改
	 * @throws Exception
	 */
	@Test
	public void testUpdate() throws Exception{
		SAXReader sax = new SAXReader();
		Document doc = sax.read("src/com/EmpList1.xml");
		//获取跟节点
		Element root = doc.getRootElement();
		Element e2 = (Element)root.elements().get(1);
		Attribute id = e2.attribute("id");
		System.out.println(id.getValue());
		//修改id属性值
		id.setValue("20");
		System.out.println(id.getValue());
		//获取name节点
		Element name = e2.element("name");
		System.out.println(name.getText());
		//修改name的文本值
		name.setText("张全蛋");
		System.out.println(name.getText());
	}
发布了22 篇原创文章 · 获赞 14 · 访问量 1176

猜你喜欢

转载自blog.csdn.net/weixin_44157233/article/details/104001363