市面上解析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()

 ContentHandler

 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,几种方式的更多相关文章

  1. java解析XML几种方式

    第一种:DOM. DOM的全称是Document Object Model,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序 ...

  2. 解析Xml四种方法

    关键字:Java解析xml.解析xml四种方法.DOM.SAX.JDOM.DOM4j.XPath [引言] 目前在Java中用于解析XML的技术很多,主流的有DOM.SAX.JDOM.DOM4j,下文 ...

  3. android解析xml文件的方式

    android解析xml文件的方式   作者:东子哥 ,发布于2012-11-26,来源:博客园   在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xm ...

  4. Java解析XML文件的方式

    在项目里,我们往往会把一些配置信息放到xml文件里,或者各部门间会通过xml文件来交换业务数据,所以有时候我们会遇到“解析xml文件”的需求.一般来讲,有基于DOM树和SAX的两种解析xml文件的方式 ...

  5. JAVA解析XML之SAX方式

    JAVA解析XML之SAX方式 SAX解析xml步骤 通过SAXParseFactory的静态newInstance()方法获取SAXParserFactory实例factory 通过SAXParse ...

  6. JAVA解析XML之DOM方式

    JAVA解析XML之DOM方式 准备工作 创建DocumentBuilderFactory对象;    创建DocumentBuilder对象; 通过DocumentBuilder对象的parse方法 ...

  7. xml 解析的四种方式

    =========================================xml文件<?xml version="1.0" encoding="GB2312 ...

  8. XML基础+Java解析XML +几种解析方式的性能比较

    XML基础+Java解析XML 一:XML基础 XML是什么: 可扩展的标记语言 XML能干什么: 描述数据.存储数据.传输(交换)数据. XML与HTML区别: 目的不一样 XML 被设计用来描述数 ...

  9. XML解析的四种方式

    1.说明 XML是EXtensible Markup Language, 即可扩展标记语言, 是一种通用的数据交换格式, 它的平台无关性.语言无关性.系统无关性, 给数据集成与交互带来了极大的方便. ...

随机推荐

  1. javascript浏览器对象

    window对象 1.window对象 window对象是BOM的核心,window对象指当前的浏览器窗口 所有JS全局对象.函数以及变量均自动成为window对象的成员 全局变量是window对象的 ...

  2. android studio ADB not responding.

    打开cmd    输入  netstat -aon|findstr "5037"   找到谁在占用5037端口 记住他的pid. 例如pid为 2028 输入  taskkill ...

  3. 关于 VS 无法转到定义和无法转到使用的问题

    今天提交完代码以后突然发现  咦  怎么F12 .点击右键的方法都不能转到定义了    转到引用 也提示  没有发现   重启VS  还是不行 .去找王晓  他也不清楚(其实我知道 他应该也不清楚  ...

  4. 查看linux的出错信息

    先执行:dmesg -c > /dev/null 该命令是把之前的一些信息删除,-c选项表示:Clear the ring buffer after first printing its con ...

  5. 【ruby】安装Ruby

    系统需求 首先确定操作系统环境,不建议在 Windows 上面搞,所以你需要用: Mac OS X 任意 Linux 发行版本 配置系统包 $ sudo apt-get install -y buil ...

  6. Workspace Cloning / Sharing in Jenkins

    http://lwandersonmusings.blogspot.com/2011/06/workspace-cloning-sharing-in-hudson.html   What's insi ...

  7. Hadoop之TaskAttemptContext类和TaskAttemptID类

    先来看看TaskAttemptContext的类图 : Figure1:TaskAttemptContext类图 用户向Hadoop提交Job(作业),Job在JobTracker对象的控制下执行.J ...

  8. linux驱动的入口函数module_init的加载和释放【转】

    本文转载自:http://blog.csdn.net/zhandoushi1982/article/details/4927579 就像你写C程序需要包含C库的头文件那样,Linux内核编程也需要包含 ...

  9. win10 python nltk安装

    主要是参照http://www.tuicool.com/articles/VFf6Bza

  10. Java常用jar包用途

    Java常用jar包用途: USAGE INDEX JAR NAME USAGE 1 ASM asm-2.2.3.jar ASM字节码库 2 ASM asm-commons-2.2.3.jar ASM ...