Java解析XML文档的几种方式

SAX解析

SAX允许在读取XML文档时就对文档进行处理,而不必等到整个文档装载完才会进行操作。
SAX采用事件处理的方式解析XML文件,利用SAX解析XML文档,比较重要的两个点是解析器和事件处理器。

SAX解析XML文档步骤
  • 创建解析工厂;
  • 得到解析器 ;
  • 获取读取器;
  • 设置内容处理器;
  • 读取XML文档
实际案例

book.xml

<?xml version="1.0" encoding="UTF-8"?>
<书架>
	<><书名  aa="bbb">Android技术开发大全</书名>
		<作者>Michael Main</作者>
		<售价>59</售价>
	</>
	<>
		<书名>Effective Java</书名>
		<作者>Ed Burnette</作者>
		<售价>68</售价>
	</>
</书架>

用SAX解析book.xml文档,并用JavaBean封装

package cn.moving.parseXml;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParse2 {
	public static void main(String args[]) throws Exception, SAXException {
		// 创建解析工厂
		SAXParserFactory sf = SAXParserFactory.newInstance();
		// 创建解析工厂得到解析器 获取读取器设置内容处理器读取XML文档
		SAXParser parser = sf.newSAXParser();
		// 获取读取器
		XMLReader reader = parser.getXMLReader();
		// 设置内容处理器
		reader.setContentHandler(new Handler());
		// 读取XML文档
		reader.parse("src/book.xml");
	}
}

class Handler extends DefaultHandler {
	
	private String currentTag ;
	private int needNumber = 2;
	private int currentNumber = 1;

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		currentTag = qName;
		if (("作者".equals(currentTag) )) {
			currentNumber++;
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if(currentNumber == 2&¤tTag.equals("作者")){
			System.out.println(new String(ch, start, length));
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
	
	}

}

将解析出来的节点,用JavaBean对象封装起来,便于进行持久操作

package cn.moving.parseXml;

import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class SAXAndBean {
	public static void main(String args[]) throws Exception, SAXException {
		// 创建解析工厂
		SAXParserFactory sf = SAXParserFactory.newInstance();
		// 得到解析器
		SAXParser parser = sf.newSAXParser();
		// 获取读取器
		XMLReader reader = parser.getXMLReader();
		// 设置内容处理器
		BeanListHandler lh = new BeanListHandler();
		reader.setContentHandler(lh);
		// 读取XML文档
		reader.parse("src/cn/moving/parseXml/outbook.xml");

		List<Book> books = lh.getBooks();
		System.out.println(books);
	}
}

class BeanListHandler extends DefaultHandler {

	private List<Book> list = new ArrayList<Book>();
	private Book book;
	private String currentTag;

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		currentTag = qName;
		if (("书".equals(currentTag))) {
			book = new Book();
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if (("书名").equals(currentTag)) {
			book.setName(new String(ch, start, length));
		}
		if (("作者").equals(currentTag)) {
			book.setAuthor(new String(ch, start, length));
		}
		if (("售价").equals(currentTag)) {
			book.setPrice(new String(ch, start, length));
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		currentTag = null;// /
		if (("书").equals(qName)) {
			list.add(book);
			book = null;
		}
	}

	public List<Book> getBooks() {
		return list;
	}
}

JavaBean


package cn.moving.parseXml;

public class Book {
	private String name ;
	private String author;
	private String price;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}
}

JAXP解析

用JAXP解析的步骤
  • 调用DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂
  • 调用工厂对象的newDocumentBuilder方法得到DOM解析器对象
  • 调用DOM解析器对象的parse()方法解析XML文档,得到代表整个文档的Document对象
  • 进行可以利用DOM特性对整个XML文档进行操作了
对XML文档进行增删改查
package cn.moving.parseXml;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class ParseXml {
	/**
	 * 使用dom方式对XML文档进行增删改查
	 * 
	 * @throws ParserConfigurationException
	 * @throws IOException
	 * @throws SAXException
	 */

	@Test
	// 读取<书名>Adroid基础教程</书名>
	public void read() throws ParserConfigurationException, SAXException, IOException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/cn/moving/parseXml/book.xml");
		NodeList list = document.getElementsByTagName("书名");
		Node node = list.item(0);
		String content = node.getTextContent();
		System.out.println(content);

	}

	@Test
	// 得到文档中所有标签
	public void readAll() throws Exception {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/cn/moving/parseXml/book.xml");
		NodeList list = document.getElementsByTagName("书名");
		Node root = document.getElementsByTagName("书架").item(0);
		list(root);// ??????????????
	}

	private void list(Node node) {
		if (node instanceof Element) {
			System.out.println(node.getNodeName());
		}
		NodeList list = node.getChildNodes();
		for (int i = 0; i < list.getLength(); i++) {
			Node child = list.item(i);
			list(child);

		}

	}

	@Test
	// 读取<书名 name=Data Structures"">数据结构(Java语言描述)</书名>
	public void readAttribute() throws Exception {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/cn/moving/parseXml/book.xml");
		NodeList list = document.getElementsByTagName("书名");
		Element element = (Element) list.item(0);
		// Element是Node的子类,所以有更多的方法
		String value = element.getAttribute("name");
		System.out.println(value);

		/*
		 * //笨办法 Node node = list.item(0); if (node.hasAttributes()) {
		 * NamedNodeMap map = node.getAttributes(); for (int i = 0; i <
		 * map.getLength(); i++) { Node nd = map.item(i); String name =
		 * nd.getNodeName(); // nd.getNodeType() String value =
		 * nd.getNodeValue(); System.out.println(name + ":" + value); } }
		 */

	}

	@Test
	// 添加节点<售价>$10</售价>
	public void add() throws ParserConfigurationException, SAXException,
			IOException, Exception, TransformerFactoryConfigurationError {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/cn/moving/parseXml/book.xml");

		Element element = document.createElement("售价");
		element.setTextContent("99元");
		document.getElementsByTagName("书").item(0).appendChild(element);

		// 更新内存中数据,将内存中数据写入XML文件中
		Transformer transformer = TransformerFactory.newInstance()
				.newTransformer();
		DOMSource source = new DOMSource(document);
		FileOutputStream fos = new FileOutputStream(new File(
				"src/cn/moving/parseXml/outbook.xml"));
		StreamResult result = new StreamResult(fos);
		transformer.transform(source, result);
		fos.flush();
		fos.close();
	}

	@Test
	// 指定位置添加节点:给<售价>56</售价>前加<售价>100</售价>
	public void addAppoint() throws Exception {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/cn/moving/parseXml/book.xml");

		// 得到参考节点(书名)
		Element refNode = (Element) document.getElementsByTagName("售价").item(0);
		// 创建一个新节点
		Element element = document.createElement("价格");
		//element.setNodeValue("100元");//wrong
		element.setTextContent("100元");
		//连接节点
		Element e = (Element)document.getElementsByTagName("书").item(0);
		e.appendChild(element);
		e.insertBefore(element, refNode);
		Transformer transformer  = TransformerFactory.newInstance().newTransformer();
		transformer.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/cn/moving/parseXml/outbook2.xml")));


	}

	@Test
	// 删除节点<售价>10</售价>
	public void delete() throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.parse("src/cn/moving/parseXml/outbook.xml");
		Node price = document.getElementsByTagName("售价").item(0);
		price.getParentNode().removeChild(price);
		DOMSource source = new DOMSource(document);
//		StreamResult os  = new StreamResult(new File("src/cn/moving/parseXml/outbook.xml"));//true
		StreamResult os  = new StreamResult(new FileOutputStream("src/cn/moving/parseXml/outbook.xml"));
		TransformerFactory.newInstance().newTransformer().transform(source, os);

	}

	@Test
	// 更新售价
	public void update() throws Exception {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder  = factory.newDocumentBuilder();
		Document document  = builder.parse("src/cn/moving/parseXml/book.xml");
		Node bookName = document.getElementsByTagName("书").item(0).getFirstChild();
		bookName.setTextContent("Android技术开发大全");
		TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/cn/moving/parseXml/book.xml")));
		
	}
}

Dom4J解析XML

Dom4J解析XML文件是DOM解析中最好用的一种方法,只需导入Dom4J的jar包即可

package cn.moving.parseXml;

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

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;


public class Dom4jParse {

	@Test
	public void read() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File(
				"src/cn/moving/parseXml/book.xml"));
		Element books = document.getRootElement();
		Element e = (Element) books.elements().get(0);
		Element bookName = e.element("书名");
		System.out.println(bookName.getText());
		Attribute attr = bookName.attribute("name");
		System.out.println(attr.getText());

	}

	@Test
	public void add() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read("src/cn/moving/parseXml/book.xml");
		Element book = (Element) document.getRootElement().element("书");
		book.addElement("出版社").setText("人民邮电出版社");
		OutputFormat format = OutputFormat.createCompactFormat();
		// OutputFormat format = new OutputFormat();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream(
				"src/cn/moving/parseXml/outbook2.xml"));
		// 漂亮格式输出
		// XMLWriter writer = new XMLWriter(new
		// FileOutputStream("src/cn/moving/parseXml/outbook2.xml"), format);
		writer.write(document);
		writer.close();
	}
	
	@Test
	//往指定位置添加元素
	public void addAppoint() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read("src/cn/moving/parseXml/book.xml");
		Element book = (Element) document.getRootElement().element("书");
		List list = book.elements();//[书名,作者,价格]
		Element e = DocumentHelper.createElement("折扣");
		e.setText("7折");
		list.add(2,e);
		OutputFormat format = OutputFormat.createCompactFormat();
		// OutputFormat format = new OutputFormat();
		format.setEncoding("UTF-8");

		XMLWriter writer = new XMLWriter(new FileOutputStream(
				"src/cn/moving/parseXml/outbook2.xml"));		
		// XMLWriter writer = new XMLWriter(new FileOutputStream("src/cn/moving/parseXml/outbook2.xml"), format);
		writer.write(document);
		writer.close();
	}
	
	@Test
	// 删除节点<售价>10</售价>
	public void delete() throws Exception {
		SAXReader reader = new SAXReader();
		Document document  = reader.read("src/cn/moving/parseXml/book.xml");
		Element element = document.getRootElement().element("书").element("售价");
		element.getParent().remove(element);
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/cn/moving/parseXml/book.xml"));
		writer.write(document);
		writer.close();
	

	}

	@Test
	// 更新售价
	public void update() throws Exception {

		SAXReader reader = new SAXReader();
		Document document  = reader.read("src/cn/moving/parseXml/book.xml");
		Element element = document.getRootElement().element("书").element("售价");
		element.setText("59");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/cn/moving/parseXml/book.xml"));
		writer.write(document);
		writer.close();		
	}
	
	@Test
	//Powerful Navigation with XPath
	public void xpath() throws Exception{
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("src/cn/moving/parseXml/book.xml"));
		String value = document.selectSingleNode("//作者").getText();
		Node node = document.selectSingleNode("//书名[@aa='bbb']");
		String bookName = document.selectSingleNode("//书名[@aa='bbb']").getText();
		String attrValue = node.valueOf("@aa");
		System.out.println(value);
		System.out.println(attrValue);
		System.out.println(bookName);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值