xml解析

XML解析

DOM(Document Object Model)解析

優點:增刪改查方便

缺點:需要讀取整個xml才能構建DOM樹。對於較大的xml,容易內存溢出

SAX(Simple API for XML)解析

優點:在讀取文檔的時候,即對文檔進行處理,而不必等到整個文檔裝載完纔會文檔進行操作

缺點:不是持久的;事件過後,若沒保存數據,那麼數據就丟了;無狀態性;從事件中只能得到文本,但不知該文本屬於哪個元素

適用於只查詢


JAXP(Java API for XML Processing)

可以進行DOM解析和SAX解析,由SUN公司提供,存在於JDK中

所在包:

org.w3c.dom:提供DOM方式解析XML的標準接口

org.xml.sax:提供SAX方式解析XML的標準接口

javax.xml:提供瞭解析XML文檔的類

JAXP調用dom方式創建xml

創建一個如下所示的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<recipe type="dessert">
<recipename cuisine="american" servings="1">Ice Cream Sundae</recipename>
</recipe>

java代碼如下:

public static void createXML(String fileName) throws Exception{
    //獲取DocumentBuilderFactory
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    //獲取DocumentBuilder
        DocumentBuilder builder = factory.newDocumentBuilder();
	//獲取Document對象
	Document document = builder.newDocument();
	//設置xml聲明
	document.setXmlStandalone(false);//指定此文檔是否是單獨的的屬性
	//創建跟元素 <recipe type="dessert">
	Element rootElement = document.createElement("recipe");
	//設置元素屬性
	rootElement.setAttribute("type", "dessert");
	//創建元素<recipename>
	Element recipename = document.createElement("recipename");
	//爲recipename元素添加屬性
	recipename.setAttribute("cuisine", "american");
	recipename.setAttribute("servings", "1");
	//設置recipename元素中的值
	recipename.setTextContent("Ice Cream Sundae");
	rootElement.appendChild(recipename);
	//將根元素添加到document中
	document.appendChild(rootElement);
		
		
	//將xml映射到文件
	boolean flag = true;
	try{
	    //獲取TransformerFactorty   用於創建 Transformer 和 Templates 對象。
	    TransformerFactory tf = TransformerFactory.newInstance();
	    //獲取Transformer對象  處理來自不同源的 XML,並將轉換輸出寫入各種接收器
	    //注意:在多線程同時運行時不能使用此類的對象
	  Transformer transformer = tf.newTransformer();
	  DOMSource source = new DOMSource(document);
	  //設置編碼格式
	  transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
	  //設置indent = "yes" | "no". indent 指定了當輸出結果樹時,Transformer 是否可以添加額外的空白;其值必須爲 yes 或 no。就是幽默誒有進行格式化
	  transformer.setOutputProperty(OutputKeys.INDENT, "yes");
	  PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
	  StreamResult result = new StreamResult(pw);
	  transformer.transform(source, result);
        }catch(Exception e){
	    flag = false;
	  e.printStackTrace();
	}
	if(flag){
	  System.out.println("生成XML文件成功!");
	}else{
	    System.out.println("生成XML文件失敗!");
	}
	}

JAXP調用SAX解析XML

public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//創建解析器工廠,
		SAXParserFactory spf = SAXParserFactory.newInstance();
		//得到解析器,
		SAXParser parser = spf.newSAXParser();
		//得到讀取器
		XMLReader reader = parser.getXMLReader();
		//給內容註冊內容處理器
//		reader.setContentHandler(new MyContentHandler());
		reader.setContentHandler(new DefaultHandler(){
			public void startDocument() throws SAXException {
				// TODO Auto-generated method stub
				super.startDocument();
				System.out.println("讀取文檔開始");
			}
			public void endDocument() throws SAXException {
				// TODO Auto-generated method stub
				super.endDocument();
				System.out.println("讀取文檔結束");
			}
		});
		//解析文檔
		reader.parse("book.xml");
}

由於dom用來增刪改比較方便,所以選擇了用期進行創建修改操作,而SAX方式可以快速的進行查找便利,所以選擇用來做解析遍歷,此處就不在編寫dom解析xml的方式了。


第三方解析XML--DOM4J

解析XML,對XML進行遍歷

首先要獲取到一個Document對象

public Document parse(URL url) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(url);
        return document;
 }

然後開始進行遍歷,在文檔中找到兩種方法見代碼:

//方法1
  public void bar(Document document) throws DocumentException {

        Element root = document.getRootElement();

        // iterate through child elements of root
        for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
            Element element = (Element) i.next();
            // do something
        }

        // iterate through child elements of root with element name "foo"
        for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) {
            Element foo = (Element) i.next();
            // do something
        }

        // iterate through attributes of root 
        for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
            Attribute attribute = (Attribute) i.next();
            // do something
        }
     }
//方法2
public void treeWalk(Document document) {
        treeWalk( document.getRootElement() );
    }

    public void treeWalk(Element element) {
        for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
            Node node = element.node(i);
            if ( node instanceof Element ) {
                treeWalk( (Element) node );
            }
            else {
                // do something....
            }
        }
    }

在文檔中表明:如果說xml文件比較大的話,建議用第二種方法,可以避免了創建每個循環迭代器對象的成本。


Dom4j創建xml

/**
*創建XML
*/
 public Document createDocument() {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement( "root" );

        Element author1 = root.addElement( "author" )
            .addAttribute( "name", "James" )
            .addAttribute( "location", "UK" )
            .addText( "James Strachan" );
        
        Element author2 = root.addElement( "author" )
            .addAttribute( "name", "Bob" )
            .addAttribute( "location", "US" )
            .addText( "Bob McWhirter" );

        return document;
    }
/**
*將XML進行持久化(保存到文件)
*/
public void write(Document document) throws IOException {

        XMLWriter writer = new XMLWriter(
            new FileWriter( "output.xml" )
        );
        writer.write( document );
        writer.close();


        /*這個地方是定義輸出格式
        *OutputFormat.createPrettyPrint()  方便閱讀的格式(帶空格,帶換行)
        *OutputFormat.createCompactFormat();沒有空格換行
        *format.setEncoding(String encoding) 可以設置編碼格式,默認utf-8
        */
        OutputFormat format = OutputFormat.createPrettyPrint();
        writer = new XMLWriter( System.out, format );
        writer.write( document );
    }

以上dom4j代碼摘自文檔中

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章