您的位置:首页 > 编程语言 > Java开发

XML、Jaxp SAX解析、dom4j解析XML、XPath运用

2017-04-11 18:25 555 查看
1.Jaxp SAX解析

SAX是事件驱动的XML处理方法,一边扫描一边解析。SAX只能读取文件,并不能修改文件

import java.io.InputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Jaxp SAX解析
*/
public class JaxpSax {
public static void main(String[] args) throws Exception, SAXException {
// 获得工厂实例
SAXParserFactory factory = SAXParserFactory.newInstance();
// 获得解析器
SAXParser parser = factory.newSAXParser();
DefaultHandler dh = new MyDefautHandler();
// 解析XML文档
InputStream in = JaxpSax.class.getClassLoader().getResourceAsStream(
"books.xml");
parser.parse(in, dh);
}
}

class MyDefautHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
System.out.println("文档开始");
}
/**
* 如果XML文件使用了schema约束<xs:element>
* url:schema--targetNameSpace
* localName--element
* name--s:element
* 如果不使用
* url:null
* localName:null
* name:element
* Attributes:当前元素的所有的属性的集合
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("book".equals(qName)){
System.out.println("元素开始:"+qName+"::"+attributes.getValue("id"));
}
System.out.println("元素开始:"+qName);
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch,start,length));
}
@Override
public void endDocument() throws SAXException {
System.out.println("文档结束");
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("元素结束:"+qName);
}
}


2.dom4j解析XML

2.1dom4j解析XML

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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

public class Dom4JReader {
public static void main(String[] args) throws DocumentException {
List<Book> books = getAll();
for (Book book : books) {
System.out.println(book.getId() + "," + book.getAuthor() + ","
+ book.getTitle() + "," + book.getYear() + ","
+ book.getPrice());
}
}

public static List<Book> getAll() throws DocumentException {
List<Book> books = new ArrayList<Book>();
// 获得解析流
SAXReader reader = new SAXReader();
InputStream in = Dom4JReader.class.getClassLoader()
.getResourceAsStream("books.xml");
// XML文件的解析
Document doc = reader.read(in);
// 获得根元素
Element root = doc.getRootElement();
// 获得所有书籍
List list = root.elements();// 获得根元素下面所以元素
for (int i = 0; i < list.size(); i++) {
// 获得每一本书元素
Element bookElement = (Element) list.get(i);
Book book = new Book();
// 获得书籍的id属性值
String id = bookElement.attributeValue("id");
book.setId(id);
// 获得author、title和price、year
List childList = bookElement.elements();
// 遍历子元素
for (int j = 0; j < childList.size(); j++) {
// 获得每一个元素
Element child = (Element) childList.get(j);
// 元素名称
String name = child.getName();
String content = child.getTextTrim();
if (name.equals("author")) {
book.setAuthor(content);
}
if (name.equals("title")) {
book.setTitle(content);
}
if (name.equals("year")) {
book.setYear(content);
}
if (name.equals("price")) {
book.setPrice(Double.parseDouble(content));
}
}
books.add(book);
}
return books;
}
}


2.2使用XPath快速查询

XPath用于在XML文档中通过元素和属性进行导航,可用来在XML文档中对元素和属性进行遍历。

XPath使用路径表达式在XML文档中选取节点。节点是通过沿着路径或step来选取的。下面列出了最有用的路径表达式:

表达式				描述
nadename			选取此节点的所有子节点
/				从根节点选取
//				从匹配选择的当前节点选择文档中的节点,而不考虑其位置
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
举例一些路径表达式及表达式的结果

表达式					结果
/students/student			通过绝对路径获取students根节点下所有的直接子节点student元素对象
students/student			通过相对路径获取students根节点下所有的直接子节点student元素对象
//name					获取所以name元素对象,不考虑位置
student//name				获取student元素下所有name元素对象
//@id					获取所以的id属性对象
//student[@id]				获取所以带id属性的student元素对象
//student[@id='002']			获取id等于002的student元素对象
//student[age>20]			获取所有子元素age的值大于20的student元素对象

通过XPath查询节点主要有两个方法:

获取所以符合条件的节点:selectNodes(String xpathExpression)返回list集合
获取符合条件的单个节点,(如果符合条件的节点有多个,那么返回第一个):selectSingleNode(String xpathExpression)返回一个Node对象

2.3dom4j对XMl文件进行增删查改、XPath的运用

package com.song._17xml;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
* 1.通过XPath查询books.xml中id为002的元素
* 2.dom4j保存XML
* 3.dom4j修改XML
* 4.dom4j删除XML元素
* 5.dom4j添加XML元素
*/
public class XPathDemo {
public static void main(String[] args) throws DocumentException, IOException {
//1.获得解析流
SAXReader reader = new SAXReader();
InputStream in = Dom4JReader.class.getClassLoader().getResourceAsStream("books.xml");
//2.XML文件的解析
Document doc = reader.read(in);
//保存XML
//		dom4jSave(doc
4000
);
//修改xml
//		dom4jUpdate(doc);
//删除XML元素
//		dom4jDelete(doc);
//添加元素
dom4jAddElement(doc);
//3.查询book ID=002的元素
Node node = doc.selectSingleNode("//book[@id='002']");
Element ele = (Element) node;
List<Element> bookElements = ele.elements();//获取该元素下所有直接子元素
for (Element element : bookElements) {
String name = element.getName();//获取元素名
String value = element.getText();//获取值
System.out.println(name+"="+value);
}
}
/*
* dom4j保存XML步骤
* 1.获得解析流
* 2.通过解析六获取Document对象
* 3.创建文件的输出位置
* 4.创建XMLWriter对象
* 5.调用XMLWriter的write方法,将Document对象写进去
* 6.关闭XMLWriter对象
*/
private static void dom4jSave(Document doc) throws IOException{
//3.创建出文件输出的位置
FileOutputStream out = new FileOutputStream("books.dom4j.xml");
XMLWriter writer = new XMLWriter(out);
//添加内容到对象
writer.write(doc);
//关闭流
writer.close();
}
/*
* 使用dom4j修改元素的思路:
* 1.获取Document对象
* 2.通过XPath查找需要修改的节点
* 3.找到该节点,调用setText方法设置值
* 修改books.xml中id为002的元素,将其中的price修改为100
*/
private static void dom4jUpdate(Document doc) throws IOException{
Element ele = (Element) doc.selectSingleNode("//book[@id='002']/price");
ele.setText("100");
dom4jSave(doc);
}
//
private static void dom4jDelete(Document doc) throws IOException{
Element ele = (Element) doc.selectSingleNode("//book[@id='002']/title");
ele.getParent().remove(ele);
dom4jSave(doc);
}
//添加id=004的book
private static void dom4jAddElement(Document doc) throws IOException{
//获取根元素
Element element = doc.getRootElement();
//创建book元素
Element bookEle = DocumentHelper.createElement("book");
//设置属性
//		bookEle.setAttributeValue("id", "004");//不推荐使用,所以换下面种
Attribute bookAttr = DocumentHelper.createAttribute(bookEle, "id", "004");//创建属性
bookEle.add(bookAttr);
Element authorEle = DocumentHelper.createElement("author");
authorEle.setText("老王");
bookEle.add(authorEle);
Element titleEel = DocumentHelper.createElement("title");
titleEel.setText("王老吉");
bookEle.add(titleEel);
element.add(bookEle);
dom4jSave(doc);
}
}

3.小结

解析XML的几大主流技术,分别是Jaxp Dom解析、Jaxp Sax解析及dom4j解析,其中:

Jaxp Dom解析插入元素速度较快,但是读取速度较慢。
Jaxp Sax 解析只能读取,但是读取速度比较快。
dom4j是当前比较主流的解析XML技术,API相对简单,通俗易懂。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java XMl dom4j XPath Jaxp Sax