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. 【Coursera】Technology :Fifth Week(1)

    Store and Forward Networking 在长途连接中,路由的数量 取决于 最优路径(花费最少).也就是说被地理条件所限制. 所以 Store and Forward Networki ...

  2. samba基本应用24-4及示例

    samba smb:service message block(137/udp, 138/udp, 139/tcp, 445/tcp) 协议是:CIFS:Common Internet File Sy ...

  3. 【BZOJ】4012: [HNOI2015]开店

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4012 给出一个$n$个点的树,树上每一个点都有一个值$age$,每条边都有边权,每次查询一 ...

  4. testNG 学习笔记 Day 3 常用的断言

    TestNG中最常用的一个断言类是Assert.java,里面有多个静态方法,这个类我们习惯叫硬断言.对应的还有一个软断言的类,叫SoftAssert.java,这个类是需要创建实例对象,才能调用相关 ...

  5. django关系类型字段

    一.多对一(ForeignKey) 多对一的关系,通常被称为外键.外键字段类的定义如下: class ForeignKey(to, on_delete, **options)[source] 外键需要 ...

  6. 【Golang 接口自动化03】 解析接口返回XML

    上一篇我们学习了怎么发送各种数据类型的http请求,这一篇我们来介绍怎么来解析接口返回的XML的数据. 解析接口返回数据 定义结构体 假设我们现在有一个接口返回的数据resp如下: <?xml ...

  7. RabbitMQ入门_11_DLX

    参考资料:https://www.rabbitmq.com/dlx.html 队列中的消息可能会成为死信消息(dead lettered).让消息成为死信消息的事件有: 消息被取消确认(nack 或 ...

  8. Codeforces 757B - Bash's Big Day(分解因子+hashing)

    757B - Bash's Big Day 思路:筛法.将所有因子个数求出,答案就是最大的因子个数,注意全为1的特殊情况. 代码: #include<bits/stdc++.h> usin ...

  9. jsp动作之 forward

    forward说明了,就想当于php的include,require函数.(但是它是跳转.forward之前的数据都不会显示) 这么说你明白了吗.就是包含,说的好听点就是跳转,但是url地址栏却是没有 ...

  10. 女生学java是否真的没有优势

    随着女性越来越独立,我们可以看到再以前我们认为不适合女性朋友从事的工作,也出现了越来越多的女生,例如对IT行业也不再跟之前一样畏惧.虽然当下很多人所持的观点依旧是,女生不适合IT行业,但是很多女生已经 ...