DOM:Document ObjectModel,文档对象模型。这种方式是W3C推荐的处理XML的一种方式。
SAX:Simple API for XML。这种方式不是官方标准,属于开源社区的
一、DOM解析:
将整个XML数据转换成一个树形对象[Document对象],将XML中的标签,属性,文本都作为一个结点对象,在解析XML的时候,先将整个xml一次性读入到内存中封装成树对象,再对树上的结点进行操作[增删改查]
以Stus.xml为例:
<stu>
<stu num="123">
<name>张三</name>
<age>18</age>
<sex>男</sex>
</stu>
<stu num="123">
<name>李四</name>
<age>19</age>
<sex>男</sex>
</stu>
<stu num="123">
<name>王芳</name>
<age>20</age>
<sex>女</sex>
</stu>
获得DOM解析器:
l、调用DocumentBuilderFactory.newInstance() 方法得到创建DOM 解析器的工厂。
2、调用工厂对象的newDocumentBuilder方法得到DOM 解析器对象。
3、调用DOM 解析器对象的parse() 方法解析XML 文档,得到代表整个文档的Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。
// 创建解析器对象
//1.创建一个DOM解析器工厂
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
//2.通过工厂生产一个解析器对象
DocumentBuilder builder=factory.newDocumentBuilder();
//3.解析指定的XML文件
Document dom=builder.parse(f);
1.获得元素根节点:
//获得根节点
Node ele=dom.getDocumentElement();
System.out.println("根节点"+ele);
2.获得元素所有的子节点:
//由于是一个元素节点,可以获得其所有的子节点
NodeList list=ele.getChildNodes();
3.遍历所有元素节点
for (int i=0;i<list.getLength();i++){
//取得一个子节点(item()获得NodeList指定索引位置的节点)
Node node=list.item(i);
//如果子节点是一个元素节点,才需要处理(instanceof用法:判断node是不是Element类型的)
if (node instanceof Element){
//将node强制转换成Elment
Element stu=(Element)node;
//获得stu指定名字的属性值
String num=stu.getAttribute("num");
System.out.println("num:"+num);
}
}
4.获得指定索引位置的节点:
//取得一个子节点(item()获得NodeList指定索引位置的节点)
Node node=list.item(i);
5.获得指定名字的属性值
//获得stu指定名字的属性值
String num=stu.getAttribute("num");
System.out.println("num:"+num);
6.修改指定元素节点的主体内容
// 拿到所有节点
NodeList nl = stu.getElementsByTagName("性别");
// 获得计算机网络的售价节点
Node a = nl.item(1);
// 修改主体内容
a.setTextContent("女");
7.增加子节点
//给stu加子节点
Element name = dom.createElement("name");
//设置name的文本
name.setTextContent("赵敏");
//将name作为stu的子节点
stu.appendChild(name);
8.删除子节点:
// 拿到所有内部价节点
NodeList nl = stu.getElementsByTagName("性别");
// 拿到数据结构的内部价节点
Node nod = nl.item(0);
// 父亲干掉儿子
node.getParentNode().removeChild(nod);
2.Sax解析:
顺序解析,事件驱动
一边读取数据,一边进行解析,在读取数据的时候会触发一定的事件,每触发一次,就可以做一次处理
1.创建解析器工厂并且生产一个解析器对象
//1.创建sax解析器工厂
SAXParserFactory factory=SAXParserFactory.newDefaultInstance();
//2.通过工厂生产一个sax解析器对象
SAXParser saxParser=factory.newSAXParser();
2.创建事件处理对象
//创建事件处理对象(事件监听器对象)
DefaultHandler handler=new MyHander();
3.开始解析
//4.开始解析
saxParser.parse(f,handler);
4.sax事件处理器需要继承DefaultHandler
public class MyHander extends DefaultHandler {
}
5.处理器
//开始解析文档
public void startDocument() throws SAXException {
System.out.println("startDocument");
}
@Override
//解析到开始标签,需要处理标签中的属性
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("Stus")) {
Student stu=new Student();
String snum = attributes.getValue("num");
int num=Integer.parseInt(snum);
stu.setNum(num);
}
}
@Override
//解析到文本内容
public void characters(char[] ch, int start, int length) throws SAXException {
String msg=new String(ch,start,length);
System.out.println(msg);
}
@Override
//解析到结束标签
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println(qName+""+msg);
}
@Override
//解析文档结束
public void endDocument() throws SAXException {
System.out.println("endDocument");
}
在解析的过程当中需要用到的方法:
getDocumentElement(); 获得根节点
getChildNodes(); 获得元素节点的所有子节点
item(index) 获得NodeList中指定索引位置的节点
getAttribute("num") 获得指定名字的属性值
getNodeName() 获得节点名称
getTextContent() 获得元素节点中的文本内容
getElementsByTagName("name") 根据标签名获得节点列表
getElementById("1234") 根据标签的ID获得指定的节点
DOM与Sax优缺点的比较:
DOM的优缺点:
DOM方式解析的优点:
由于所有的结点都在内存的Document对象中,支持随机访问。
DOM方式解析的缺点:
由于所有的数据是一次性读入到内存中的,对于比较大的xml数据,非常占内存
Sax的优缺点:
Sax的优点:由于每次值需要存放触发事件的位置,占用内存较少
Sax的缺点:不支持随机访问