分享

JAXP(Java API for XML Parsing)

 芳草小集 2006-03-24
 

JAXP(Java API for XML Parsing) 

 

過去幾年中,XML分折已經被標准為兩個不同的處理模型:SAX(Simple API for XML)以及DOM(Document Object Model)。這兩個標准提供了各種API以便開發人員處理XML數據,分別適用於不同的分折需要。JAXPSUN公司在1999年後期提出的,它是一個API,但更准確地說,它應該是一個抽象層。JAXP並不提供解折功能!沒有SAXDOM或其它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个:DocumentNodeNodeListElementAttr下面就这些对象的功能和实现的方法作一个大致的介绍。

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这个对象,而是用到诸如ElementAttrTextNode对象的子对象来操作文档。Node对象为这些对象提供了一个抽象的、公共的根。虽然在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的子对象,因而在DOMAttr并不是DOM树的一部分,所以Node中的getparentNode()getpreviousSibling()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);

        }

 

}

 

 

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多