天天看點

JAXP學習(2)簡單示例

本文結合執行個體對JAXP進行基本學習。

DOM (Document Object Model APIs)

DOM方式解析XML

The DOM API is generally an easier API to use. It provides a familiar tree structure of objects. You can use the DOM API to manipulate the hierarchy of application objects it encapsulates. The DOM API is ideal for interactive applications because the entire object model is present in memory, where it can be accessed and manipulated by the user.
JAXP學習(2)簡單示例

下面給出示例的目錄結構和示例

JAXP學習(2)簡單示例

books.xml

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="COOKING">
  <title lang="en">Everyday Italian</title> 
  <author>Giada De Laurentiis</author> 
  <year>2005</year> 
  <price>30.00</price> 
</book>
<book category="CHILDREN">
  <title lang="en">Harry Potter</title> 
  <author>J K. Rowling</author> 
  <year>2005</year> 
  <price>29.99</price> 
</book>
<book category="WEB">
  <title lang="en">Learning XML</title> 
  <author>Erik T. Ray</author> 
  <year>2003</year> 
  <price>39.95</price> 
</book>
</bookstore>
           

Book.java

package entity;

public class Book {
    private String title;
    private String author;
    private String year;
    private String price;
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getYear() {
        return year;
    }
    public void setYear(String year) {
        this.year = year;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Book [title=" + title + ", author=" + author + ", year=" + year + ", price=" + price + "]";
    }
    public Book() {
        super();
    }
    public Book(String title, String author, String year, String price) {
        super();
        this.title = title;
        this.author = author;
        this.year = year;
        this.price = price;
    }

}
           

JaxpDomTest.java

package test;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.Test;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

import entity.Book;
/**
 * 測試JAXP DOM方式操作XML
 * @author Administrator 2017年6月23日09:10:42
 *
 */
public class JaxpDomTest {
    /**
     * XML讀取
     */
    @Test
    public void domTest(){
        try {
            //擷取xml資料
            ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
            InputStream is=classLoader.getResourceAsStream("xmldoc/books.xml");
            //擷取DocumentBuilder
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder db = factory.newDocumentBuilder();
            //将xml解析為Document
            Document doc = db.parse(is);
            //處理Document
            NodeList list = doc.getElementsByTagName("book");
            int nodeLength=list.getLength();
            for(int i=;i<nodeLength;i++){
                Element ele=(Element)list.item(i);
                String title=ele.getElementsByTagName("title").item().getTextContent();
            String author=ele.getElementsByTagName("author").item().getFirstChild().getNodeValue();
                String year=ele.getElementsByTagName("year").item().getFirstChild().getNodeValue();
                String price=ele.getElementsByTagName("price").item().getFirstChild().getNodeValue();
                Book book=new Book(title, author, year, price);
                System.out.println(book.toString());
            }
        } catch (DOMException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

讀取xml内容并儲存到Book執行個體中。domTest()運作結果

Book [title=Everyday Italian, author=Giada De Laurentiis, year=2005, price=30.00]
Book [title=Harry Potter, author=J K. Rowling, year=2005, price=29.99]
Book [title=Learning XML, author=Erik T. Ray, year=2003, price=39.95]

           

這裡隻簡單示範讀取XML操作,DOM的修改,添加,删除可結合API學習。

SAX(Simple API for XML APIs)

SAX方式解析XML

The Simple API for XML (SAX) is the event-driven, serial-access mechanism that does element-by-element processing. The API for this level reads and writes XML to a data repository or the web. For server-side and high-performance applications, you will want to fully understand this level. But for many applications, a minimal understanding will suffice.
JAXP學習(2)簡單示例

SAX示例代碼:

JaxpSaxTest.java

package test;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.junit.Test;
import org.xml.sax.SAXException;

/**
 * JAXP SAX方式讀取XML
 * @author Administrator 2017年6月28日10:05:54
 *
 */
public class JaxpSaxTest {
    @Test
    public void saxTest(){
        try {
            //擷取SAXParser
            SAXParserFactory factory=SAXParserFactory.newInstance();
            SAXParser newSAXParser = factory.newSAXParser();
            //解析xml資料,并定義事件處理器(SAXParser會回調MySAXEventHandler中對應的方法).
            newSAXParser.parse(new File("src/xmldoc/books.xml"), new MySAXEventHandler());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
           

MySAXEventHandler.java

package test;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import entity.Book;

/**
 * 自定義事件處理器繼承DefaultHandler,根據需要重寫DefaultHandler的方法
 * @author Administrator 2017年6月28日10:08:27
 *
 */
public class MySAXEventHandler extends DefaultHandler {
    /**
     * 标簽名稱,用以區分不同的标簽
     */
    private String tagName="";
    /**
     * Book對應xml中<book>元素
     */
    private Book book=new Book();
    /**
     * Book集合對應xml中<bookstore>元素
     */
    private List<Book> bookstore=new ArrayList<>();

    /**
     * 文檔開始事件
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("........startDocument.......");
    }
    /**
     * 元素開始事件
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.print("<"+qName+">");
        tagName=qName;
        if("book".equals(qName)){
            book=new Book();
        }
    }
    /**
     * 文本資料事件
     */
    @Override
    public void characters(char ch[], int start, int length) throws SAXException {
        String content=new String(ch, start, length);
        System.out.print(content);
        switch (tagName){
            case "title": 
                book.setTitle(content);
                break;
            case "author":
                book.setAuthor(content);
                break;
            case "year":
                book.setYear(content);
                break;
            case "price":
                book.setPrice(content);
                break;
        }
    }
    /**
     * 元素結束事件
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.print("</"+qName+">");
        tagName="";//清空标記,防止endElement()方法結束後,再次回調characters()時,switch語句的條件仍然是qName值。
        if("book".equals(qName)){
            bookstore.add(book);
        }
    }
    /**
     * 文檔結束時間
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("\n"+".............endDocument..............");
        for(Book bk:bookstore){
            System.out.println(bk.toString());
        }
    }
}
           

運作saxTest(),運作結果:

........startDocument.......
<bookstore>
<book>
  <title>Everyday Italian</title> 
  <author>Giada De Laurentiis</author> 
  <year>2005</year> 
  <price>30.00</price> 
</book>
<book>
  <title>Harry Potter</title> 
  <author>J K. Rowling</author> 
  <year>2005</year> 
  <price>29.99</price> 
</book>
<book>
  <title>Learning XML</title> 
  <author>Erik T. Ray</author> 
  <year>2003</year> 
  <price>39.95</price> 
</book>
</bookstore>
.............endDocument..............
Book [title=Everyday Italian, author=Giada De Laurentiis, year=2005, price=30.00]
Book [title=Harry Potter, author=J K. Rowling, year=2005, price=29.99]
Book [title=Learning XML, author=Erik T. Ray, year=2003, price=39.95]
           

可以看出,使用SAX解析XML時,通常要自定義事件處理器繼承DefaultHandler。

StAX(Streaming API for XML)

StAX方式解析XML

To summarize, StAX provides a standard, bidirectional pull parser interface for streaming XML processing, offering a simpler programming model than SAX and more efficient memory management than DOM. StAX enables developers to parse and modify XML streams as events, and to extend XML information models to allow application-specific additions.

StAX示例代碼

JaxpStaxTest.java

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.junit.Test;
/**
 * JAXP StAX方式解析XML
 * @author Administrator 2017年6月28日10:22:31
 *
 */
public class JaxpStaxTest {
    /**
     * 基于指針的方式
     */
    @Test
    public void staxCursorTest(){
        try {
            //擷取XMLStreamReader
            XMLInputFactory factory=XMLInputFactory.newFactory();
            File file=new File("src/xmldoc/books.xml");
            XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(new FileInputStream(file));
            //用xmlStreamReader擷取資料
            while(xmlStreamReader.hasNext()){
                int eventType=xmlStreamReader.getEventType();
                switch(eventType){
                    case XMLStreamReader.START_DOCUMENT:
                        System.out.println("------------START_DOCUMENT----------------");
                        break;
                    case XMLStreamReader.START_ELEMENT:
                        System.out.print("<"+xmlStreamReader.getLocalName()+">");
                        break;
                    case XMLStreamReader.CHARACTERS:
                        System.out.print(xmlStreamReader.getText());
                        break;
                    case XMLStreamReader.END_ELEMENT:
                        System.out.print("</"+xmlStreamReader.getLocalName()+">");
                        break;
                }
                int nextType=xmlStreamReader.next();
                if(nextType==XMLStreamReader.END_DOCUMENT){
                    System.out.println("\n"+"------------END_DOCUMENT------------------");
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
    }
    /**
     * 基于疊代器的方式
     */
    @Test
    public void staxIteratorTest(){
        try {
            //擷取XMLEventReader
            XMLInputFactory factory=XMLInputFactory.newFactory();
            File file=new File("src/xmldoc/books.xml");
            XMLEventReader xmlEventReader = factory.createXMLEventReader(new FileInputStream(file));
            //用XMLEvent擷取資料
            while (xmlEventReader.hasNext()) {
                XMLEvent xmlEvent=xmlEventReader.peek();
                int eventType=xmlEvent.getEventType();
                switch(eventType){
                    case XMLEvent.START_DOCUMENT:
                        System.out.println("----START_DOCUMENT----");
                        break;
                    case XMLEvent.START_ELEMENT:
                        StartElement startElement = xmlEvent.asStartElement();
                        System.out.print("<"+startElement.getName()+">");
                        break;
                    case XMLEvent.CHARACTERS:
                        Characters characters = xmlEvent.asCharacters();
                        System.out.print(characters.getData());
                        break;
                    case XMLEvent.END_ELEMENT:
                        EndElement endElement = xmlEvent.asEndElement();
                        System.out.print("</"+endElement.getName()+">");
                        break;
                    case XMLEvent.END_DOCUMENT:
                        System.out.print("\n"+"-----END_DOCUMENT----");
                        break;
                }
                xmlEventReader.nextEvent();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        }
    }
}
           

運作staxCursorTest()和staxIteratorTest()結果類似,如下所示:

----START_DOCUMENT----
<bookstore>
<book>
  <title>Everyday Italian</title> 
  <author>Giada De Laurentiis</author> 
  <year>2005</year> 
  <price>30.00</price> 
</book>
<book>
  <title>Harry Potter</title> 
  <author>J K. Rowling</author> 
  <year>2005</year> 
  <price>29.99</price> 
</book>
<book>
  <title>Learning XML</title> 
  <author>Erik T. Ray</author> 
  <year>2003</year> 
  <price>39.95</price> 
</book>
</bookstore>
-----END_DOCUMENT----
           

StAX提供了兩種解析方式。直覺的差別在于Cursor方式通過xmlStreamReader擷取資料,Iterator方式通過xmlEvent擷取資料。

XSLT(Extensible Stylesheet Language Transformations)

簡單介紹XSLT

The Extensible Stylesheet Language Transformations (XSLT) standard defines mechanisms for addressing XML data (XPath) and for specifying transformations on the data in order to convert it into other forms. JAXP includes an interpreting implementation of XSLT
JAXP學習(2)簡單示例

代碼:

JaxpXsltTest.java

package test;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * JAXP xslt簡單示例
 * @author Administrator 2017年6月28日10:53:35
 *
 */
public class JaxpXsltTest {
    @Test
    public void xsltTest(){
        try {
            // 擷取Transformer
            TransformerFactory tFactory =TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            //擷取資料源
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new File("src/xmldoc/books.xml"));
            DOMSource source = new DOMSource(document);
            //擷取結果流
            StreamResult result = new StreamResult(System.out);
            //将資料源轉換(傳輸)到結果流中
            transformer.transform(source, result);

        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerFactoryConfigurationError e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
}
           
JAXP學習(2)簡單示例

這裡隻是JAXP的簡單示例,不同解析方式的了解和對比後續介紹。

參考資料:

XPath JAVA用法總結及代碼樣例

Java API for XML Processing (JAXP)

繼續閱讀