body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

JAXP:

█ JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成:
    ☞org.w3c.dom:提供DOM方式解析XML的标准接口
    ☞org.xml.sax:提供SAX方式解析XML的标准接口
    ☞javax.xml:提供了解析XML文档的类
█ javax.xml.parsers包中,定义了几个工厂类。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象。
   ☞DocumentBuilderFactory
   ☞SAXParserFactory

使用JAXP进行DOM解析

█ javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会自动创建一个工厂的对象并返回。
获得JAXP中的DOM解析器

调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。
调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。
调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。

DOM编程 Node对象
█ DOM模型(document object model)
      ☞DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)  document 。
      ☞在dom中,节点之间关系如下:
            •位于一个节点之上的节点是该节点的父节点(parent)
            •一个节点之下的节点是该节点的子节点(children)
            •同一层次,具有相同父节点的节点是兄弟节点(sibling)
            •一个节点的下一个层次的节点集合是节点后代(descendant)
            •父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)
█ Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)
█ Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。
DOM方式解析XML文件:
1、得到某个具体的节点内容
2、打印某节点的所有元素节点
3、修改某个元素节点的主体内容
4、向指定元素节点中增加子元素节点
5、向指定元素节点上增加同级元素节点
6、删除指定元素节点
7、操作XML文件属性
更新XML文档:
█ javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
█ Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:
      • javax.xml.transform.dom.DOMSource类来关联要转换的document对象,
      • 用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。
█ Transformer对象通过TransformerFactory获得。
//jaxp dom解析的标准写回流程

TransformerFactory tsf =TransformerFactory.newInstance();
Transformer tsTransformer = tsf.newTransformer();
tsTransformer.transform(
new DOMSource(document),
new StreamResult("src/books.xml"));

Books.xml JAXPDomPaser.java
<?xml version="1.0" encoding="utf-8"  ?>
<书架>
        <书>
        <书名 id="001">浪潮之巅</书名>
                <作者>吴军</作者>
                <售价>29</售价>
        </书>
        <书>
                <书名 id='002'>数学之美</书名>
                <作者>吴军</作者>
                <售价><第一版>29</第一版></售价>
        </书>
</书架>
package com.java.xmldom;
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;
public class JAXPDomPaser {
        public static void main(String[] args) throws Exception {  //真正开发中不能使用
                //多态,返回的是内部实现的一个子类的实例;DOM解析器的工厂
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                //DOM解析器对象
                DocumentBuilder documentBuilder=dbf.newDocumentBuilder();
                //绝对路径和相对路径都可以;拿到文档对象模型:DOM树;DOM对象
                Document document=documentBuilder.parse("Books.xml");
                //解析流程
//1、得到某个具体的节点内容 得到第一本书的书名
                NodeList booknameList = document.getElementsByTagName("书名");
                System.out.println("JAXDomPaser.main()"+booknameList.getLength());
                Node bookname1=booknameList.item(0);
                short nodeType=bookname1.getNodeType();    //元素节点,节点类型=1
                String nodeName = bookname1.getNodeName();
                String nodeValue = bookname1.getNodeValue();
                String textContent=bookname1.getTextContent();
                System.out.println("JAXPDomPaser.main()  "+ nodeType + nodeName + nodeValue+textContent);
//打印某节点的所有元素节点 ,第二个节点
                NodeList bookList = document.getElementsByTagName("书");
                //拿到第二本书
                Node book2=bookList.item(1);
                NodeList childNodes=book2.getChildNodes();  //这里空格也算一个子节点;
                System.out.println("第二本书的子元素个数:"+childNodes.getLength());
                for(int i=0;i<childNodes.getLength();++i){
                        if(childNodes.item(i).getNodeType()==1){
                                String childnodename = childNodes.item(i).getNodeName();
                                System.out.println("JAXPDomPaser.main ()  "+childnodename);
                        }
                }

//修改某个元素节点的主体内容,把第一本书的作者改成梅浩
                Node book1=bookList.item(0);
                book1.getChildNodes().item(3).setTextContent("梅浩");  //这里要写回XML才会生效
//向指定元素节点上增加同级元素节点
                Element newElement=document.createElement("销量"); //这里注意,新建的元素只有一个,添加完就没有了;比如给每个学生添加一个性别属性,用for循环添加,最只会把新建的节点添加到最后一个for循环满足添加的节点,然后写入xml
                newElement.setTextContent("1000");
                book1.appendChild(newElement);

//删除指定元素节点
                Node shoujianode=document.getElementsByTagName("售价").item(0);
                book1.removeChild(shoujianode);

//操作XML文件属性
                String xmlEncoding=document.getXmlEncoding();
                String version=document.getXmlVersion();
                boolean  standalong=document.getXmlStandalone();
                System.out.println("xml encoding: "+xmlEncoding+";  xml version: "+version+";  xml standalong: "+standalong);

//把内存中的dom树输出到磁盘中的文档的标准写法;只有增加、修改才会写入
                TransformerFactory tsf =TransformerFactory.newInstance();
                Transformer tsTransformer = tsf.newTransformer();
                tsTransformer.transform(
                new DOMSource(document),
                new StreamResult("src/Books.xml"));
        }
}//xml会重新保存在src下
((Element)studentList.item(k)).setAttribute("ID",arg);  //找到指定地点,添加一个属性并设置值;这个是Element里面的方法
SAX解析:  //一般用来读,写和修改还是用DOM

█ 在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
█ SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。

█ SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
      ☞解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
      ☞解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
      ☞事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
//事件处理器有一个缺省的DefaultHandler
//方法步骤
☞使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
☞通过SAX解析工厂得到解析器对象               
SAXParser sp = spf.newSAXParser();
☞通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
☞设置读取器的事件处理器               
xmlReader.setContentHandler(new BookParserHandler());
☞解析xml文件       
xmlReader.parse("book.xml");

Books.xml MySaxParseDemo.java
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<书架>
        <书>
        <书名 id="001">浪潮之巅</书名>
                <作者>梅浩</作者>
        </书>
        <书>
                <书名 id="002">数学之美</书名>
                <作者>吴军</作者>
                <售价><第一版>29</第一版></售价>
        </书>
</书架>
package com.java.xml_sax;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MySaxParseDemo {
     public static void main(String[] args) throws  Exception {
        SAXParserFactory spf=SAXParserFactory.newInstance();
        SAXParser saxParser=spf.newSAXParser();
        MySaxhandler mySaxHandler=new MySaxhandler();
// parse(String uri, DefaultHandler dh)
//Parse the content described by the giving Uniform Resource Identifier (URI) as XML using the specified
//使用指定的 DefaultHandler 将给定统一资源标识符 (URI) 描述的内容解析为 XML。
       saxParser.parse("Books.xml",mySaxHandler); 
//调用这个方法要传递一个缺省DefaultHandler dh ,我们要自己写一个类来重写这个方法
        }
}
class MySaxhandler extends DefaultHandler{     //定义自己的类来重写方法
//写好类名和继承,右键-源码-覆盖/实现方法选择要覆盖的方法
        int count=0; //统计书名出现的次数,经常用这种方法来设置输出制定信息
        public void startDocument() throws SAXException {
                super.startDocument();
                System.out.println("MySaxHandler.startDocument()!文档开始");
        }
        public void endDocument() throws SAXException {
                super.endDocument();
                System.out.println("MySaxHandler.endDocument()!文档解析结束");
        }
public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
                super.startElement(arg0, arg1, arg2, arg3);   //鼠标放上面可以自动显示父类对应的参数名,应该是版本问题不能关联源代码。不然的话就不会显示arg了,那样可以直观看出每个参数的表示意义:startElement(String uri, String localName, String qName, Attributes attributes)
                System.out.println("MySaxHandler.startElement()!元素  "+arg2+"  节点开始");
                if(arg2=="书名"){
                        String value=arg3.getValue("id");    //通过属性名查找属性值
                        String value1=arg3.getValue(0);      //通过属性的次序查找属性值,书名里面第0个属性值
                        System.out.println("id=  "+value);
                        System.out.println("id1=  "+value1);
                }
                if(arg2=="书名"){    //标记第二本书
                        count++;
                }
        }
        public void endElement(String arg0, String arg1, String arg2) throws SAXException {
//endElement(String uri, String localName, String qName)
                super.endElement(arg0, arg1, arg2);
                System.out.println("MySaxHandler.endElement()!元素  "+arg2+"  节点闭合");
        }
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
//characters(char[] ch, int start, int length)
                if(2==count){    //当前是第二本书的时候
                        String content = new String(arg0, arg1, arg2);
                        System.out.println("MySaxHandler.characters()!文本节点" + content);
                        count=-1;  //修改变量,不然后面的都会输出
                }
                super.characters(arg0, arg1, arg2);
                /*String content = new String(arg0, arg1, arg2);
                System.out.println("MySaxHandler.characters()!文本节点" + content);*/
        }
}

//第二种方法
SAX方式解析XML文档:
1、使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
2、通过SAX解析工厂得到解析器对象               
SAXParser sp = spf.newSAXParser();
3、通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
4、设置读取器的事件处理器               
xmlReader.setContentHandler(new BookParserHandler());
5、解析xml文件       
xmlReader.parse("book.xml");
cd.xml sax.xml
<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
        <CD>
                <TITLE>Empire Burlesque</TITLE>
                <ARTIST>Bob Dylan</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>Columbia</COMPANY>
                <PRICE>10.90</PRICE>
                <YEAR>1985</YEAR>
        </CD>
        <CD>
                <TITLE>Hide your heart</TITLE>
                <ARTIST>Bonnie Tyler</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>CBS Records</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1988</YEAR>
        </CD>
        <CD>
                <TITLE>Greatest Hits</TITLE>
                <ARTIST>Dolly Parton</ARTIST>
                <COUNTRY>USA</COUNTRY>
                <COMPANY>RCA</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1982</YEAR>
        </CD>
        <CD>
                <TITLE>Still got the blues</TITLE>
                <ARTIST>Gary Moore</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Virgin records</COMPANY>
                <PRICE>10.20</PRICE>
                <YEAR>1990</YEAR>
        </CD>
        <CD>
                <TITLE>Eros</TITLE>
                <ARTIST>Eros Ramazzotti</ARTIST>
                <COUNTRY>EU</COUNTRY>
                <COMPANY>BMG</COMPANY>
                <PRICE>9.90</PRICE>
                <YEAR>1997</YEAR>
        </CD>
        <CD>
                <TITLE>One night only</TITLE>
                <ARTIST>Bee Gees</ARTIST>
                <COUNTRY>UK</COUNTRY>
                <COMPANY>Polydor</COMPANY>
                <PRICE>10.90</PRICE>
                <YEAR>1998</YEAR>
        </CD>
</CATALOG>

程序结果:
//导入包什么的没有放入笔记
public class sax {
        public static void main(String[] args) throws Exception{
//使用SAXParserFactory创建SAX解析工厂
         SAXParserFactory spf=SAXParserFactory.newInstance();
//通过SAX解析工厂得到解析器对象
        SAXParser sp=spf.newSAXParser();
//通过解析器对象得到一个XML的读取器
        XMLReader reader=sp.getXMLReader();
//设置读取器的事件处理器     
        MySaxhandler mySaxHandler=new MySaxhandler();
        reader.setContentHandler(mySaxHandler);
//解析xml文件
        reader.parse("cd.xml");
        }
}
class MySaxhandler extends DefaultHandler{
        String tagName;
        public int i=0;
        public int j=0;
        public String[] artist = new String[6];              //记录所有ARTIST
        public String[] country = new String[6];          //记录所有COUNTRY
        public Boolean ta=false;    //标记artist是读到元素开始还是元素结束
        public Boolean tc=false;    //标记country是读到元素开始还是元素结束
        public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
                        tagName=qName;     //将读取到的标签名赋给tagName
                        if(tagName.equals("ARTIST")){
                                ta=true;   //标记ARTIST是开始
                        }
                        if(tagName.equals("COUNTRY")){
                                tc=true;  //标记ARTIST是结束
                        }
        }
        public void characters(char[] ch, int start, int length)throws SAXException {
                String name=new String(ch, start, length);     //拼接出每次的文本
                if(tagName.equals("ARTIST")&& ta==true){   //如果读到ARTIST的开始,那么后面的文本就是我们要的,要存起来
                        ta=false;        //记录完,后面读到的肯定是元素结束,这里事先标记
                        artist[i++]=name;   //记录ARTIST
                }
                if(tagName.equals("COUNTRY")&&tc==true){
                        tc=false;
                        country[j++]=name;
                }       
        }
        public void endElement(String uri, String localName, String qName)throws SAXException {
                tagName=qName;
                if(tagName.equals("ARTIST")){
                        ta=false;   //再次赋值为0,确保正确
                }
                if(tagName.equals("COUNTRY")){
                        tc=false;
                }
        }
        public void endDocument() throws SAXException {
                for(int k=0;k<j;k++){
                        if(country[k].equals("UK")){
                                System.out.println("MySaxDemo.main characters() "+artist[k]);
                        }
                }
        }
}

XML解析之JAXP的更多相关文章

  1. XML 解析之 jaxp 解析器

    XML 的解析方式有两种方式: DOM 解析和 SAX 解析. DOM 解析: 根据 XML 的层级结构, 在内存中分配一个树形结构, 把 XML 的标签, 属性和文本都封装成对象. 优点: 可以实现 ...

  2. XML解析器之JAXP与DOM4J

    XML是一种数据格式,那么需要对XML文件进行操作就需要用到XML解析器---------针对dom方式和sax方式提供了不同的解析技术-----需要不同的XML解析器 dom方式:会把文档中所有元素 ...

  3. XML解析之JAXP案例详解

    根据一个CRUD的案例,对JAXP解析xml技术,进行详细的解释: 首先,已知一个xml文件中的数据如下: <?xml version="1.0" encoding=&quo ...

  4. XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax

    本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...

  5. JAVA基础学习之XMLCDATA区、XML处理指令、XML约束概述、JavaBean、XML解析(8)

    1.CDATA区在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理.遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直 ...

  6. XML解析【介绍、DOM、SAX详细说明、jaxp、dom4j、XPATH】

    什么是XML解析 前面XML章节已经说了,XML被设计为"什么都不做",XML只用于组织.存储数据,除此之外的数据生成.读取.传送等等的操作都与XML本身无关! XML解析就是读取 ...

  7. xml解析方式之JAXP解析入门

    XML解析 1 引入 xml文件除了给开发者看,更多的情况使用[程序读取xml文件]的内容.这叫做xml解析 2 XML解析方式(原理不同) DOM解析 SAX解析 3 XML解析工具 DOM解析原理 ...

  8. Java XML解析工具 dom4j介绍及使用实例

    Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...

  9. 【Java】XML解析之DOM4J

    DOM4J介绍 dom4j是一个简单的开源库,用于处理XML. XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP,使用需要引用dom4j.jar包 ...

随机推荐

  1. UNIX系统的显示时间何时会到尽头

    本文转载自:http://www.cnblogs.com/dfcao/p/expertCprogramming_intr0.html 本文分为三个小块: 一.UNIX系统中时间的存储形式: 二. ti ...

  2. arm linux利用alsa驱动并使用usb音频设备

    一.背景: arm linux的内核版本是3.13.0 二.准备工作 添加alsa驱动到内核中,也就是在编译内核的时候加入以下选项: 接下来就重新编译内核即可 三.交叉编译alsa-lib和alsa- ...

  3. JavaScript:正则表达式 问号

    问号 1.?表示重复前面内容的0次或一次(但尽可能多重复) var reg=/abc?/g; var str="abcdabcaba"; console.log(str.match ...

  4. 切面条|2014年蓝桥杯B组题解析第二题-fishers

    切面条 一根高筋拉面,中间切一刀,可以得到2根面条. 如果先对折1次,中间切一刀,可以得到3根面条. 如果连续对折2次,中间切一刀,可以得到5根面条. 那么,连续对折10次,中间切一刀,会得到多少面条 ...

  5. 【SVN】Linux搭建SVN服务

    1.yum安装svn yum install -y subversion 日志打印 Loaded plugins: fastestmirror Determining fastest mirrors ...

  6. 【打分策略】Elasticsearch打分策略详解与explain手把手计算

    一.目的 一个搜索引擎使用的时候必定需要排序这个模块,一般情况下在不选择按照某一字段排序的情况下,都是按照打分的高低进行一个默认排序的,所以如果正式使用的话,必须对默认排序的打分策略有一个详细的了解才 ...

  7. The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path 解决方法

    项目忽然出现 The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Pat ...

  8. Linux内核的五大模块

    Linux内核的五大模块 (转自)https://blog.csdn.net/huangjingbin/article/details/19396235 Linux内核的五大模块 1.进程调度模块 2 ...

  9. 用python生成器实现杨辉三角

    先看杨辉三角的形态: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 上学的时候大多是用c语言的两层for循环在实现,现在我们尝试用生成器来实现. 先说思路:我 ...

  10. MVC项目发布IIS CSS无法加载

    IIS配置网站在本地服务器调用不了CSS,新装了一个WIN8系统,IIS配置好之后做好的网站样式表浏览器不调用 处理方法 : 把静态内网 勾选打上即可 如果上述方法操作完成还是访问不鸟就继续往下看 权 ...