xml解析的方式
1. DOM 解析(Java解析) :
但该类提供了一个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 解析 :
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();
}
}