Java SAX XML解析器代表Simple API for XML(SAX)解析器。
SAX是一種用于訪問XML文檔的事件驅(qū)動(dòng)的串行訪問機(jī)制。
此機(jī)制經(jīng)常用于傳輸和接收XML文檔。
SAX是一種狀態(tài)獨(dú)立處理,其中元素的處理不依賴于其他元素。StAX是狀態(tài)相關(guān)處理。
SAX是一個(gè)事件驅(qū)動(dòng)模型。 當(dāng)使用SAX解析器時(shí),我們提供了回調(diào)方法,并且解析器在讀取XML數(shù)據(jù)時(shí)調(diào)用它們。
在SAX中,我們不能回到文檔的早期部分,我們只能處理元素逐個(gè)元素,從開始到結(jié)束。
SAX是快速和高效的,并且它對(duì)于狀態(tài)無關(guān)的過濾是有用的。當(dāng)遇到元素標(biāo)記和時(shí),SAX解析器調(diào)用一個(gè)方法當(dāng)發(fā)現(xiàn)文本時(shí)調(diào)用不同的方法。
SAX比DOM要求更少的內(nèi)存,因?yàn)镾AX不像DOM那樣創(chuàng)建XML數(shù)據(jù)的內(nèi)部樹結(jié)構(gòu)。
在下面我們將看到一個(gè)輸出所有SAX事件的演示應(yīng)用程序。它是從包中擴(kuò)展 DefaultHandler
org.xml.sax.helpers
如下。
public class Main extends DefaultHandler {
以下代碼設(shè)置了解析器并啟動(dòng)它:
SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); parser = spf.newSAXParser(); parser.parse(file, this);
這些代碼行創(chuàng)建一個(gè)SAXParserFactory實(shí)例,由 javax.xml.parsers.SAXParserFactory
系統(tǒng)屬性的設(shè)置決定。
工廠被設(shè)置為支持XML命名空間將 setNamespaceAware
設(shè)置為 true
然后通過 newSAXParser()
方法從工廠獲取SAXParser實(shí)例。
然后它處理開始文檔和結(jié)束文檔事件:
public void startDocument() { System.out.println("Start document: "); } public void endDocument() { System.out.println("End document: "); }
之后,它使用 System.out.println
打印消息一旦方法是由解析器調(diào)用。
遇到開始標(biāo)記或結(jié)束標(biāo)記時(shí),根據(jù)需要,將標(biāo)記的名稱作為String傳遞到 startElement
或 endElement
方法。
當(dāng)遇到開始標(biāo)記時(shí),它定義的任何屬性都會(huì)在 Attributes
列表中傳遞。
public void startElement(String uri, String localName, String qname, Attributes attr) { System.out.println("Start element: local name: " + localName + " qname: " + qname + " uri: " + uri); }
元素中的字符作為字符數(shù)組傳遞,以及字符數(shù)和指向第一個(gè)字符的數(shù)組的偏移量。
public void characters(char[] ch, int start, int length) { System.out.println("Characters: " + new String(ch, start, length)); }
完整的代碼。
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.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class Main extends DefaultHandler { private static Main handler = null; private SAXParser parser = null; public static void main(String args[]) { if (args.length == 0) { System.out.println("No file to process. Usage is:" + "\njava TrySAX <filename>"); return; } File xmlFile = new File(args[0]); handler = new Main(); handler.process(xmlFile); } private void process(File file) { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); System.out.println("Parser will " + (spf.isNamespaceAware() ? "" : "not ") + "be namespace aware"); System.out.println("Parser will " + (spf.isValidating() ? "" : "not ") + "validate XML"); try { parser = spf.newSAXParser(); System.out.println("Parser object is: " + parser); } catch (SAXException e) { e.printStackTrace(System.err); System.exit(1); } catch (ParserConfigurationException e) { e.printStackTrace(System.err); System.exit(1); } System.out.println("\nStarting parsing of " + file + "\n"); try { parser.parse(file, this); } catch (IOException e) { e.printStackTrace(System.err); } catch (SAXException e) { e.printStackTrace(System.err); } } public void startDocument() { System.out.println("Start document: "); } public void endDocument() { System.out.println("End document: "); } public void startElement(String uri, String localName, String qname, Attributes attr) { System.out.println("Start element: local name: " + localName + " qname: " + qname + " uri: " + uri); } public void endElement(String uri, String localName, String qname) { System.out.println("End element: local name: " + localName + " qname: " + qname + " uri: " + uri); } public void characters(char[] ch, int start, int length) { System.out.println("Characters: " + new String(ch, start, length)); } public void ignorableWhitespace(char[] ch, int start, int length) { System.out.println("Ignorable whitespace: " + new String(ch, start, length)); } }
上面的代碼生成以下結(jié)果。
解析器可以生成三種錯(cuò)誤:
當(dāng)發(fā)生致命錯(cuò)誤時(shí),解析器無法繼續(xù)。
對(duì)于非致命錯(cuò)誤和警告,默認(rèn)錯(cuò)誤處理程序不會(huì)生成異常,也不會(huì)顯示任何消息。
下面的行安裝我們自己的錯(cuò)誤處理程序。
reader.setErrorHandler(new MyErrorHandler());
MyErrorHandler
類實(shí)現(xiàn)標(biāo)準(zhǔn) org.xml.sax.ErrorHandler
接口,并定義一種方法來獲取任何SAXParseException提供的異常信息。
完整的代碼。
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; class MyErrorHandler implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { show("Warning", e); throw (e); } public void error(SAXParseException e) throws SAXException { show("Error", e); throw (e); } public void fatalError(SAXParseException e) throws SAXException { show("Fatal Error", e); throw (e); } private void show(String type, SAXParseException e) { System.out.println(type + ": " + e.getMessage()); System.out.println("Line " + e.getLineNumber() + " Column " + e.getColumnNumber()); System.out.println("System ID: " + e.getSystemId()); } } // Installation and Use of an Error Handler in a SAX Parser public class SAXCheck { static public void main(String[] arg) throws Exception { boolean validate = false; validate = true; SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(validate); XMLReader reader = null; SAXParser parser = spf.newSAXParser(); reader = parser.getXMLReader(); reader.setErrorHandler(new MyErrorHandler()); InputSource is = new InputSource("test.xml"); reader.parse(is); } }
我們可以在使用SAXParser解析期間打開XML模式驗(yàn)證。
import java.io.File; import javax.xml.XMLConstants; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; public class Main { public static void main(String args[]) throws Exception { String language = XMLConstants.W3C_XML_SCHEMA_NS_URI; SchemaFactory factory = SchemaFactory.newInstance(language); Schema schema = factory.newSchema(new File("yourSchema")); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setSchema(schema); SAXParser parser = spf.newSAXParser(); // parser.parse(...); } }
以下代碼顯示了當(dāng)使用DefaultHandler時(shí)我們不需要實(shí)現(xiàn)所有的方法,我們只需要提供實(shí)現(xiàn)我們關(guān)心的方法。
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class Main { public static void main(String args[]) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println(qName); } public void characters(char ch[], int start, int length) throws SAXException { System.out.println(new String(ch, start, length)); } }; saxParser.parse(args[0], handler); } }
以下代碼通過覆蓋DefaultHandler中的錯(cuò)誤處理程序方法來處理SAX錯(cuò)誤
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; public class Main { public static void main(String[] argv) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); SAXParser parser = factory.newSAXParser(); SaxHandler handler = new SaxHandler(); parser.parse("sample.xml", handler); } } class SaxHandler extends DefaultHandler { public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { if (qName.equals("order")) { } } public void error(SAXParseException ex) throws SAXException { System.out.println("ERROR: [at " + ex.getLineNumber() + "] " + ex); } public void fatalError(SAXParseException ex) throws SAXException { System.out.println("FATAL_ERROR: [at " + ex.getLineNumber() + "] " + ex); } public void warning(SAXParseException ex) throws SAXException { System.out.println("WARNING: [at " + ex.getLineNumber() + "] " + ex); } }
下面的代碼選擇實(shí)現(xiàn) ContentHandler
接口并提供所有必要方法的實(shí)現(xiàn)。
它還實(shí)現(xiàn) ErrorHandler
接口。
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; public class Main { static public void main(String[] arg) throws Exception { String filename = "yourXML.xml"; // Create a new factory that will create the parser. SAXParserFactory spf = SAXParserFactory.newInstance(); // Create the XMLReader to be used to parse the document. SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader(); // Specify the error handler and the content handler. reader.setErrorHandler(new MyErrorHandler()); reader.setContentHandler(new MyContentHandler()); // Use the XMLReader to parse the entire file. InputSource is = new InputSource(filename); reader.parse(is); } } class MyContentHandler implements ContentHandler { private Locator locator; /** * The name and of the SAX document and the current location within the * document. */ public void setDocumentLocator(Locator locator) { this.locator = locator; System.out.println("-" + locator.getLineNumber() + "---Document ID: " + locator.getSystemId()); } /** The parsing of a document has started.. */ public void startDocument() { System.out.println("-" + locator.getLineNumber() + "---Document parse started"); } /** The parsing of a document has completed.. */ public void endDocument() { System.out.println("-" + locator.getLineNumber() + "---Document parse ended"); } /** The start of a namespace scope */ public void startPrefixMapping(String prefix, String uri) { System.out.println("-" + locator.getLineNumber() + "---Namespace scope begins"); System.out.println(" " + prefix + "=\"" + uri + "\""); } /** The end of a namespace scope */ public void endPrefixMapping(String prefix) { System.out.println("-" + locator.getLineNumber() + "---Namespace scope ends"); System.out.println(" " + prefix); } /** The opening tag of an element. */ public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { System.out.println("-" + locator.getLineNumber() + "---Opening tag of an element"); System.out.println(" Namespace: " + namespaceURI); System.out.println(" Local name: " + localName); System.out.println(" Qualified name: " + qName); for (int i = 0; i < atts.getLength(); i++) { System.out.println(" Attribute: " + atts.getQName(i) + "=\"" + atts.getValue(i) + "\""); } } /** The closing tag of an element. */ public void endElement(String namespaceURI, String localName, String qName) { System.out.println("-" + locator.getLineNumber() + "---Closing tag of an element"); System.out.println(" Namespace: " + namespaceURI); System.out.println(" Local name: " + localName); System.out.println(" Qualified name: " + qName); } /** Character data. */ public void characters(char[] ch, int start, int length) { System.out.println("-" + locator.getLineNumber() + "---Character data"); showCharacters(ch, start, length); } /** Ignorable whitespace character data. */ public void ignorableWhitespace(char[] ch, int start, int length) { System.out.println("-" + locator.getLineNumber() + "---Whitespace"); showCharacters(ch, start, length); } /** Processing Instruction */ public void processingInstruction(String target, String data) { System.out.println("-" + locator.getLineNumber() + "---Processing Instruction"); System.out.println(" Target: " + target); System.out.println(" Data: " + data); } /** A skipped entity. */ public void skippedEntity(String name) { System.out.println("-" + locator.getLineNumber() + "---Skipped Entity"); System.out.println(" Name: " + name); } /** * Internal method to format arrays of characters so the special whitespace * characters will show. */ public void showCharacters(char[] ch, int start, int length) { System.out.print(" \""); for (int i = start; i < start + length; i++) switch (ch[i]) { case "\n": System.out.print("\\n"); break; case "\r": System.out.print("\\r"); break; case "\t": System.out.print("\\t"); break; default: System.out.print(ch[i]); break; } System.out.println("\""); } } class MyErrorHandler implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { show("Warning", e); throw (e); } public void error(SAXParseException e) throws SAXException { show("Error", e); throw (e); } public void fatalError(SAXParseException e) throws SAXException { show("Fatal Error", e); throw (e); } private void show(String type, SAXParseException e) { System.out.println(type + ": " + e.getMessage()); System.out.println("Line " + e.getLineNumber() + " Column " + e.getColumnNumber()); System.out.println("System ID: " + e.getSystemId()); } }
以下代碼顯示了如何從DefaultHandler訪問Locator接口。
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class Main{ public static void main(String[] args) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); SAXParser parser = factory.newSAXParser(); parser.parse("sample.xml", new SampleOfXmlLocator()); } } class SampleOfXmlLocator extends DefaultHandler { private Locator locator; public void setDocumentLocator(Locator locator) { this.locator = locator; } public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { if (qName.equals("order")) { System.out.println("here process element start"); } else { String location = ""; if (locator != null) { location = locator.getSystemId(); // XML-document name; location += " line " + locator.getLineNumber(); location += ", column " + locator.getColumnNumber(); location += ": "; } throw new SAXException(location + "Illegal element"); } } }
更多建議: