zoukankan      html  css  js  c++  java
  • JAXP(Java API for XML Parsing)

    JAXP(Java API for XML Parsing) 
     
    过去几年中,XML分折已经被标准为两个不同的处理模型:SAX(Simple API for XML)以及DOM(Document Object Model)。

     
    这 两个标准提供了各种API以便开发人员处理XML数据,分别适用于不同的分折需要。JAXP是SUN公司在1999年后期提出的,它是一个API,但更准 确地说,它应该是一个抽象层。JAXP并不提供解折功能!没有SAX、DOM或其它XML解折API,我们无法解折XML。 
    一、SAX(Simple API for XML)
    SAX是基于事件的处理模型,在此模型中,解折程序按序列顺序解释数据元素,同时基于所选择的结构回调函数。它最大的优点是:它并不把任何XML文档装载进内存,因此被认为是非常迅速和轻便的。它使用一个序列只读的方法,并不支持对XML元素的随机访问。 
    基本实现由以下三个骤组成
    1、实现一个扩展DefaultHandler的类,并为每种类型的结构包含回调方法。
    2、初始化一个新的SAXParser类。Parser读到XML源文件,并触发DefaultHandler类中所实现的一个回调方法
    3、须序读取XML源文件。在须序读取中,无法随机访问结构中的元素。剩下的工作取决于Handler类中你的实现方案。 
    示例
    书写一个用于读取的XML文檔test.xml,具体内容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <simple date="21/2/2006">
            <name>wang</name>
            <location>China DongGuan</location>
    </simple>
     
    实现一个扩展DefaultHandler的类SaxTestHandler.java代码如下
    package mypack;
     
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
     
    public class SaxTestHandler extends DefaultHandler {
     
            // 重载DefaultHandler类的方法
            // 以拦截SAX事件通知。
            //      
     
            /* 开始解折文析进执行 */
            public void startDocument() throws SAXException {
                    System.out.println("SAX Event: START DOCUMENT");
            }
     
            /* 结束解折时执行 */
            public void endDocument() throws SAXException {
                    System.out.println("SAX Event: END DOCUMENT");
            }
     
            /* 遇到一个节点时执行 */
            public void startElement(String namespaceURI, String localName,
                            String qName, Attributes attr) throws SAXException {
                    System.out.println("SAX Event: START ELEMENT[ " + localName + " ]");
                    // System.out.println(namespaceURI+";;;"+qName);
     
                    // 如果有属性,打印属性和属性值
                    for (int i = 0; i < attr.getLength(); i++) {
                            System.out.println(" ATTRIBUTE: " + attr.getLocalName(i)
                                            + " VALUE: " + attr.getValue(i));
                    }
            }
     
            // 元素数据
            public void characters(char[] ch, int start, int length)
                            throws SAXException {
                    String s = new String(ch, start, length);
                    System.out.println(s);
            }
    }
     
    这个类实现了内容处理接口的实现,该实现只做了一个简单的处理:把有关XML文文件的内容打印到系统控制台。
     
    一个SAXParser类,用于指定解折器并读取XML文档然后调用Handler类的回调方法。代码如下:
    package mypack;
     
    import java.io.FileReader;
     
    import org.xml.sax.InputSource;
    import org.xml.sax.XMLReader;
    import org.xml.sax.helpers.XMLReaderFactory;
     
    public class SAXTest {
     
            /**
             * @param args
             */
            public static void main(String[] args) {
                    // TODO 自动产生方法 
                    try {
                            // 建立SAX2解折器
                            XMLReader xr = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
     
                            // 安装ContentHandler内容处理类
                            SaxTestHandler handler=new SaxTestHandler();
                            xr.setContentHandler( handler );
     
                            // 解折文檔
                            xr.parse(new InputSource(new FileReader("D://MyProject//Ewebsite//XML//JavaSource//test.xml")));
                    } catch (Exception e) {
                            e.printStackTrace();
                    }
            }
    }
     
    执行SAXTest可以打印出test.xml文件的内容(节点名,节点的属性及值,元素内容)
     
    二、DOM(Document Object Model)
    XML 将数据组织为一棵树,所以DOM就是对这棵树的一个对象描叙。通俗的说,就是通过解折XML文档,为XML文文件在逻辑上建立一个树模型,树的节点就是一 个个对象。我们通过存到这些对象就能够存取XML文档的内容。当XML文档很大时,这个过程可能需要一块相当大的内存,这可能出现内存不足的现象。
     
    使用DOM处理的基本步骤如下:
    1、实例一个DOMParser。
    2、得到一个Document对象。
    3、使用Document对象访问代表了XML文文件中元素的节点。
     
    XML源被完全读入内存,并用Document对象表示。这就使得应用程序能够随机访问任何节点,这一点也是SAX所不能做到的。
     
    一个读取XML文檔的DOM处理示例
    package mypack;
     
    import java.io.FileReader;
    import java.io.IOException;
     
    import javax.xml.parsers.ParserConfigurationException;
     
    import org.apache.xerces.parsers.DOMParser;//导入DOMParser解折器
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
     
    public class DOMTest {
     
            /**
             * @param args
             * @throws ParserConfigurationException
             * @throws IOException
             * @throws SAXException
             */
            public static void main(String[] args) throws ParserConfigurationException,
                            SAXException, IOException {
                    // TODO 自动产生方法 Stub
     
                    // 实例解折器
                    DOMParser parser = new DOMParser();
                    // 以Docment对象的形式获取DOM树
                    parser.parse(new InputSource(new FileReader(
                                    "D://MyProject//Ewebsite//XML//JavaSource//test.xml")));
                    Document doc = parser.getDocument();
                    // 使用Document对象的方法得到NodeList对象
                    NodeList nl = doc.getElementsByTagName("name");
                    System.out.println(nl.getLength());// 标签的次数
                    Node my_node = nl.item(0);
                    // 输出name标签的元素数据
                    String name = my_node.getFirstChild().getNodeValue();
                    System.out.println(name);
            }
    }
     
    现在,既然我们已经能够从XML文件中提取出数据了,我们就可以把这些数据用在合适的地方,来构筑应用程序。
     
    DOM对象详解
    1.基本的DOM对象

    DOM的基本对象有5个:Document,Node,NodeList,Element和Attr。下面就这些对象的功能和实现的方法作一个大致的介绍。

    Document 对象代表了整个XML的文档,所有其它的Node,都以一定的顺序包含在Document对象之内,排列成一个树形的结构,程序员可以通过遍历这颗树来得 到XML文档的所有的内容,这也是对XML文档操作的起点。我们总是先通过解析XML源文件而得到一个Document对象,然后再来执行后续的操作。此 外,Document还包含了创建其它节点的方法,比如createAttribut()用来创建一个Attr对象。它所包含的主要的方法有:

    createAttribute(String):用给定的属性名创建一个Attr对象,并可在其后使用setAttributeNode方法来放置在某一个Element对象上面。

    createElement(String):用给定的标签名创建一个Element对象,代表XML文档中的一个标签,然后就可以在这个Element对象上添加属性或进行其它的操作。

    createTextNode(String):用给定的字符串创建一个Text对象,Text对象代表了标签或者属性中所包含的纯文本字符串。如果在一个标签内没有其它的标签,那么标签内的文本所代表的Text对象是这个Element对象的唯一子对象。

    getElementsByTagName(String):返回一个NodeList对象,它包含了所有给定标签名字的标签。

    getDocumentElement():返回一个代表这个DOM树的根节点的Element对象,也就是代表XML文档根元素的那个对象。

    Node 对象是DOM结构中最为基本的对象,代表了文档树中的一个抽象的节点。在实际使用的时候,很少会真正的用到Node这个对象,而是用到诸如 Element、Attr、Text等Node对象的子对象来操作文档。Node对象为这些对象提供了一个抽象的、公共的根。

    Node 接口是整个文档对象模型的主要数据类型。它表示该文档树中的单个节点。当实现 Node 接口的所有对象公开处理子节点的方法时,不是实现 Node 接口的所有对象都有子节点。例如,Text 节点可能没有子节点,且将子节点添加到这样的节点将导致引发 DOMException

    包括属性 nodeNamenodeValueattributes 作为一种获取节点信息的机制,无需向下强制转换为特定的派生接口。在没有对特定的 nodeType(如 ElementnodeValueCommentattributes)的属性的明显映射的情况下,这将返回 null。注意,特定的接口可能包含其他更方便的机制来获取和设置相关信息。

    nodeNamenodeValueattributes 的值将根据以下节点类型的不同而不同。

    Interface nodeName nodeValue attributes
    Attr Attr.name 相同 Attr.value 相同 null
    CDATASection "#cdata-section" CharacterData.data 相同,CDATA 节的内容 null
    Comment "#comment" CharacterData.data 相同,该注释的内容 null
    Document "#document" null null
    DocumentFragment "#document-fragment" null null
    DocumentType DocumentType.name 相同 null null
    Element Element.tagName 相同 null NamedNodeMap
    Entity entity name null null
    EntityReference 引用的实体名称 null null
    Notation notation name null null
    ProcessingInstruction ProcessingInstruction.target 相同 ProcessingInstruction.data 相同 null
    Text "#text" CharacterData.data 相同,该文本节点的内容 null

    虽然在Node对象中定义了 对其子节点进行存取的方法,但是有一些Node子对象,比如Text对象,它并不存在子节点,这一点是要注意的。Node对象所包含的主要的方法有:

    appendChild(org.w3c.dom.Node):为这个节点添加一个子节点,并放在所有子节点的最后,如果这个子节点已经存在,则先把它删掉再添加进去。

    getFirstChild():如果节点存在子节点,则返回第一个子节点,对等的,还有getLastChild()方法返回最后一个子节点。

    getNextSibling():返回在DOM树中这个节点的下一个兄弟节点,对等的,还有getPreviousSibling()方法返回其前一个兄弟节点。

    getNodeName():根据节点的类型返回节点的名称。

    getNodeType():返回节点的类型。

    getNodeValue():返回节点的值。

    hasChildNodes():判断是不是存在有子节点。

    hasAttributes():判断这个节点是否存在有属性。

    getOwnerDocument():返回节点所处的Document对象。

    insertBefore(org.w3c.dom.Node new,org.w3c.dom.Node ref):在给定的一个子对象前再插入一个子对象。

    removeChild(org.w3c.dom.Node):删除给定的子节点对象。

    replaceChild(org.w3c.dom.Node new,org.w3c.dom.Node old):用一个新的Node对象代替给定的子节点对象。

    NodeList对象,顾名思义,就是代表了一个包含了一个或者多个Node的列表。可以简单的把它看成一个Node的数组,我们可以通过方法来获得列表中的元素:

    GetLength():返回列表的长度。

    Item(int):返回指定位置的Node对象。

    Element对象代表的是XML文档中的标签元素,继承于Node,亦是Node的最主要的子对象。在标签中可以包含有属性,因而Element对象中有存取其属性的方法,而任何Node中定义的方法,也可以用在Element对象上面。

    getElementsByTagName(String):返回一个NodeList对象,它包含了在这个标签中其下的子孙节点中具有给定标签名字的标签。

    getTagName():返回一个代表这个标签名字的字符串。

    getAttribute(String): 返回标签中给定属性名称的属性的值。在这儿需要主要的是,应为XML文档中允许有实体属性出现,而这个方法对这些实体属性并不适用。这时候需要用到 getAttributeNodes()方法来得到一个Attr对象来进行进一步的操作。

    getAttributeNode(String):返回一个代表给定属性名称的Attr对象。

    Attr 对象代表了某个标签中的属性。Attr继承于Node,但是因为Attr实际上是包含在Element中的,它并不能被看作是Element的子对象,因 而在DOM中Attr并不是DOM树的一部分,所以Node中的getparentNode(),getdivviousSibling()和 getnextSibling()返回的都将是null。也就是说,Attr其实是被看作包含它的Element对象的一部分,它并不作为DOM树中单独 的一个节点出现。这一点在使用的时候要同其它的Node子对象相区别。

    需要说明的是,上面所说的DOM对象在DOM中都是用接口定义的, DOM其实可以在任何面向对象的语言中实现,只要它实现了DOM所定义的接口和功能就可以了。
     
    三、JAXP
    1、用SAX处理XML
    下面是JAXP的操作示范
    (1)   创建已实现的Handler类的实例。
    (2)   利用SAXParserFactory的静态方法newInstance()方法获取一个factory类。
    (3)   通过newSAXParser()静态方法从factory中获取SAX分折器。
    (4)   分折XML数据:调用SAXParser的分折方法,把XML输入作为第一个参数,而Handler实现方案作为第二个参数。
     
     
    示例代码如下:
    package mypack;
     
    import java.io.IOException;
     
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
     
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
     
    public class JaxpSaxTest {
            /**
             * @param args
             * @throws SAXException 
             * @throws ParserConfigurationException 
             * @throws IOException 
             */
            public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
                    // TODO 自动产生方法 Stub
                    //实例一个内容处理类
                    DefaultHandler handler=new SaxTestHandler();
                    //得到厂类
                    SAXParserFactory factory=SAXParserFactory.newInstance();
                    //在厂类中获取SAX分折器
                    SAXParser parser=factory.newSAXParser();
                    //分折XML数据
                    parser.parse("D://MyProject//Ewebsite//XML//JavaSource//test.xml",handler);
            }
    }
     
    2、用DOM处理
     
    步聚如下: 
    (1)初始化一个新的Builder类。Builder类负责读取XML数据并把XML数据转化为树状表示。
    (2)一旦数据转化完成,即创建Document对象。一旦对象创建后,以后所有的对XML文档的操作都与解折器无关了。
    (3) 使用Document对象访问代表了XML文文件中元素的节点。
     
    示例代码如下:
    package mypack;
     
    import java.io.IOException;
     
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
     
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.SAXException;
     
    public class JaxpDomTest {
            /**
             * @param args
             * @throws ParserConfigurationException
             * @throws IOException
             * @throws SAXException
             */
            public static void main(String[] args) throws ParserConfigurationException,
                            SAXException, IOException {
                    // TODO 自动产生方法 Stub
     
                    // 实例一个Builder类,用DocumentBuilder的目的是为了创建与具体解折器无关的程序
                    // 厂类的静态方法newInstance()被调用时,它根据一个系统变量来决定具体使用哪一个解折器。
                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder builder = factory.newDocumentBuilder();
     
                    // 创建Document对象
                    Document document = builder
                                    .parse("D://MyProject//Ewebsite//XML//JavaSource//test.xml");
     
                    // 使用Document对象的方法得到NodeList对象
                    NodeList nl = document.getElementsByTagName("name");
                    System.out.println(nl.getLength());// 标签的次数
                    Node my_node = nl.item(0);
                    // 输出name标签的元素数据
                    String name = my_node.getFirstChild().getNodeValue();
                    System.out.println(name);
            }
     
    }

     

     

     

    http://www.99inf.net/SoftwareDev/Java/43727.htm

  • 相关阅读:
    java ssl https 连接详解 生成证书
    mysql实战优化之四:mysql索引优化
    mysql实战优化之五: 更新/插入优化 sql优化
    mysql实战优化之六:Order by优化 sql优化、索引优化
    mina2中IoHandler
    I/O通信模型(BIO,NIO,AIO)
    mina框架详解
    转:架构师于小波:魅族实时消息推送架构
    支付业务的数据库表的设计
    实战 TestNG 监听器
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959341.html
Copyright © 2011-2022 走看看