Java XML API
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 SAX 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 Parserpublic 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");}}}
Java DOM简介
Java XML教程 - Java DOM简介
DOM是标准的树结构,其中每个节点包含来自XML结构的一个组件。
XML文档中两种最常见的节点类型是元素节点和文本节点。
使用Java DOM API,我们可以创建节点,删除节点,更改其内容,并遍历节点层次结构。
何时使用DOM
文档对象模型标准是为XML文档操作而设计的。
DOM的用意是语言无关的。Java的DOM解析器没有利用Java的面向对象的特性优势。
混合内容模型
文本和元素在DOM层次结构中混合。这种结构在DOM模型中称为混合内容。
例如,我们有以下xml结构:
<yourTag>This is an <bold>important</bold> test.</yourTag>
DOM节点的层级如下,其中每行代表一个节点:
ELEMENT: yourTag+ TEXT: This is an+ ELEMENT: bold+ TEXT: important+ TEXT: test.
yourTag
元素包含文本,后跟一个子元素,后跟另外的文本。
节点类型
为了支持混合内容,DOM节点非常简单。标签元素的“内容"标识它是的节点的类型。
例如,<yourTag> 节点内容是元素 yourTag
的名称。
DOM节点API定义 nodeValue()
, nodeType()
和 nodeName()
方法。
对于元素节点< yourTag>
nodeName()返回yourTag,而nodeValue()返回null。
对于文本节点 + TEXT:这是一个
nodeName()返回#text,nodeValue()返回“This is an"。
例子
以下代码显示了如何使用DOM解析器来解析xml文件并获取一个 org.w3c.dom.Document
对象。
import java.io.File;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;public class Main {public static void main(String[] args) throws Exception {DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = null;db = dbf.newDocumentBuilder();Document doc = db.parse(new File("games.xml"));} }
例2
以下代码显示如何执行DOM转储。
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException;public class Main{static public void main(String[] arg) throws Exception{String filename = "input.xml";boolean validate = true;DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setValidating(validate);dbf.setNamespaceAware(true);dbf.setIgnoringElementContentWhitespace(true);DocumentBuilder builder = dbf.newDocumentBuilder();builder.setErrorHandler(new MyErrorHandler());InputSource is = new InputSource(filename);Document doc = builder.parse(is);TreeDumper td = new TreeDumper();td.dump(doc);} } class TreeDumper {public void dump(Document doc) {dumpLoop((Node)doc,"");}private void dumpLoop(Node node,String indent) {switch(node.getNodeType()) {case Node.CDATA_SECTION_NODE:System.out.println(indent + "CDATA_SECTION_NODE");break;case Node.COMMENT_NODE:System.out.println(indent + "COMMENT_NODE");break;case Node.DOCUMENT_FRAGMENT_NODE:System.out.println(indent + "DOCUMENT_FRAGMENT_NODE");break;case Node.DOCUMENT_NODE:System.out.println(indent + "DOCUMENT_NODE");break;case Node.DOCUMENT_TYPE_NODE:System.out.println(indent + "DOCUMENT_TYPE_NODE");break;case Node.ELEMENT_NODE:System.out.println(indent + "ELEMENT_NODE");break;case Node.ENTITY_NODE:System.out.println(indent + "ENTITY_NODE");break;case Node.ENTITY_REFERENCE_NODE:System.out.println(indent + "ENTITY_REFERENCE_NODE");break;case Node.NOTATION_NODE:System.out.println(indent + "NOTATION_NODE");break;case Node.PROCESSING_INSTRUCTION_NODE:System.out.println(indent + "PROCESSING_INSTRUCTION_NODE");break;case Node.TEXT_NODE:System.out.println(indent + "TEXT_NODE");break;default:System.out.println(indent + "Unknown node");break;}NodeList list = node.getChildNodes();for(int i=0; i<list.getLength(); i++)dumpLoop(list.item(i),indent + " ");} } 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());} }
错误处理程序
以下代码显示了如何在使用DOM解析器解析XML时处理错误。
import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException;public class DOMCheck {static public void main(String[] arg) {boolean validate = true;DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setValidating(validate);dbf.setNamespaceAware(true);try {DocumentBuilder builder = dbf.newDocumentBuilder();builder.setErrorHandler(new MyErrorHandler());InputSource is = new InputSource("person.xml");Document doc = builder.parse(is);} catch (SAXException e) {System.out.println(e);} catch (ParserConfigurationException e) {System.err.println(e);} catch (IOException e) {System.err.println(e);}} }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());} }
例3
以下代码显示了如何递归访问DOM树中的所有节点。
import java.io.File;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList;public class Main {public static void main(String[] argv) throws Exception{DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setValidating(true);factory.setExpandEntityReferences(false);Document doc = factory.newDocumentBuilder().parse(new File("file.xml"));visit(doc, 0);}public static void visit(Node node, int level) {NodeList list = node.getChildNodes();for (int i = 0; i < list.getLength(); i++) {Node childNode = list.item(i);visit(childNode, level + 1);}} }
例4
下面的代码显示了如何将XML片段转换为DOM片段。
import java.io.File; import java.io.StringReader;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.InputSource;public class Main {public static void main(String[] argv) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setValidating(true);Document doc = factory.newDocumentBuilder().parse(new File("infilename.xml"));String fragment = "<fragment>aaa</fragment>";factory = DocumentBuilderFactory.newInstance();Document d = factory.newDocumentBuilder().parse(new InputSource(new StringReader(fragment)));Node node = doc.importNode(d.getDocumentElement(), true);DocumentFragment docfrag = doc.createDocumentFragment();while (node.hasChildNodes()) {docfrag.appendChild(node.removeChild(node.getFirstChild()));}Element element = doc.getDocumentElement();element.appendChild(docfrag);}}
例5
下面的代码显示了如何解析XML字符串:使用DOM和StringReader。
import java.io.StringReader;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource;public class Main {public static void main(String arg[]) throws Exception{String xmlRecords = "<data><employee><name>A</name>"+ "<title>Manager</title></employee></data>";DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();InputSource is = new InputSource();is.setCharacterStream(new StringReader(xmlRecords));Document doc = db.parse(is);NodeList nodes = doc.getElementsByTagName("employee");for (int i = 0; i < nodes.getLength(); i++) {Element element = (Element) nodes.item(i);NodeList name = element.getElementsByTagName("name");Element line = (Element) name.item(0);System.out.println("Name: " + getCharacterDataFromElement(line));NodeList title = element.getElementsByTagName("title");line = (Element) title.item(0);System.out.println("Title: " + getCharacterDataFromElement(line));}}public static String getCharacterDataFromElement(Element e) {Node child = e.getFirstChild();if (child instanceof CharacterData) {CharacterData cd = (CharacterData) child;return cd.getData();}return "";} }
上面的代码生成以下结果。
Java DOM编辑
Java XML教程 - Java DOM编辑
属性
以下代码显示如何向元素添加属性。
import java.io.StringWriter;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult;import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element;public class Main {public static void main(String[] argv) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();DOMImplementation impl = builder.getDOMImplementation();Document doc = impl.createDocument(null, null, null);Element e1 = doc.createElement("api");doc.appendChild(e1);Element e2 = doc.createElement("java");e1.appendChild(e2);e2.setAttribute("url", "http://www.www.w3cschool.cn");//transform the DOM for showing the result in consoleDOMSource domSource = new DOMSource(doc);Transformer transformer = TransformerFactory.newInstance().newTransformer();transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");transformer.setOutputProperty(OutputKeys.METHOD, "xml");transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");transformer.setOutputProperty(OutputKeys.INDENT, "yes");StringWriter sw = new StringWriter();StreamResult sr = new StreamResult(sw);transformer.transform(domSource, sr);System.out.println(sw.toString());} }
上面的代码生成以下结果。
复制属性
public void dupAttributes(Document doc) {Element root = doc.getDocumentElement();Element personOne = (Element)root.getFirstChild();Element personTwo = (Element)personOne.getNextSibling();Element personThree = (Element)personTwo.getNextSibling();Attr deptAttr = personOne.getAttributeNode("dept");personOne.removeAttributeNode(deptAttr);String deptString = deptAttr.getValue();personTwo.setAttribute("dept",deptString);personThree.setAttribute("dept",deptString);String mailString = personOne.getAttribute("mail");personTwo.setAttribute("mail",mailString);String titleString = personOne.getAttribute("title");personOne.removeAttribute("title");personThree.setAttribute("title",titleString);}
删除两个属性
public void delAttribute(Document doc) {Element root = doc.getDocumentElement();Element person = (Element)root.getFirstChild();person.removeAttribute("extension");person.removeAttribute("dept");}
元素
import java.io.StringWriter;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult;import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Node;public class Main {public static void main(String[] argv) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();DOMImplementation impl = builder.getDOMImplementation();Document doc = impl.createDocument(null, null, null);Node root = doc.createElement("A");doc.appendChild(root);Node stanza = doc.createElement("B");root.appendChild(stanza);Node line = doc.createElement("C");stanza.appendChild(line);line.appendChild(doc.createTextNode("test"));line = doc.createElement("Line");stanza.appendChild(line);line.appendChild(doc.createTextNode("test"));//transform the DOM for showing the result in consoleDOMSource domSource = new DOMSource(doc);Transformer transformer = TransformerFactory.newInstance().newTransformer();transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");transformer.setOutputProperty(OutputKeys.METHOD, "xml");transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");transformer.setOutputProperty(OutputKeys.INDENT, "yes");StringWriter sw = new StringWriter();StreamResult sr = new StreamResult(sw);transformer.transform(domSource, sr);System.out.println(sw.toString());} }
上面的代码生成以下结果。
以下代码显示如何从父代删除元素。
public void deleteFirstElement(Document doc) {Element root = doc.getDocumentElement();Element child = (Element)root.getFirstChild();root.removeChild(child);}
文本节点
以下代码显示如何向元素添加文本节点。
import java.io.StringWriter;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSOutput; import org.w3c.dom.ls.LSSerializer;public class Main {public static void main(String[] argv) throws Exception {DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();dbf.setNamespaceAware(true);DocumentBuilder db = dbf.newDocumentBuilder();Document doc = db.newDocument();Element root = doc.createElementNS(null, "person"); // Create Root ElementElement item = doc.createElementNS(null, "name"); // Create elementitem.appendChild(doc.createTextNode("Jeff"));root.appendChild(item); // Attach element to Root elementitem = doc.createElementNS(null, "age"); // Create another Elementitem.appendChild(doc.createTextNode("28"));root.appendChild(item); // Attach Element to previous element down treeitem = doc.createElementNS(null, "height");item.appendChild(doc.createTextNode("1.80"));root.appendChild(item); // Attach another Element - grandaugtherdoc.appendChild(root); // Add Root to DocumentDOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();DOMImplementationLS domImplLS = (DOMImplementationLS) registry.getDOMImplementation("LS");LSSerializer ser = domImplLS.createLSSerializer(); // Create a serializer// for the DOMLSOutput out = domImplLS.createLSOutput();StringWriter stringOut = new StringWriter(); // Writer will be a Stringout.setCharacterStream(stringOut);ser.write(doc, out); // Serialize the DOMSystem.out.println("STRXML = " + stringOut.toString()); // DOM as a String} }
上面的代码生成以下结果。
以下代码显示了如何通过插入和替换编辑文本。
public void edit3(Document doc) {int count;int offset;Element root = doc.getDocumentElement();Element place = (Element)root.getFirstChild();Text name = (Text)place.getFirstChild().getFirstChild();Text directions = (Text)place.getLastChild().getFirstChild();offset = 7;name.insertData(offset," black");offset = 5;count = 4;directions.replaceData(offset,count,"right");}
通过剪切和粘贴修改文本
public void edit(Document doc) {int length;int count;int offset;Element root = doc.getDocumentElement();Element place = (Element)root.getFirstChild();Text name = (Text)place.getFirstChild().getFirstChild();Text directions = (Text)place.getLastChild().getFirstChild();length = name.getLength();count = 4;offset = length - 4;name.deleteData(offset,count);length = directions.getLength();count = 6;offset = length - count;String bridge = directions.substringData(offset,count);name.appendData(bridge);count = 5;offset = 4;directions.deleteData(offset,count);}
通过替换修改文本
public void edit(Document doc) {Element root = doc.getDocumentElement();Element place = (Element)root.getFirstChild();Text name = (Text)place.getFirstChild().getFirstChild();Text directions = (Text)place.getLastChild().getFirstChild();name.setData("AAA");directions.setData("BBB");}
注释
以下代码显示如何为XML创建注释节点。
import java.io.File;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element;public class Main {public static void main(String[] argv) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();factory.setValidating(true);factory.setExpandEntityReferences(false);Document doc = factory.newDocumentBuilder().parse(new File("filename"));Element element = doc.getDocumentElement();Comment comment = doc.createComment("A Document Comment");element.getParentNode().insertBefore(comment, element);} }
处理指令
下面的代码显示了如何添加ProcessingInstruction。
public void addProcessingInstruction(Document doc) {Element root = doc.getDocumentElement();Element folks = (Element)root.getLastChild();ProcessingInstruction pi;pi = (ProcessingInstruction)doc.createProcessingInstruction("validate","phone=\"lookup\"");root.insertBefore(pi,folks);}
CDATA
以下代码显示如何添加CDATA到XML文档。
public void addCDATA(Document doc) {Element root = doc.getDocumentElement();Element place = (Element)root.getFirstChild();Element directions = (Element)place.getLastChild();String dirtext =">>>\n" +"<<<\n" +"&&&\n" +"<><><>.";CDATASection dirdata = doc.createCDATASection(dirtext);directions.replaceChild(dirdata,directions.getFirstChild());}
克隆
public void duplicatePerson(Document doc) {Element root = doc.getDocumentElement();Element origPerson = (Element)root.getFirstChild();Element newPerson = (Element)origPerson.cloneNode(true);root.appendChild(newPerson);}
Java XSLT
Java XML教程 - Java XSLT
可扩展样式表语言转换(XSLT)标准定义类,用于使用XPath寻址XML数据和进行转换数据以其他形式。
JAXP包括XSLT的解释实现。
XSL,XSLT和XPath
可扩展样式表语言(XSL)有三个主要子组件:
组件 | 描述 |
---|---|
XSL-FO | 格式化对象标准。 我们可以定义字体大小,页面布局和对象呈现的其他方面。 |
XSLT | 它定义了从XML到其他格式的转换。例如,使用XSLT从XML文档生成HTML。 |
XPath | XPath是一种规范语言,我们可以用它来创建一个元素的路径。 |
JAXP转换包
以下是对JAXP Transformation API的包的描述:
包 | 描述 |
---|---|
javax.xml.transform | 这个包定义了返回Transformer对象的工厂类。 我们可以使用输入和输出对象配置Transformer,并调用其transform()方法来执行转换。 |
javax.xml.transform.dom | 定义DOMSource和DOMResult类,用于将DOM用作转换中的输入或输出。 |
javax.xml.transform.sax | 定义SAXSource和SAXResult类,用于在转换中使用SAX作为输入或输出。 |
javax.xml.transform.stream | 定义StreamSource和StreamResult类,以将I/O流用作转换的输入或输出。 |
XPath表达式指定用于选择一组XML节点的模式。
XSLT模板可以使用这些模式来选择节点并应用转换。
使用XPath表达式,我们可以引用元素的文本和属性。XPath规范定义了七种类型的节点:
- 根
- 元素
- 文本
- 属性
- 注释
- 处理指令
- 命名空间
XPath寻址
XML文档是树结构的节点集合。
XPath使用路径符号在XML中寻址节点。
-
正斜杠/是路径分隔符。
- 文档根目录的绝对路径以/开头。
- 相对路径可以从任何其他开始。
- 双重周期
..
表示父节点。 - 单个期间
.
表示当前节点。
在XPath /h1/h2
中选择位于h1元素下的所有h2元素。
要选择一个特定的h2元素,我们使用方括号 []
来索引。
例如, /h1[4]/h2 [5]
将选择第五个 h2
在第四个 h1
元素下。
要引用属性,请在属性名称前加上@符号。例如, @type
是指 type
属性。
h1/@type
选择 h1
元素的 type
属性。
XPath表达式
XPath表达式可以使用通配符,运算符及其自身的函数。
表达式 @type="unordered"
指定一个属性名为 type
,其值为无序
。
表达式 h1[@ type="unordered"]
选择所有 h1
元素其 type
属性值是无序的。
例子
假设我们将电话数据存储在以下XML文档中。
<PHONEBOOK> <PERSON><NAME>Joe Wang</NAME><EMAIL>joe@yourserver.com</EMAIL><TELEPHONE>202-999-9999</TELEPHONE><WEB>www.w3cschool.cn</WEB> </PERSON> <PERSON><NAME>Karol</name><EMAIL>karol@yourserver.com</EMAIL><TELEPHONE>306-999-9999</TELEPHONE><WEB>www.w3cschool.cn</WEB> </PERSON> <PERSON><NAME>Green</NAME><EMAIL>green@yourserver.com</EMAIL><TELEPHONE>202-414-9999</TELEPHONE><WEB>www.w3cschool.cn</WEB> </PERSON> </PHONEBOOK>
我们将使用以下XSLT将上述XML转换为HTML文件。
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"><html> <head> <title>Directory</title> </head> <body><table border="1"><tr><th>Name</th><th>Telephone</th><th>Email</th> </tr><xsl:for-each select="PHONEBOOK/PERSON"><xsl:sort/><tr><td><xsl:value-of select="NAME"/></td><td><xsl:value-of select="TELEPHONE"/></td><td><xsl:value-of select="EMAIL"/></td></tr> </xsl:for-each></table> </body> </html> </xsl:template> </xsl:stylesheet>
从上面的代码,我们可以看到数据将被转换为HTML表。
我们使用下面的代码来做转换。
import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource;public class Main {public static void main(String args[]) throws Exception {StreamSource source = new StreamSource(args[0]);StreamSource stylesource = new StreamSource(args[1]);TransformerFactory factory = TransformerFactory.newInstance();Transformer transformer = factory.newTransformer(stylesource);StreamResult result = new StreamResult(System.out);transformer.transform(source, result);} }
例2
以下代码显示了如何使用Stax解析器转换xml。
import java.io.File; import java.io.FileInputStream; import java.io.FileWriter;import javax.xml.XMLConstants; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator;public class Main {public static void main(String[] args) throws Exception {SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);System.out.println("schema factory instance obtained is " + sf);Schema schema = sf.newSchema(new File(args[0]));System.out.println("schema obtained is = " + schema);Validator validator = schema.newValidator();String fileName = args[1].toString();String fileName2 = args[2].toString();javax.xml.transform.Result xmlResult = new javax.xml.transform.stax.StAXResult(XMLOutputFactory.newInstance().createXMLStreamWriter(new FileWriter(fileName2)));javax.xml.transform.Source xmlSource = new javax.xml.transform.stax.StAXSource(getXMLEventReader(fileName));validator.validate(new StreamSource(args[1]));validator.validate(xmlSource, xmlResult);}private static XMLEventReader getXMLEventReader(String filename)throws Exception {XMLInputFactory xmlif = null;XMLEventReader xmlr = null;xmlif = XMLInputFactory.newInstance();xmlif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,Boolean.TRUE);xmlif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,Boolean.FALSE);xmlif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);xmlif.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);FileInputStream fis = new FileInputStream(filename);xmlr = xmlif.createXMLEventReader(filename, fis);return xmlr;}}
例3
以下代码使用 DOMSource
作为变换输入。
import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader;import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult;import org.w3c.dom.Document; import org.xml.sax.InputSource;public class Main {public static void main(String[] argv) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(new InputSource(new InputStreamReader(new FileInputStream("inputFile.xml"))));Transformer xformer = TransformerFactory.newInstance().newTransformer();xformer.setOutputProperty(OutputKeys.METHOD, "xml");xformer.setOutputProperty(OutputKeys.INDENT, "yes");xformer.setOutputProperty("http://xml.apache.org/xslt;indent-amount", "4");xformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");Source source = new DOMSource(document);Result result = new StreamResult(new File("result.xml"));xformer.transform(source, result);} }
例4
以下代码显示了如何使用XPath更改特定元素。
import java.io.File;import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory;import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource;public class Main {public static void main(String[] args) throws Exception {Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource("data.xml"));XPath xpath = XPathFactory.newInstance().newXPath();NodeList nodes = (NodeList) xpath.evaluate("//employee/name[text()="old"]", doc,XPathConstants.NODESET);for (int idx = 0; idx < nodes.getLength(); idx++) {nodes.item(idx).setTextContent("new value");}Transformer xformer = TransformerFactory.newInstance().newTransformer();xformer.transform(new DOMSource(doc), new StreamResult(new File("data_new.xml")));} }
Java StAX
Java XML教程 - Java StAX
StAX是为了解决SAX和DOM API中的限制而创建的。
StAX API允许我们请求下一个事件(拉动事件),并允许状态以过程方式存储。
XML解析有两种编程模型:流和文档对象模型(DOM)。
DOM模型涉及创建表示整个文档树的内存对象。DOM树可以自由导航。 成本是一个大的内存占用。这对于小文档来说是可以的,但是当文档变得更大时,内存消耗可能会迅速上升。
流是指其中XML数据被串行解析的编程模型。在文档中,我们只能在一个位置查看XML数据。这意味着我们需要在读取XML文档之前知道XML结构。用于XML处理的流模型在存在内存限制时很有用。
拉式解析vs推式解析
当我们想获取(拉取)XML数据时,我们做流式拉解析。
当解析器发送数据时,无论客户端是否准备好使用它,我们都进行流式推送解析。
StAX拉解析器可以过滤XML文档并忽略元素不必要。
StAX是一个双向API,通过它我们可以读取和写入XML文档。 SAX是只读的。
SAX是一个推送API,而StAX是拉式。
例子
此程序演示如何使用StAX解析器。它打印XHTML网页的所有超链接链接。
import java.io.InputStream; import java.net.URL;import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader;public class Main {public static void main(String[] args) throws Exception {URL url = new URL("http://www.w3c.org");InputStream in = url.openStream();XMLInputFactory factory = XMLInputFactory.newInstance();XMLStreamReader parser = factory.createXMLStreamReader(in);while (parser.hasNext()) {int event = parser.next();if (event == XMLStreamConstants.START_ELEMENT) {if (parser.getLocalName().equals("a")) {String href = parser.getAttributeValue(null, "href");if (href != null)System.out.println(href);}}}} }
例2
下面的代码显示了如何使用XML流读取器加载XML文档。
import java.io.File; import java.io.FileInputStream;import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader;public class Main {public static void main(String[] args) throws Exception {File file = new File("yourXML.xml");FileInputStream inputStream = new FileInputStream(file);XMLInputFactory inputFactory = XMLInputFactory.newInstance();XMLStreamReader reader = inputFactory.createXMLStreamReader(inputStream);System.out.println(reader.getVersion());System.out.println(reader.isStandalone());System.out.println(reader.standaloneSet());System.out.println(reader.getEncoding());System.out.println(reader.getCharacterEncodingScheme());parseRestOfDocument(reader);}private static void parseRestOfDocument(XMLStreamReader reader)throws XMLStreamException {while (reader.hasNext()) {int type = reader.next();switch (type) {case XMLStreamConstants.START_ELEMENT:System.out.println(reader.getLocalName());if (reader.getNamespaceURI() != null) {String prefix = reader.getPrefix();if (prefix == null) {prefix = "[None]";}System.out.println("prefix = "" + prefix + "", URI = ""+ reader.getNamespaceURI() + """);}if (reader.getAttributeCount() > 0) {for (int i = 0; i < reader.getAttributeCount(); i++) {System.out.println("Attribute (name = ""+ reader.getAttributeLocalName(i) + "", value = ""+ reader.getAttributeValue(i) + "")");String attURI = reader.getAttributeNamespace(i);if (attURI != null) {String attPrefix = reader.getAttributePrefix(i);if (attPrefix == null || attPrefix.equals("")) {attPrefix = "[None]";}System.out.println("prefix=" + attPrefix + ",URI=" + attURI);}}}break;case XMLStreamConstants.END_ELEMENT:System.out.println("XMLStreamConstants.END_ELEMENT");break;case XMLStreamConstants.CHARACTERS:if (!reader.isWhiteSpace()) {System.out.println("CD:" + reader.getText());}break;case XMLStreamConstants.DTD:System.out.println("DTD:" + reader.getText());break;case XMLStreamConstants.SPACE:System.out.println(" ");break;case XMLStreamConstants.COMMENT:System.out.println(reader.getText());break;default:System.out.println(type);}}} }
XMLStreamWriter
以下代码显示了如何使用 XMLStreamWriter
输出xml。
import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter;public class Main {public static void main(String[] args) throws Exception {XMLOutputFactory factory = XMLOutputFactory.newInstance();XMLStreamWriter writer = factory.createXMLStreamWriter(System.out);writer.writeStartDocument("1.0");writer.writeStartElement("catalog");writer.writeStartElement("book");writer.writeAttribute("id", "1");writer.writeStartElement("code");writer.writeCharacters("I01");writer.writeEndElement();writer.writeStartElement("title");writer.writeCharacters("This is the title");writer.writeEndElement();writer.writeStartElement("price");writer.writeCharacters("$2.95");writer.writeEndElement();writer.writeEndDocument();writer.flush();writer.close();} }
上面的代码生成以下结果。
XMLEventReader
import java.io.FileReader; import java.io.Reader; import java.util.Iterator;import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent;public class Main {public static void main(String[] args) throws Exception {XMLInputFactory factory = XMLInputFactory.newInstance();Reader fileReader = new FileReader("Source.xml");XMLEventReader reader = factory.createXMLEventReader(fileReader);while (reader.hasNext()) {XMLEvent event = reader.nextEvent();if (event.isStartElement()) {StartElement element = (StartElement) event;System.out.println("Start Element: " + element.getName());Iterator iterator = element.getAttributes();while (iterator.hasNext()) {Attribute attribute = (Attribute) iterator.next();QName name = attribute.getName();String value = attribute.getValue();System.out.println("Attribute name/value: " + name + "/" + value);}}if (event.isEndElement()) {EndElement element = (EndElement) event;System.out.println("End element:" + element.getName());}if (event.isCharacters()) {Characters characters = (Characters) event;System.out.println("Text: " + characters.getData());}}} }
XMLEventWriter
import java.util.Arrays; import java.util.List;import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.EndDocument; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartDocument; import javax.xml.stream.events.StartElement;public class Main {public static void main(String[] args) throws Exception {XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();XMLEventWriter writer = outputFactory.createXMLEventWriter(System.out);XMLEventFactory xmlEventFactory = XMLEventFactory.newInstance();StartDocument startDocument = xmlEventFactory.createStartDocument("UTF-8", "1.0");writer.add(startDocument);StartElement startElement = xmlEventFactory.createStartElement("", "", "My-list");writer.add(startElement);Attribute attribute = xmlEventFactory.createAttribute("version", "1");List attributeList = Arrays.asList(attribute);List nsList = Arrays.asList();StartElement startElement2 = xmlEventFactory.createStartElement("", "", "Item",attributeList.iterator(), nsList.iterator());writer.add(startElement2);StartElement codeSE = xmlEventFactory.createStartElement("", "", "code");writer.add(codeSE);Characters codeChars = xmlEventFactory.createCharacters("I001");writer.add(codeChars);EndElement codeEE = xmlEventFactory.createEndElement("", "", "code");writer.add(codeEE);StartElement nameSE = xmlEventFactory.createStartElement(" ", " ", "name");writer.add(nameSE);Characters nameChars = xmlEventFactory.createCharacters("a name");writer.add(nameChars);EndElement nameEE = xmlEventFactory.createEndElement("", "", "name");writer.add(nameEE);StartElement contactSE = xmlEventFactory.createStartElement("", "", "contact");writer.add(contactSE);Characters contactChars = xmlEventFactory.createCharacters("another name");writer.add(contactChars);EndElement contactEE = xmlEventFactory.createEndElement("", "", "contact");writer.add(contactEE);EndDocument ed = xmlEventFactory.createEndDocument();writer.add(ed);writer.flush();writer.close();} }
上面的代码生成以下结果。
StreamFilter
import java.io.FileInputStream;import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.events.XMLEvent;public class Main implements javax.xml.stream.StreamFilter {public static void main(String[] args) throws Exception {String filename = "yourXML.xml";XMLInputFactory xmlif = null;xmlif = XMLInputFactory.newInstance();xmlif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,Boolean.TRUE);xmlif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,Boolean.FALSE);xmlif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);xmlif.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);System.out.println("FACTORY: " + xmlif);System.out.println("filename = " + filename);FileInputStream fis = new FileInputStream(filename);XMLStreamReader xmlr = xmlif.createFilteredReader(xmlif.createXMLStreamReader(fis), new Main());int eventType = xmlr.getEventType();printEventType(eventType);while (xmlr.hasNext()) {eventType = xmlr.next();printEventType(eventType);printName(xmlr, eventType);printText(xmlr);if (xmlr.isStartElement()) {printAttributes(xmlr);}printPIData(xmlr);}}public static final String getEventTypeString(int eventType) {switch (eventType) {case XMLEvent.START_ELEMENT:return "START_ELEMENT";case XMLEvent.END_ELEMENT:return "END_ELEMENT";case XMLEvent.PROCESSING_INSTRUCTION:return "PROCESSING_INSTRUCTION";case XMLEvent.CHARACTERS:return "CHARACTERS";case XMLEvent.COMMENT:return "COMMENT";case XMLEvent.START_DOCUMENT:return "START_DOCUMENT";case XMLEvent.END_DOCUMENT:return "END_DOCUMENT";case XMLEvent.ENTITY_REFERENCE:return "ENTITY_REFERENCE";case XMLEvent.ATTRIBUTE:return "ATTRIBUTE";case XMLEvent.DTD:return "DTD";case XMLEvent.CDATA:return "CDATA";}return "UNKNOWN_EVENT_TYPE";}private static void printEventType(int eventType) {System.out.print("EVENT TYPE(" + eventType + "):");System.out.println(getEventTypeString(eventType));}private static void printName(XMLStreamReader xmlr, int eventType) {if (xmlr.hasName()) {System.out.println("HAS NAME: " + xmlr.getLocalName());} else {System.out.println("HAS NO NAME");}}private static void printText(XMLStreamReader xmlr) {if (xmlr.hasText()) {System.out.println("HAS TEXT: " + xmlr.getText());} else {System.out.println("HAS NO TEXT");}}private static void printPIData(XMLStreamReader xmlr) {if (xmlr.getEventType() == XMLEvent.PROCESSING_INSTRUCTION) {System.out.println(" PI target = " + xmlr.getPITarget());System.out.println(" PI Data = " + xmlr.getPIData());}}private static void printAttributes(XMLStreamReader xmlr) {if (xmlr.getAttributeCount() > 0) {System.out.println("\nHAS ATTRIBUTES: ");int count = xmlr.getAttributeCount();for (int i = 0; i < count; i++) {QName name = xmlr.getAttributeName(i);String namespace = xmlr.getAttributeNamespace(i);String type = xmlr.getAttributeType(i);String prefix = xmlr.getAttributePrefix(i);String value = xmlr.getAttributeValue(i);System.out.println("ATTRIBUTE-PREFIX: " + prefix);System.out.println("ATTRIBUTE-NAMESP: " + namespace);System.out.println("ATTRIBUTE-NAME: " + name.toString());System.out.println("ATTRIBUTE-VALUE: " + value);System.out.println("ATTRIBUTE-TYPE: " + type);}} else {System.out.println("HAS NO ATTRIBUTES");}}public boolean accept(XMLStreamReader reader) {if (!reader.isStartElement() && !reader.isEndElement()) {return false;} else {return true;}} }