SAX解析XML file 介紹2

[list]
[*]1. Overview
[*]2. How to use DefaultHandler
[*]3. Focus on namespace
[/list]
[b]1. Overview[/b]
在第一篇文章介紹到SAX的基本用法,並且通過範例實現了一個簡單的解析程序,其中實現了ContentHandler, ErrorHandler, 在coding的時候,你會發現很多方法我們根本就沒有做任何處理,直接是個空實現,這對於造成了代碼的冗餘,別擔心DefaultHandler已經幫我們做了這部份工作,我們只需要直接extends DefaultHandler就Okay了, 當然假如我們的class已經extends了另外一個類了,這樣我們是不是隻能束手就擒了呢?No! 我們可以使用組合的方式將DefaultHandler給組合進來, 如: setSAXHandler( ContentHandler defaultHandler ), 這樣你就可以把你對DefaultHandler的實現給靈活的組合進來,同時也提高到了代碼的靈活性及可擴展性; 另外本篇中將簡要的介紹另外一個重要話題namespace。
[b]2. How to use DefaultHandler[/b]
DefaultHandler其實就是對接口ContentHandler, ErrorHandler等的一種適配,其中待解析的XML如下:

<?xml version="1.0" encoding="utf-8"?>
<S:books xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
<ns3:book pages="1000" price="$99">
<name>Thinking in java</name>
<version>3.0</version>
</ns3:book>
<ns3:book pages="800" price="$40">
<name>JUnit in Action</name>
<version>2.0</version>
</ns3:book>
<ns3:book pages="900" price="$70">
<name>Lucene in Action</name>
<version>2.0</version>
</ns3:book>
</S:books>

根據上面的XML文件,我們可以瞭解到,這裏使用了S,ns3分別作books, book的前綴,所以如果單純的輸出localName, 則只有少了prefix的節點名稱, 所以我們可以輸出name(prefix:localName), 這樣就可以得到全稱了, 當然這裏還牽涉到uri, 其中http://www.w3.org/2003/05/soap-envelope即爲S的uri.解析代碼如下:

package com.chris.sax.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintStream;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

public class XMLParser2 extends DefaultHandler
{

protected PrintStream output = System.out;
protected PrintStream error = System.err;
public void parserXMLFile( String fileName ) throws SAXException, IOException
{
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setContentHandler( this );
reader.setErrorHandler( this );
InputSource source = new InputSource( new FileInputStream( new File( fileName ) ) );
reader.parse(source);
}
@Override
public void startElement( String uri, String localName, String name,
Attributes attributes ) throws SAXException
{
output.append("<" +name );
for( int i = 0; i < attributes.getLength(); i++ )
{
String attrName = attributes.getQName( i );
String attrValue = attributes.getValue( i );
output.append(" " + attrName + "=" + attrValue );
}
output.append(">");
}
@Override
public void endElement( String uri, String localName, String name )
throws SAXException
{
output.println( "</" + name + ">" );
}
@Override
public void characters( char[] ch, int start, int length )
throws SAXException
{

output.append( new String(ch, start, length ) );
}
@Override
public void startDocument() throws SAXException
{
output.println("<xml version=\"1.0\" encoding=\"utf-8\"?>");
}
public static void main( String[] args ) throws SAXException, IOException
{
XMLParser2 parser = new XMLParser2();
parser.parserXMLFile("books2.xml");
}
}

瞧這些代碼,比起先前([url]SAX解析XML file 介紹[/url])那段實現簡單清晰多了, 我們override 我們關心的Methods就Okay了。
代碼運行結果如下:

<xml version="1.0" encoding="utf-8"?>
<S:books>
<ns3:book pages=1000 price=$99>
<name>Thinking in java</name>

<version>3.0</version>

</ns3:book>

<ns3:book pages=800 price=$40>
<name>JUnit in Action</name>

<version>2.0</version>

</ns3:book>

<ns3:book pages=900 price=$70>
<name>Lucene in Action</name>

<version>2.0</version>

</ns3:book>

</S:books>

[b]3. Focus on namespace[/b]
假如你要對你的nanmespace作特殊的處理,比如換掉其中的前綴,修改uri等,那麼你可以override startPrefixMapping and endPrefixMapping來一起配合完成你要的效果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章