XML的解析

来源:互联网 发布:淘宝禁售拉卡拉 编辑:程序博客网 时间:2024/05/22 12:36

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: 修改金瓶梅的售价为80public 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:给葵花宝典的售价增加一个内部价节点 :50public 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:给葵花宝典的售价增加一个批发价节点 :60public 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;}@Overridepublic 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: 修改金瓶梅的售价为70public 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:给葵花宝典的售价增加一个内部价节点 :50public 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:给葵花宝典的售价增加一个批发价节点 :60public 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: 修改金瓶梅的售价为50public 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:给葵花宝典的售价增加一个内部价节点 :50public 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:给葵花宝典的售价增加一个批发价节点 :60public 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();}}




0 0
原创粉丝点击