XML的解析

xml解析的方式

1. DOM 解析(Java解析) : 

利用DOM树来解析

javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,
但该类提供了一个newInstance方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。
调用 DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂。
调用工厂对象的newDocumentBuilder方法得到DOM解析器对象。
调用 DOM解析器对象的parse()方法解析XML文档,得到代表整个文档的Document对象,进行可以利用DOM特性对整个XML文档进行操作了:
•1、得到某个具体的节点内容
•2、遍历所有元素节点
•3、修改某个元素节点的主体内容
•4、向指定元素节点中增加子元素节点
•5、向指定元素节点上增加同级元素节点
•6、删除指定元素节点
•7、操作XML文件属性


更新XML文档:
javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转
换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。
类Transformer:此抽象类的实例能够将源树(内存)转换为结果树(硬盘上的xml文档)
利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:

•javax.xml.transform.dom.DOMSource类来关联要转换的document对象,

•用javax.xml.transform.stream.StreamResult对象来表示数据的目的地。

Transformer对象通过TransformerFactory获得。


book.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
	<书>
		<书名>葵花宝典</书名>
		<作者>安倍晋三</作者>
		<售价>100</售价>
	</书>
	<书>
		<书名>金瓶梅</书名>
		<作者>安倍晋四</作者>
		<售价>50</售价>
	</书>
</书架>

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

//演示dom方式解析XML文件
public class DOM_parseXML {

	public static void main(String[] args) throws Exception {
		// 创建解析器对象
		DocumentBuilder db = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder();
		// 加载XML文档
		Document document = db.parse("src/book.xml");

		// test1(document) ;
		// test2(document);
		// test3(document);
		// test4(document);
		// test5(document);
//		test6(document);
		test7(document);
	}

	// 1、得到某个具体的节点内容 : eg: 拿到金瓶梅的售价
	public static void test1(Document document) {
		// 拿到所有售价节点
		NodeList nl = document.getElementsByTagName("售价");
		// 获得金瓶梅的售价节点
		Node n = nl.item(1);

		// 获取售价文本
		System.out.println(n.getTextContent());
	}

	// 2、遍历所有元素节点
	public static void test2(Node node) {
		// 对node节点进行循环
		NodeList nl = node.getChildNodes();
		// 循环判断
		for (int i = 0; i < nl.getLength(); i++) {
			Node n = nl.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				// 说明此节点就是标签节点
				System.out.println(n.getNodeName());
				test2(n);
			}
		}
	}

	// 3、修改某个元素节点的主体内容 eg: 修改金瓶梅的售价为80
	public static void test3(Document document) throws Exception {
		// 拿到所有售价节点
		NodeList nl = document.getElementsByTagName("售价");
		// 获得金瓶梅的售价节点
		Node n = nl.item(1);
		// 修改主体内容
		n.setTextContent("80");

		// 将修改的结果保存到硬盘上
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));

	}

	// 4、向指定元素节点中增加子元素节点:eg:给葵花宝典的售价增加一个内部价节点 :50
	public static void test4(Document document) throws Exception {
		// 拿到所有售价节点
		NodeList nl = document.getElementsByTagName("售价");
		// 获得葵花宝典的售价节点
		Node n = nl.item(0);

		// 创建新的节点
		Element el = document.createElement("内部价");
		// 设置节点的主体内容
		el.setTextContent("50");

		// 将内部价节点挂接到售价几点上
		n.appendChild(el);

		// 将修改的结果保存到硬盘上
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
	}

	// 5、向指定元素节点上增加同级元素节点 : eg:给葵花宝典的售价增加一个批发价节点 :60
	public static void test5(Document document) throws Exception {
		// 拿到所有书节点
		NodeList nl = document.getElementsByTagName("书");
		// 获得葵花宝典的书节点
		Node n = nl.item(0);

		// 创建批发价节点
		Element el = document.createElement("批发价");
		// 设置节点的主体内容
		el.setTextContent("60");

		// 将内部价节点挂接到书点上
		n.appendChild(el);

		// 将修改的结果保存到硬盘上
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
	}

	// 6、删除指定元素节点 eg: 删除内部价节点
	public static void test6(Document document) throws Exception {
		// 拿到所有内部价节点
		NodeList nl = document.getElementsByTagName("内部价");
		// 拿到葵花宝典的内部价节点
		Node node = nl.item(0);

		// 父亲干掉儿子
		node.getParentNode().removeChild(node);

		// 将修改的结果保存到硬盘上
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
	}

	// 7、操作XML文件属性: eg: 给葵花宝典的书几点增加一个属性: ISBN : "黑马程序员"
	public static void test7(Document document) throws Exception {
		// 拿到所有书节点
		NodeList nl = document.getElementsByTagName("书");
		// 获得葵花宝典的书节点
		Node n = nl.item(0);

		// 增加一个属性
		((Element) n).setAttribute("ISBN", "黑马程序员");

		// 将修改的结果保存到硬盘上
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
	}

}


2. SAX 解析 :


边加载边解析.  

图中:SAX Reader改为XML Reader

l使用SAXParserFactory创建SAX解析工厂

SAXParserFactory spf =SAXParserFactory.newInstance();

l通过SAX解析工厂得到解析器对象 

SAXParser sp = spf.newSAXParser();

l通过解析器对象得到一个XML的读取器

XMLReader xmlReader =sp.getXMLReader();

l设置读取器的事件处理器 

xmlReader.setContentHandler(newBookParserHandler());

l解析xml文件 

xmlReader.parse("book.xml");

book.java(bean):

package bean;

public class Book {
	
	private String bookName;
	private String author;
	private float price;
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	@Override
	public String toString() {
		return "Book [bookName=" + bookName + ", author=" + author + ", price="
				+ price + "]";
	}
	
	

}


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 SAX_parseXML2 {

	public static void main(String[] args) throws Exception{
		//创建sax解析器
		SAXParser sax = SAXParserFactory.newInstance().newSAXParser() ;
		//获取内容读取器
		XMLReader xml =  sax.getXMLReader() ;
		//注册一个内容处理器
		xml.setContentHandler(new DefaultHandler(){
			String curName = "" ;  //记录当前是那个标签
			int index = 0 ;  //记录读取到了那个作者

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

			public void endElement(String uri, String localName, String qName)
					throws SAXException {
				curName = "" ;
			}

			public void characters(char[] ch, int start, int length)
					throws SAXException {
				
				if("作者".equals(curName) && index == 2){
					//说明读取到了第二本书的作者
					System.out.println(new String(ch,start,length));
				}
			}
		}) ;
		//加载xml文档
		xml.parse("src/book.xml") ;
	}
	
}

实际开发中是把数据封装到bean中:

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;

import com.heima52.bean.Book;

//演示封装数据到JavaBean中
public class SAX_parseXML3 {

	public static void main(String[] args) throws Exception{
		//创建sax解析器
		SAXParser sax = SAXParserFactory.newInstance().newSAXParser() ;
		//获取内容读取器
		XMLReader xml =  sax.getXMLReader() ;
		//创建集合对象用来放置所有的书
		final List<Book> list = new ArrayList<Book>() ;
		//注册一个内容处理器
		xml.setContentHandler(new DefaultHandler(){
			String curName = "" ;  //记录当前是那个标签
			int index = 0 ;  //记录读取到了那个作者
			Book book = null ;

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

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

			public void characters(char[] ch, int start, int length)
					throws SAXException {
				if("书名".equals(curName))
					book.setBookName(new String(ch,start,length)) ;
				if("作者".equals(curName))
					book.setAuthor(new String(ch,start,length)) ;
				if("售价".equals(curName))
					book.setPrice(Float.parseFloat(new String(ch,start,length))) ;
			}
		}) ;
		//加载xml文档
		xml.parse("src/book.xml") ;
		
		//打印集合数据
		for (Book book : list) {
			System.out.println(book);
		}
	}
	
}


解析包

* JAXP (sun 公司提供)
* DOM4j (第三方)


3.Dom4j解析(掌握)

* document的方法: 

elements() : 拿到节点的所有子节点

elements(String) : 拿到指定名字的所有的子节点

element(String) : 拿到指定名字的子节点

* Element节点的方法:

setText() : 设置标签节点的内容

getTest() : 获得标签节点的内容

addAttibute(String name ,String value ) : 添加标签的属性

removeAttribute(String name) : 删除某个属性

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

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

//演示用dom4j来解析XML文件
public class Dom4j_parseXML {

	public static void main(String[] args) throws Exception {
		// 创建dom4j的解析器
		SAXReader reader = new SAXReader();
		// 加载document对象
		Document document = reader.read("src/book.xml");

		// test1(document);
		// test2(document);
		// test3(document);
		// test4(document);
		// test5(document);
//		test6(document);
		test7(document);
	}

	// 1、得到某个具体的节点内容 : eg: 拿到金瓶梅的售价
	public static void test1(Document document) {
		// 拿到根节点
		Element root = document.getRootElement();
		// 拿到所有的书节点
		List<Element> list = root.elements("书");
		// 拿到第二本书
		Element bookEl = list.get(1);
		// 获取售价文本
		System.out.println(bookEl.elementText("售价"));
	}

	//
	// 2、遍历所有元素节点
	public static void test2(Document document) {
		treeWalk(document.getRootElement());
	}

	public static void treeWalk(Element element) {
		for (int i = 0, size = element.nodeCount(); i < size; i++) {
			Node node = element.node(i);
			if (node instanceof Element) {
				System.out.println(node.getName());
				treeWalk((Element) node);
			}
		}
	}

	//
	// 3、修改某个元素节点的主体内容 eg: 修改金瓶梅的售价为70
	public static void test3(Document document) throws Exception {
		// 获取根节点
		Element root = document.getRootElement();
		// 拿到第二种本节点
		Element bookEL = (Element) root.elements("书").get(1);
		// 拿到售价节点
		Element priceEl = bookEL.element("售价");
		// 改变主体内容
		priceEl.setText("70");

		// 将结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();

	}

	//
	// 4、向指定元素节点中增加子元素节点:eg:给葵花宝典的售价增加一个内部价节点 :50
	public static void test4(Document document) throws Exception {
		// 获取根节点
		Element root = document.getRootElement();
		// 拿到第一种本节点
		Element bookEL = (Element) root.elements("书").get(0);
		// 拿到售价节点
		Element priceEl = bookEL.element("售价");

		// 添加子节点
		priceEl.addElement("内部价").setText("50");

		// 将结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();

	}

	//
	// 5、向指定元素节点上增加同级元素节点 : eg:给葵花宝典的售价增加一个批发价节点 :60
	public static void test5(Document document) throws Exception {
		// 获取根节点
		Element root = document.getRootElement();
		// 拿到第一种本节点
		Element bookEL = (Element) root.elements("书").get(0);

		// 给书节点添加子节点
		bookEL.addElement("批发价").setText("60");

		// 将结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();
	}

	//
	// 6、删除指定元素节点 eg: 删除内部价节点
	public static void test6(Document document) throws Exception {
		// 获取根节点
		Element root = document.getRootElement();
		// 拿到第一种本节点
		Element bookEL = (Element) root.elements("书").get(0);
		// 拿到内部价节点
		Element neibuEL = bookEL.element("售价").element("内部价");
		// 父亲干掉儿子
		neibuEL.getParent().remove(neibuEL);

		// 将修改的结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();
	}

	//
	// 7、操作XML文件属性: eg: 给葵花宝典的书几点增加一个属性: ISBN : "黑马程序员"
	public static void test7(Document document) throws Exception {
		// 获取根节点
		Element root = document.getRootElement();
		// 拿到第一种本节点
		Element bookEL = (Element) root.elements("书").get(0);

		// 增加一个属性
		bookEL.addAttribute("ISBN", "黑马程序员") ;
		
		// 将修改的结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();
	}

}



4.XPath解析

主要作用是获取某个节点的路径 。

专门用于查询:

定义了一种规则

使用的方法:

selectSingleNode():

selectNodes():

使用步骤:

1.注意要导包:jaxen....jar

2.创建解析器:

SAXReader reader = new SAXReader();

3.解析xml获得document对象

Document document = reader.read(url);

XPath:

nodename  选取此节点

/  从根节点选取

//   从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置

..  选取当前节点的父节点

@  选取属性

[@属性名]  属性过滤

[标签名]  子元素过滤

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

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

//演示用dom4j的xpath导航来解析XML文件
public class Dom4j_parseXMLByXpath {

	public static void main(String[] args) throws Exception {
		// 创建dom4j的解析器
		SAXReader reader = new SAXReader();
		// 加载document对象
		Document document = reader.read("src/book.xml");

	// test1(document);
		test2(document);
//		 test3(document);
//		 test4(document);
		// test5(document);
//		test6(document);
		//test7(document);
	}

	// 1、得到某个具体的节点内容 : eg: 拿到金瓶梅的售价
	public static void test1(Document document) {
		//获取金瓶梅的售价节点
		//Node node = document.selectSingleNode("/书架/书[2]/售价") ;
		Node node = document.selectSingleNode("//书[2]/售价") ;
		//Node node = document.selectSingleNode("//书/售价[2]") ; //不行
		
		//打印售价信息
		System.out.println(node.getText());
		
	}

	//
	// 2、遍历所有元素节点
	public static void test2(Document document) {
		treeWalk(document.getRootElement());
	}

	public static void treeWalk(Element element) {
		for (int i = 0, size = element.nodeCount(); i < size; i++) {
			Node node = element.node(i);
			if (node instanceof Element) {
				System.out.println(node.getName());
				treeWalk((Element) node);
			}
		}
	}

	//
	// 3、修改某个元素节点的主体内容 eg: 修改金瓶梅的售价为50
	public static void test3(Document document) throws Exception {
		//拿到金瓶梅的售价节点
		Node priceEl = document.selectSingleNode("//书[2]/售价") ;
		// 改变主体内容
		priceEl.setText("50");

		// 将结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();

	}

	//
	// 4、向指定元素节点中增加子元素节点:eg:给葵花宝典的售价增加一个内部价节点 :50
	public static void test4(Document document) throws Exception {
		//拿到葵花宝典的售价节点
		Node priceEl = document.selectSingleNode("//书[1]/售价") ;

		// 添加子节点
		((Element)priceEl).addElement("内部价").setText("50");

		// 将结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();

	}

	//
	// 5、向指定元素节点上增加同级元素节点 : eg:给葵花宝典的售价增加一个批发价节点 :60
	public static void test5(Document document) throws Exception {
		// 获取根节点
		Element root = document.getRootElement();
		// 拿到第一种本节点
		Element bookEL = (Element) root.elements("书").get(0);

		// 给书节点添加子节点
		bookEL.addElement("批发价").setText("60");

		// 将结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();
	}

	//
	// 6、删除指定元素节点 eg: 删除内部价节点
	public static void test6(Document document) throws Exception {
		//拿到内部价节点
		Node neibuEL = document.selectSingleNode("//内部价") ;
		// 父亲干掉儿子
		neibuEL.getParent().remove(neibuEL);

		// 将修改的结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();
	}

	//
	// 7、操作XML文件属性: eg: 给葵花宝典的书几点增加一个属性: ISBN : "黑马程序员"
	public static void test7(Document document) throws Exception {
		
		// 拿到第一种本节点
		Node bookEL = document.selectSingleNode("//书[1]") ;

		// 增加一个属性
		((Element)bookEL).addAttribute("ISBN", "黑马程序员") ;
		
		// 将修改的结果保存到硬盘上
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),
				OutputFormat.createPrettyPrint());
		writer.write(document);
		writer.close();
	}

}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值