解析xml,几种方式
市面上解析xml分两种方式,1.dom 2.sax ,xml解析常见的一共有三种开发包,1.jaxp 2.jdom 3.dom4j,这三种方式最常用的是dom4j,jaxp和jdom很少有人用,jaxp是sun公司开发的,对于这个sun公司老是我就不知道怎么说他,被收购后我就没法叫,是叫甲骨文还叫原sun公司,别扭,书归正传,jaxp虽然使用起来很烂,但是它是标准,这个我们必须得懂,没准那天对jaxp二次开始开发,它就好用了,还是只得期待的,所以,首先我们来说下jaxp的用法,
jaxp是开发包是j2SE的一部分,它由javax.xml, org.w3c.dom, org.xml.sax,还有其自包组成
在javax.xml.parse包中定义了几个工厂类,程序员可以调用这些工厂类,得到xml的dom和sax解析器,从而实现对xml的解析。
要用jaxp的dom解析xml需要按三步走,
第一步:创建工厂
第二步:拿到一个dom解析器
第三步:得到Document对象
看代码:
//创建工厂
DocumentBuilderFactory factor = DocumentBuilderFactory.newInstance();
//得到dom解析器
DocumentBuilder builder = factor.newDocumentBuilder();
//得到Docuemnt
Document document = builder.parse("src/student.xml");
注意DocumentBuilderFactory是一个抽象方类,它向外界提供了一个得到实例的方法,通过工厂在得到dom解析器,dom解析器在加载一个xml让后返回一个文档对象,然后我们就能对文档进行读取了。
得到了Document,然后写几个简单的查询,
我们先读取一下xml文档的所有信息
public void read1() throws Exception{
//创建工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//得到dom解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//得到Document文档对象
Document document = builder.parse("src/student.xml");
Node node = document.getElementsByTagName("学校").item(0);//学校是xml的文档根节点
list(node);//循环显示
}
private void list(Node node) {
//用于判断node是否为一个节点
if(node instanceof Element){
System.out.println(node.getNodeName());
}
NodeList childs = node.getChildNodes();
for(int i = 0;i<childs.getLength();i++){
list(childs.item(i));
}
}
我们先获取一个节点的值,
//创建工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//得到一个dom解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//得到一个Document对象
Document document = builder.parse("src/student.xml");
NodeList list = doc.getElementsByTagName("名字");
//这里我只想得到第一个学生的名字
Node node = list.item(0);
System.out.println(node.getTextContent());
获取一个节点的Attribute属性的值
//创建dom工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//得到dom解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//得到doc文档
Document doc = builder.parse("src/student.xml");
//元素
Element bookName = (Element) doc.getElementsByTagName("书名").item(0);
String value = bookName.getAttribute("name");
System.out.println(value);
对于xml而言,查询无非就是差标签的值,和标签属性的值,如果大家想深学,想探究jaxp的话,去看帮助文档吧
下面往xml里添加节点
这里我写一个比较难的添加,就是给特定的位置添加节点,这个你会了,正常的添加你也就回了
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("src/book.xml");
//创建一个新节点
Element e = doc.createElement("售价");
e.setTextContent("59.0");
//得到一个参考节点
Element refChild =(Element) doc.getElementsByTagName("价格").item(0);
//得到要插入的节点
Element element = (Element) doc.getElementsByTagName("书").item(0);
//添加节点
element.insertBefore(e, refChild); //把内存里的xml,写回到本地的xml文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult(new FileOutputStream("src/book.xml")));
这里要注意,我们添加完了节点element.insertBefore(e, refChild);之后,没有后面的代码的话我们本地的xml不会增加,为什么呢,那我们加到哪去了。我们这个是添加到了内存里,内存里的xml肯定对了,所以我们要把内存里的xml写回到我们本地。这里用到一个类,就是Transform,这个类能帮助我把内存中的xml写回本地。
添加一个属性
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("src/book.xml"); Element e = (Element) doc.getElementsByTagName("书名").item(0);
e.setAttribute("name", "添加的新属性"); //把内存里的xml,写回到本地的xml文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult(new FileOutputStream("src/book.xml")));
注意一定要从内存中,写回本地。
删除,删除一定要用父节点来删子节点。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("src/book.xml"); Element e = (Element) doc.getElementsByTagName("价格").item(0);
e.getParentNode().removeChild(e); TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult(new FileOutputStream("src/book.xml")));
以上是jaxp对xml的crud。
下面说一下jaxp的sax解析器,对xml的解析,dom解析xml文档时,会把整个读取后的xml放在内存中,在内存中dom树代表Document,这样会有一个问题,如果xml比较大,就会消耗大量的内存,而且很容易造成内存溢出。对于sax解析的话,那么它允许你在读取的时候进行操作,不需要等整个文档加载完成。
sax采用事件处理方式解析xml,一共两个部分 1.解析器 2.事件处理器
解析器可以使用jaxp的api来创建,创建完成,就可以指定解析器去解析某个xml文档。这个解析器解析到xml文档的一个组成部分,都会调用一个事件处理器方法,解析器在调用事件处理器的时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
事件处理器由我们自己编写,我们通过事件处理器总方法的参数,就可以获取到sax解析xml的内容。
一张图,让你更理解sax
想要了解更过,去看ContentHandler 的api
来看一个简单的sax解析,这个一共分5部
1.创建工厂
2.得到解析器
3.得到读取器
4.设置内容处理器
5.读取xml文档内容
看一段代码
//1.创建工厂
SAXParserFactory factory = SAXParserFactory.newInstance(); //2.得到解析器
SAXParser parser = factory.newSAXParser(); //3.得到读取器
XMLReader reader = parser.getXMLReader(); //4.设置内容处理器
//这个内容处理器是我们自己写的,我们自己写的这个类要实现
reader.setContentHandler(null);
//5.读取xml文档内容
reader.parse("src/book.xml");
下面我们自己写一个处理器,四个处理器,我们对内容修改,那就要写一个内容处理器ContentHandler,这里实现ContentHandler,常用的方法有startElement(),endElement()
characters()
class ListXML implements ContentHandler{
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
@Override
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
// TODO Auto-generated method stub
}
}
然后我们去查帮助文档,我们会看到一个DefaultHandler,原来人家都给我们写好了,这个我们就可以把多余的方法去掉,
写一个完整的sax读取xml,这个读取xml全部内容,
//1.创建工厂
SAXParserFactory factory = SAXParserFactory.newInstance(); //2.得到解析器
SAXParser parser = factory.newSAXParser(); //3.得到读取器
XMLReader reader = parser.getXMLReader(); //4.设置内容处理器
reader.setContentHandler(new GetXML());
//5.读取xml文档内容
reader.parse("src/book.xml"); //下面是一个内容处理器
class GetXML extends DefaultHandler{
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
for(int i = 0 ; atts != null && i < atts.getLength(); i++){
String attrName = atts.getQName(i);
String attrVlaue = atts.getValue(i);
System.out.println(attrName + "=" + attrVlaue);
}
System.out.println("<"+qName+">"); } @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch,start,length));
} @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("<"+qName+"/>"); }
}
我觉得sax解析能做到这样就行了。
下面是dom4j,dom4j好用是公认的,曾经也有人做过实验,dom4j,最快,jdom第二,jaxp最慢,第二的就不用学了。
我认为dom4j不用任何人交,不需要交,看文档就可以,提醒大家,看dom4j的xpath的时候找好地方,xpath的文档官方有中文,这一点就很爽,需要什么直接
看文档,养成这个好习惯。
推荐文章
http://xhy0422.javaeye.com/blog/50235
解析xml,几种方式的更多相关文章
- java解析XML几种方式
第一种:DOM. DOM的全称是Document Object Model,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序 ...
- 解析Xml四种方法
关键字:Java解析xml.解析xml四种方法.DOM.SAX.JDOM.DOM4j.XPath [引言] 目前在Java中用于解析XML的技术很多,主流的有DOM.SAX.JDOM.DOM4j,下文 ...
- android解析xml文件的方式
android解析xml文件的方式 作者:东子哥 ,发布于2012-11-26,来源:博客园 在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xm ...
- Java解析XML文件的方式
在项目里,我们往往会把一些配置信息放到xml文件里,或者各部门间会通过xml文件来交换业务数据,所以有时候我们会遇到“解析xml文件”的需求.一般来讲,有基于DOM树和SAX的两种解析xml文件的方式 ...
- JAVA解析XML之SAX方式
JAVA解析XML之SAX方式 SAX解析xml步骤 通过SAXParseFactory的静态newInstance()方法获取SAXParserFactory实例factory 通过SAXParse ...
- JAVA解析XML之DOM方式
JAVA解析XML之DOM方式 准备工作 创建DocumentBuilderFactory对象; 创建DocumentBuilder对象; 通过DocumentBuilder对象的parse方法 ...
- xml 解析的四种方式
=========================================xml文件<?xml version="1.0" encoding="GB2312 ...
- XML基础+Java解析XML +几种解析方式的性能比较
XML基础+Java解析XML 一:XML基础 XML是什么: 可扩展的标记语言 XML能干什么: 描述数据.存储数据.传输(交换)数据. XML与HTML区别: 目的不一样 XML 被设计用来描述数 ...
- XML解析的四种方式
1.说明 XML是EXtensible Markup Language, 即可扩展标记语言, 是一种通用的数据交换格式, 它的平台无关性.语言无关性.系统无关性, 给数据集成与交互带来了极大的方便. ...
随机推荐
- 3D语音天气球(源码分享)——完结篇
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 由于这篇文章是本系列最后一篇,有必要进行简单的回顾和思路整理. 这个程序是由两 ...
- logstash的性能测试
logstash有简单的批量生成插件.generator.详情见官网:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-g ...
- JFreeChart在制作折线图
JFreeChart在制作折线图的时候可以使用两种不同的方式 package Line; import java.awt.Color; import java.awt.Font; import org ...
- PAT乙级 1019. 数字黑洞 (20)
1019. 数字黑洞 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定任一个各位数字不完全相同的4位 ...
- php导出word格式数据的代码
<?php /** * 生成word文档的类 * by www.jbxue.com */ class word { function start() { ...
- linux设备驱动归纳总结(四):2.进程调度的相关概念【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-65555.html linux设备驱动归纳总结(四):2.进程调度的相关概念 xxxxxxxxxxxx ...
- html5 canvas 笔记一(基本用法与绘制图形)
<canvas> 元素 <canvas id="tutorial" width="150" height="150"> ...
- 【Pro ASP.NET MVC 3 Framework】.学习笔记.5.SportsStore一个真实的程序
我们要建造的程序不是一个浅显的例子.我们要创建一个坚固的,现实的程序,坚持使它成为最佳实践.与Web Form中拖控件不同.一开始投入MVC程序付出利息,它给我们可维护的,可扩展的,有单元测试卓越支持 ...
- expdp impdp中 exclude/include 的使用
exclude和include参数能够在使用expdp或impdp是对特定的对象或对象类型进行筛选或过滤.比如因工作的需要导出特定的表或不导出特定 的表.视图以及存储过程.索引.约束.授权统计信息等等 ...
- PHP程序中删除字符串最后一个字符的三种方法
常见的语法格式: foreach ($arr as $key => $value) {$arr_str = $arr['x_id'] . ',' . $arr_str;} 假设字符数组 $arr ...