Java XML教程 - Java XML API
SAX API
下面是关键的SAX API的摘要:
类 | 用法 |
---|---|
SAXParserFactory | 创建由系统属性javax.xml.parsers.SAXParserFactory确定的解析器的实例。 |
SAXParser | SAXParser接口定义了几个重载的parse()方法。 |
SAXReader | SAXParser包装一个SAXReader,并从SAXParser的getXMLReader()方法返回。 |
DefaultHandler | DefaultHandler实现了ContentHandler,ErrorHandler,DTDHandler,和EntityResolver接口。 通过使用DefaultHandler,我们可以只覆盖我们需要的那些。 |
ContentHandler | 此接口定义回调方法,如startDocument,endDocument,startElement和endElement。 这些方法在识别XML标记时调用。它还定义了被调用的方法characters()当解析器遇到XML元素中的文本时。它定义被调用的processingInstruction()当解析器遇到内联处理指令时。 |
ErrorHandler | 它使用error(),fatalError()和warning()方法来响应各种解析错误。 默认的错误处理程序只会抛出致命错误和的异常忽略验证错误。 |
DTDHandler | 用于处理DTD |
EntityResolver | 它的resolveEntity()方法用于标识数据。 |
我们通常实现大多数 ContentHandler
方法。
为了提供更稳健的实现,我们可以从ErrorHandler
实现方法。
SAX包
SAX解析器在下表中列出的软件包中定义。
包 | 描述 |
---|---|
org.xml.sax | 定义SAX接口。 |
org.xml.sax.ext | 定义用于更高级SAX处理的SAX扩展。 |
org.xml.sax.helpers | 定义SAX API的辅助类。 |
javax.xml.parsers | 定义SAXParserFactory类,它返回SAXParser。 |
DOM API
javax.xml.parsers.DocumentBuilderFactory
类返回一个 DocumentBuilder
实例。
我们使用 DocumentBuilder
实例来产生一个 Document
对象退出XML文档。
构建器由系统属性 javax.xml.parsers.DocumentBuilderFactory
确定。
DocumentBuilder 中的 newDocument()
方法可以创建一个实现 org.w3c.dom.Document
接口的空Document。
我们可以使用其中一个构建器的解析方法来创建一个 Document
从现有的XML文档。
DOM包
文档对象模型实现在中定义下表中列出的软件包。
包 | 描述 |
---|---|
org.w3c.dom | 定义XML文档的DOM编程接口。 |
javax.xml.parsers | 定义DocumentBuilderFactory类和DocumentBuilder类。 |
XSLT API
TransformerFactory
创建一个 Transformer
对象。
XSLT API在下表中显示的包中定义。
包 | 描述 |
---|---|
javax.xml.transform | 定义TransformerFactory和Transformer类。 我们可以从变换器对象调用transform()方法来进行变换。 |
javax.xml.transform.dom | 用于从DOM创建输入和输出对象的类。 |
javax.xml.transform.sax | 用于从SAX解析器创建输入对象和从SAX事件处理程序输出对象的类。 |
javax.xml.transform.stream | 用于从I / O流创建输入对象和输出对象的类。 |
StAX APIs
StAX为开发人员提供了SAX和DOM解析器的替代方法。
StAX可以用更少的内存进行高性能流过滤,处理和修改。
StAX是用于流式XML处理的标准的双向拉解析器接口。
StAX提供比SAX更简单的编程模型,并且比DOM更高的内存效率。
StAX可以解析和修改XML流作为事件。
StAX包
StAX APIs在下表中显示的包中定义。
包 | 描述 |
---|---|
javax.xml.stream | 定义迭代XML文档元素的XMLStreamReader接口。 定义XMLStreamWriter接口,指定如何写入XML。 |
javax.xml.transform.stax | 提供StAX特定的转换API。 |
Java XML教程 - Java SAX API简介
Java SAX XML解析器代表Simple API for XML(SAX)解析器。
SAX是一种用于访问XML文档的事件驱动的串行访问机制。
此机制经常用于传输和接收XML文档。
SAX是一种状态独立处理,其中元素的处理不依赖于其他元素。StAX是状态相关处理。
SAX是一个事件驱动模型。 当使用SAX解析器时,我们提供了回调方法,并且解析器在读取XML数据时调用它们。
在SAX中,我们不能回到文档的早期部分,我们只能处理元素逐个元素,从开始到结束。
何时使用SAX
SAX是快速和高效的,并且它对于状态无关的过滤是有用的。当遇到元素标记和时,SAX解析器调用一个方法当发现文本时调用不同的方法。
SAX比DOM要求更少的内存,因为SAX不像DOM那样创建XML数据的内部树结构。
使用SAX解析XML文件
在下面我们将看到一个输出所有SAX事件的演示应用程序。它是从包中扩展 DefaultHandler
org.xml.sax.helpers
如下。
public class Main extends DefaultHandler {
以下代码设置了解析器并启动它:
SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); parser = spf.newSAXParser(); parser.parse(file, this);
这些代码行创建一个SAXParserFactory实例,由 javax.xml.parsers.SAXParserFactory
系统属性的设置决定。
工厂被设置为支持XML命名空间将 setNamespaceAware
设置为 true
然后通过 newSAXParser()
方法从工厂获取SAXParser实例。
然后它处理开始文档和结束文档事件:
public void startDocument() { System.out.println("Start document: "); } public void endDocument() { System.out.println("End document: "); }
之后,它使用 System.out.println
打印消息一旦方法是由解析器调用。
遇到开始标记或结束标记时,根据需要,将标记的名称作为String传递到 startElement
或 endElement
方法。
当遇到开始标记时,它定义的任何属性都会在 Attributes
列表中传递。
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 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)); } }
上面的代码生成以下结果。
错误处理程序
解析器可以生成三种错误:
- 致命错误
- 错误
- 警告
当发生致命错误时,解析器无法继续。
对于非致命错误和警告,默认错误处理程序不会生成异常,也不会显示任何消息。
下面的行安装我们自己的错误处理程序。
reader.setErrorHandler(new MyErrorHandler());
MyErrorHandler
类实现标准 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); } }
XML模式验证
我们可以在使用SAXParser解析期间打开XML模式验证。
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(...); } }
DefaultHandler
以下代码显示了当使用DefaultHandler时我们不需要实现所有的方法,我们只需要提供实现我们关心的方法。
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中的错误处理程序方法来处理SAX错误
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); } }
ContentHandler
下面的代码选择实现 ContentHandler
接口并提供所有必要方法的实现。
它还实现 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"); } } }