XML三大解析详解!!!(Dom、Sax、Pull)
作者:互联网
文章目录
前言
文章内容:本文主要讲述XML的三大解析,
一、XML三大解析
Dom解析:百度百科上给的官方概念是Dom是一种解析器,Dom解析器把XML转换为JavaScript可存取的对象。以我的理解就是Dom解析是将XML文件全部载入内存,变成一棵Dom树,然后再通过获取这棵树的节点和节点列表来对XML文档进行解析。
Sax解析:
Pull解析:
二、XML三大解析优缺点
1.Dom解析优缺点
优点:
<1>Dom树是被加载入内存的,更加方便操作;
<2>Dom解析是支持读、写、重新排列等多种功能的;
缺点:
<1>需要将整个文件加载入内存,浪费时间和空间;
<2>如果文件过大的话还会导致内存溢出等问题;
2.Sax解析优缺点
优点:
<1>是一个元素一个元素的解析,对内存的耗费小;
缺点:
<1>编码麻烦;
<2>它的第一个优点也可以理解为它的缺点
3.Pull解析优缺点
优点:
<1>也是一个一个元素进行解析,但是同时解决了Dom和Sax解析的问题
三、案例分析
1.XML文档(store.xml)
<?xml version="1.0" encoding="utf-8"?>
<商场>
<商品>
<商品名>空调</商品名>
<品牌>美的</品牌>
<类型>家电</类型>
<售价>2988.00元</售价>
</商品>
<商品>
<商品名>豆浆机</商品名>
<品牌>美的</品牌>
<类型>988.00元</类型>
<售价>家电</售价>
</商品>
<商品>
<商品名>手机</商品名>
<品牌>华为</品牌>
<类型>2688元</类型>
<售价>电子产品</售价>
</商品>
<商品>
<商品名>水乳</商品名>
<品牌>雅诗兰黛</品牌>
<类型>2088.00元</类型>
<售价>护肤品</售价>
</商品>
</商场>
<>编程思路
①通过DocumentBuilderFactory工厂类获取DocumentBuilderFactory对象。这里采用DocumentFactory中的newInstance方法。
//获取DocumentBuilderFactory一个实例
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
②通过DocumentBuilder类获取DocumentBuilder的一个实例,这里通过调用builderFactory中的newDocumentBuilder的方法
2.Dom解析案例
//获取DocumentBuilder的一个实例
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
③通过DocumentBuilder解析XML文档并获取Document对象(
//通过documentBuilder 解析xml文档获得Document对象
Document document=documentBuilder.parse("store.xml");
④通过元素的名称找到元素的集合,并将指定的所有元素输出
NodeList nodeList=document.getElementsByTagName("商品名");
// NodeList nodeList1=document.getElementsByTagName("售价");
for(int i=0;i<nodeList.getLength();i++){
Node node=nodeList.item(i);
String content=node.getTextContent();
System.out.println(content);
}
⑤Dom有一个优点就是可以进行xml文档的修改,因为Dom树是被写入内存中,所以还需要用到I/O流来进行读取
源代码:
public class domTest {
@Test
public void domParse() throws Exception {
//获取DocumentBuilderFactory一个实例
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//获取DocumentBuilder的一个实例
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
//通过documentBuilder 解析xml文档获得Document对象
Document document = documentBuilder.parse("store.xml");
//通过元素的名字可以找到元素的集合
NodeList nodeList = document.getElementsByTagName("商品名");
// NodeList nodeList1=document.getElementsByTagName("售价");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
String content = node.getTextContent();
System.out.println(content);
}
}
@Test
public void changeXML() throws Exception {
DocumentBuilderFactory documentBuilderFactory1 = DocumentBuilderFactory.newInstance();
DocumentBuilder documnetBuilder1 = documentBuilderFactory1.newDocumentBuilder();
Document document1 = documnetBuilder1.parse("store.xml");
NodeList nodeList1 = document1.getElementsByTagName("商品名");
//获取节点列表的第一个元素
Node node = nodeList1.item(0);
node.setTextContent("烤箱");
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
Source source = new DOMSource(document1);
Result result = new StreamResult("store.xml");
transformer.transform(source, result);
for (int i = 0; i < nodeList1.getLength(); i++) {
Node node1 = nodeList1.item(i);
String content = node1.getTextContent();
System.out.println(content);
}
}
}
3.Sax解析案例
Sax和Dom的思想是一致的,代码也是类似书写,有区别的就是在获取工厂之后,Sax是通过获取reader,然后通过reader来设置ContentHandler,然后再对xml文档进行解析
源代码:
①一个一个元素进行解析
public class SaxTest {
@Test
public void saxParser() throws Exception {
//获取工厂
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
//获取xmlReader通过这个reader可以设置ContentHandler
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(new myHandler());
//对xml文档进行解析
xmlReader.parse("store.xml");
}
//因为ContentHandler接口未实现的方法过多,所以继承ContentHandler的实现类DefaultHandler
private class myHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("文档开始");
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("文档结束");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
System.out.println("开始标签<" + qName + ">");
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
System.out.println("结束标签</" + qName + ">");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
String text = new String(ch, start, length);
System.out.println("文本内容" + text);
}
}
}
②对解析到的元素的某项内容进行修改
public class SaxTest1 {
@Test
public void saxParser() throws Exception {
//获取工厂
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//获取SAXParser对象
SAXParser saxParser = saxParserFactory.newSAXParser();
//获取reader
XMLReader xmlReader = saxParser.getXMLReader();
//为reader设置ContentHandler
xmlReader.setContentHandler(new DefaultHandler(){
//判断解析的一个元素是否完成
boolean isType = false;
//计数器用来传入你想解析的元素索引值
int count = 0;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
//开始解析元素时遇到了类型,需要将isType置为true
if ("类型".equals(qName)) {
isType = true;
//解析元素个数加1
count++;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
//解析元素结束时,需要将isType置为false,防止解析下一个元素时,会因为isType的值而停止解析,这样我们设置isPrice的意义就不存在了
if ("类型".equals(qName)) {
isType = false;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
//当前解析的元素结束,输出元素的对应内容
if (isType && count == 2)
System.out.println(new String(ch, start, length));
}
});
//因为是读取一个元素,所以只需要覆盖重写DefaultHandler中的元素开始、结束、和元素的函数
//解析xml文档
xmlReader.parse("store.xml");
}
}
③将xml文档解析成ArrayList集合
public class Store {
private String goodsName;
private String brandName;
private String goodsType;
@Override
public String toString() {
return "Store{" +
"goodsName='" + goodsName + '\'' +
", brandName='" + brandName + '\'' +
", goodsType='" + goodsType + '\'' +
", goodsPrice='" + goodsPrice + '\'' +
'}';
}
private String goodsPrice;
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getGoodsType() {
return goodsType;
}
public void setGoodsType(String goodsType) {
this.goodsType = goodsType;
}
public String getGoodsPrice() {
return goodsPrice;
}
public void setGoodsPrice(String goodsPrice) {
this.goodsPrice = goodsPrice;
}
}
public class SaxTest2 {
@Test
public void saxParser() throws Exception {
//获取工厂
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//获取SAXParser实例
SAXParser saxParser = saxParserFactory.newSAXParser();
//获取reader
XMLReader xmlReader = saxParser.getXMLReader();
//设置ContentHandler
xmlReader.setContentHandler(new DefaultHandler() {
//创建一个集合用来存放元素对象
ArrayList<Store> list = null;
//创建商品对象
Store store = null;
String tag = null;
//因为是解析成为ArrayList,是通过一个个元素加入集合而成,所以只需要覆盖重写三个函数
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
//解析到商场的时候,创建商场集合
if ("商场".equals(qName)) {
list = new ArrayList<Store>();
} else if ("商品".equals(qName)) {//解析到商品的时候创建一个商品对象
store = new Store();
}
//解析到商品名的时候将商品名赋值给tag
if ("商品名".equals(qName)) {
tag = "商品名";
} else if ("品牌".equals(qName)) {//解析到商品品牌的时候将商品品牌赋值给tag
tag = "品牌";
} else if ("售价".equals(qName)) {//解析到商品售价的时候将售价赋值给tag
tag = "售价";
} else if ("类型".equals(qName)) {//解析到商品类型的时候将类型复制给tag
tag = "类型";
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
//将tag复原为null
tag = null;
//解析到商场集合结束的时候,将商场集合遍历输出
if ("商场".equals(qName)) {
for (Store store1 : list) {
System.out.println(store1);
}
} else if ("商品".equals(qName)) {//解析到商品集合结束的时候,将商品添加进入商场集合
list.add(store);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
//解析到商品名的时候,将tag赋值给商品名
if ("商品名".equals(tag)) {
store.setGoodsName(new String(ch, start, length));
} else if ("品牌".equals(tag)) {//解析到商品品牌的时候,将tag赋值给品牌
store.setBrandName(new String(ch, start, length));
} else if ("售价".equals(tag)) {//解析到商品售价的时候,将tag赋值给售价
store.setGoodsPrice(new String(ch, start, length));
} else if ("类型".equals(tag)) {//解析到商品类型的时候,将tag赋值给类型
store.setGoodsType(new String(ch, start, length));
}
}
});
xmlReader.parse("store.xml");
}
}
4.Pull解析案例
源代码:
持续更新中!!!
标签:XML,Pull,String,Dom,void,qName,tag,解析,public 来源: https://blog.csdn.net/qq_45842760/article/details/112528921