Java Tutorial/XML/SAX
Содержание
- 1 Accessing features of the SAX parser implementation
- 2 A Class to Convert SAX Parse Information into an XML Document
- 3 A Content Handler to Output a Sorted List
- 4 A Program to Display the Input from a SAX Parser: subclass ContentHandler
- 5 Calling a .NET Web Service
- 6 Configuring SAX parser factory to produce alternate parser
- 7 Generating SAX Parsing Events by Traversing a DOM Document
- 8 Handling SAX errors during parsing
- 9 Intercepting All Accesses to External Entities During XML SAX Parsing
- 10 Parsing XML with a simple SAX document handler
- 11 Produce a SAX stream from a DOM Document
- 12 SAX Error Checking: A Simple Implementation of the ErrorHandler Interface
- 13 SAX parer with all its action displayed
- 14 Sax to DOM converter
- 15 The XMLReader interface
- 16 Using XML locator to indicate current parser position
Accessing features of the SAX parser implementation
<source lang="java">
import javax.xml.parsers.SAXParserFactory; public class Main {
public static void main(String[] argv) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); String features[] = { "http://xml.org/sax/features/namespaces", "http://xml.org/sax/features/namespace-prefixes", "http://xml.org/sax/features/string-interning", "http://xml.org/sax/features/validation", "http://xml.org/sax/features/external-general-entities", "http://xml.org/sax/features/external-parameter-entities", "http://xml.org/sax/features/lexical-handler/parameter-entities", }; for (int i = 0; i < features.length; i++) { System.out.print("\t- "" + features[i] + "" is "); System.out.println(""" + factory.getFeature(features[i]) + """); } }
}</source>
A Class to Convert SAX Parse Information into an XML Document
<source lang="java">
import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import javax.xml.parsers.ParserConfigurationException; 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 SAXCopy {
static public void main(String[] arg) { try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setErrorHandler(new MyErrorHandler()); MyCopyHandler duper = new MyCopyHandler(); reader.setContentHandler(duper); InputSource is = new InputSource("test.xml"); reader.parse(is); } catch (SAXException e) { System.exit(1); } catch (ParserConfigurationException e) { System.err.println(e); System.exit(1); } catch (IOException e) { System.err.println(e); System.exit(1); } }
} 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()); }
} class MyCopyHandler implements ContentHandler {
private boolean namespaceBegin = false; private String currentNamespace; private String currentNamespaceUri; private Locator locator; public MyCopyHandler() { } public void setDocumentLocator(Locator locator) { this.locator = locator; } public void startDocument() { System.out.println("<?xml version=\"1.0\"?>"); System.out.println(); } public void endDocument() { } public void startPrefixMapping(String prefix, String uri) { namespaceBegin = true; currentNamespace = prefix; currentNamespaceUri = uri; } public void endPrefixMapping(String prefix) { } public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { System.out.println("<" + qName); if (namespaceBegin) { System.out.print(" xmlns:" + currentNamespace + "=\"" + currentNamespaceUri + "\""); namespaceBegin = false; } for (int i = 0; i < atts.getLength(); i++) { System.out.print(" " + atts.getQName(i) + "=\\" + atts.getValue(i) + "\""); } System.out.print(">"); } public void endElement(String namespaceURI, String localName, String qName) { System.out.print("</" + qName + ">"); } public void characters(char[] ch, int start, int length) { for (int i = start; i < start + length; i++) System.out.print(ch[i]); } public void ignorableWhitespace(char[] ch, int start, int length) { for (int i = start; i < start + length; i++) System.out.print(ch[i]); } public void processingInstruction(String target, String data) { System.out.print("<?" + target + " " + data + "?>"); } public void skippedEntity(String name) { System.out.print("&" + name + ";"); }
}</source>
<?xml version="1.0"?> <roots > <a > <b >text </a> </roots>
A Content Handler to Output a Sorted List
<source lang="java">
/* Code revised from Java, XML, and JAXP by Arthur Griffith John Wiley & Sons 2002
- /
import java.io.IOException; import java.io.PrintWriter; import java.util.Vector; import javax.xml.parsers.ParserConfigurationException; 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 MappingContentHandler {
static public void main(String[] arg) { try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setErrorHandler(new MyErrorHandler()); MyTextHandler duper = new MyTextHandler(); reader.setContentHandler(duper); InputSource is = new InputSource("person.xml"); reader.parse(is); } catch (SAXException e) { System.out.println(e); } catch (ParserConfigurationException e) { System.err.println(e); System.exit(1); } catch (IOException e) { System.err.println(e); System.exit(1); } }
} 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()); }
} class MyTextHandler implements ContentHandler {
private boolean insideNameElement = false; private boolean insidePhoneElement = false; private boolean insideEmailElement = false; private Person person; private Vector<Person> personVec; public MyTextHandler() { personVec = new Vector<Person>(); } public void setDocumentLocator(Locator locator) { } public void startDocument() { } public void endDocument() { for(int i=0; i<personVec.size(); i++) { Person p = (Person)personVec.elementAt(i); System.out.println(p.getName()+" "+p.getPhone()+" "+p.getEmail()); } } public void startPrefixMapping(String prefix,String uri) { } public void endPrefixMapping(String prefix) { } public void startElement(String namespaceURI,String localName, String qName,Attributes atts) { if(qName.equals("person")) { person = new Person(); } else if(qName.equals("name")) { insideNameElement = true; } else if(qName.equals("phone")) { insidePhoneElement = true; } else if(qName.equals("email")) { insideEmailElement = true; } } public void endElement(String namespaceURI,String localName, String qName) { if(qName.equals("person")) { if(person != null){ personVec.addElement(person); } } else if(qName.equals("name")) { insideNameElement = false; } else if(qName.equals("phone")) { insidePhoneElement = false; } else if(qName.equals("email")) { insideEmailElement = false; } } public void characters(char[] ch,int start,int length) { String str = ""; for(int i=start; i<start + length; i++) str += ch[i]; if(insideNameElement) person.setName(str); else if(insidePhoneElement) person.setPhone(str); else if(insideEmailElement) person.setEmail(str); } public void ignorableWhitespace(char[] ch,int start,int length) { } public void processingInstruction(String target,String data) { } public void skippedEntity(String name) { }
} class Person {
private String name = null; private String phone = null; private String email = null; public void setName(String value) { name = value; } public void setPhone(String value) { phone = value; } public void setEmail(String value) { email = value; } public String getName() { if(name == null) return("none"); return(name); } public String getPhone() { if(phone == null) return("none"); return(phone); } public String getEmail() { if(email == null) return("none"); return(email); }
}</source>
R, L 999 555-8888 e@yoursite.net V, R 333 555-9910 rv@yoursite.ru B, D. none b@xyz.net B, M 502 555-2192 none
A Program to Display the Input from a SAX Parser: subclass ContentHandler
<source lang="java">
/* Code revised from Java, XML, and JAXP by Arthur Griffith John Wiley & Sons 2002
- /
import java.io.IOException; 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; class MyContentHandler implements ContentHandler {
private Locator locator; public void setDocumentLocator(Locator locator) { this.locator = locator; System.out.println("-" + locator.getLineNumber() + "---Document ID: " + locator.getSystemId()); } public void startDocument() { System.out.println("-" + locator.getLineNumber() + "---Document parse started"); } public void endDocument() { System.out.println("-" + locator.getLineNumber() + "---Document parse ended"); } public void startPrefixMapping(String prefix, String uri) { System.out.println("-" + locator.getLineNumber() + "---Namespace scope begins"); System.out.println(" " + prefix + "=\"" + uri + "\""); } public void endPrefixMapping(String prefix) { System.out.println("-" + locator.getLineNumber() + "---Namespace scope ends"); System.out.println(" " + prefix); } 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) + "\""); } } 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); } public void characters(char[] ch, int start, int length) { System.out.println("-" + locator.getLineNumber() + "---Character data"); showCharacters(ch, start, length); } public void ignorableWhitespace(char[] ch, int start, int length) { System.out.println("-" + locator.getLineNumber() + "---Whitespace"); showCharacters(ch, start, length); } public void processingInstruction(String target, String data) { System.out.println("-" + locator.getLineNumber() + "---Processing Instruction"); System.out.println(" Target: " + target); System.out.println(" Data: " + data); } public void skippedEntity(String name) { System.out.println("-" + locator.getLineNumber() + "---Skipped Entity"); System.out.println(" Name: " + name); } 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()); }
} public class SAXDump {
static public void main(String[] arg) { SAXParserFactory spf = SAXParserFactory.newInstance(); XMLReader reader = null; try { SAXParser parser = spf.newSAXParser(); reader = parser.getXMLReader(); } catch (Exception e) { System.err.println(e); System.exit(1); } reader.setErrorHandler(new MyErrorHandler()); reader.setContentHandler(new MyContentHandler()); try { InputSource is = new InputSource("test.xml"); reader.parse(is); } catch (SAXException e) { System.exit(1); } catch (IOException e) { System.err.println(e); System.exit(1); } }
}</source>
-1---Document ID: file:///C:/Java_Dev/eclipse31/Eclipse/test.xml -1---Document parse started -1---Opening tag of an element Namespace: Local name: Qualified name: roots -2---Character data "\n " -2---Opening tag of an element Namespace: Local name: Qualified name: a -3---Character data "\n " -3---Opening tag of an element Namespace: Local name: Qualified name: b -3---Character data "text" -3---Closing tag of an element Namespace: Local name: Qualified name: b -4---Character data "\n " -4---Closing tag of an element Namespace: Local name: Qualified name: a -5---Character data "\n" -5---Closing tag of an element Namespace: Local name: Qualified name: roots -6---Document parse ended
Calling a .NET Web Service
<source lang="java">
import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.net.URL; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.xml.sax.InputSource; public class Main {
public static void main(String[] args) throws Exception { URL webSvcGetURL = new URL("http://www.server.net/Webservices"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(webSvcGetURL .openStream())); SAXSource saxSource = new SAXSource(new InputSource(bufferedReader)); String curDir = new File(".").getCanonicalPath(); StreamSource xlstStreamSource = new StreamSource(new File(curDir + File.separator + "style.xsl")); File resultHTMLFile = new File(curDir + File.separator + "output.html"); StreamResult streamResult = new StreamResult(resultHTMLFile); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(xlstStreamSource); transformer.transform((Source) saxSource, streamResult); }
}</source>
Configuring SAX parser factory to produce alternate parser
<source lang="java">
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class Main {
public static void main(String[] args) throws Exception { System.setProperty("avax.xml.parsers.SAXParserFactory", "org.apache.xerces.parsers.SAXParser"); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); }
}</source>
Generating SAX Parsing Events by Traversing a DOM Document
<source lang="java">
import java.io.File; import java.net.URI; import javax.xml.parsers.DocumentBuilderFactory; 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.sax.SAXResult; import org.w3c.dom.Document; import org.xml.sax.helpers.DefaultHandler; 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")); Source source = new DOMSource(doc); URI uri = new File("infilename.xml").toURI(); source.setSystemId(uri.toString()); DefaultHandler handler = new MyHandler(); SAXResult result = new SAXResult(handler); Transformer xformer = TransformerFactory.newInstance().newTransformer(); xformer.transform(source, result); }
} class MyHandler extends DefaultHandler { }</source>
Handling SAX errors during parsing
<source lang="java">
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); }
}</source>
Intercepting All Accesses to External Entities During XML SAX Parsing
<source lang="java">
import java.io.File; import java.io.FileReader; import java.net.URI; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); builder.setEntityResolver(new MyResolver()); Document doc = builder.parse(new File("infilename.xml")); }
} class MyResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) { try { URI uri = new URI(systemId); if ("file".equals(uri.getScheme())) { String filename = uri.getSchemeSpecificPart(); return new InputSource(new FileReader(filename)); } } catch (Exception e) { } return null; }
}</source>
Parsing XML with a simple SAX document handler
<source lang="java">
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[] argv) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SaxHandler handler = new SaxHandler(); parser.parse("sample.xml", handler); }
} class SaxHandler extends DefaultHandler {
public void startDocument() throws SAXException { System.out.println("Document processing started"); } public void endDocument() throws SAXException { System.out.println("Document processing finished"); } public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { if (qName.equals("order")) { } else if (qName.equals("date")) { } else { throw new IllegalArgumentException("Element "" + qName + "" is not allowed here"); } } public void endElement(String uri, String localName, String qName) throws SAXException { }
}</source>
Produce a SAX stream from a DOM Document
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/* $Id: DOM2SAX.java 627367 2008-02-13 12:03:30Z maxberger $ */
import java.util.List; import java.util.Map; import java.util.Stack; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.AttributesImpl; /**
* Helper class that produces a SAX stream from a DOM Document.*
* Part of the code here copied and adapted from Apache Xalan-J, * src/org/apache/xalan/xsltc/trax/DOM2SAX.java */ public class DOM2SAX { private static final String EMPTYSTRING = ""; private static final String XMLNS_PREFIX = "xmlns"; private ContentHandler contentHandler; private LexicalHandler lexicalHandler; private Map prefixes = new java.util.HashMap(); /** * Main constructor * @param handler the ContentHandler to send SAX events to */ public DOM2SAX(ContentHandler handler) { this.contentHandler = handler; if (handler instanceof LexicalHandler) { this.lexicalHandler = (LexicalHandler)handler; } } /** * Writes the given document using the given ContentHandler. * @param doc DOM document * @param fragment if false no startDocument() and endDocument() calls are issued. * @throws SAXException In case of a problem while writing XML */ public void writeDocument(Document doc, boolean fragment) throws SAXException { if (!fragment) { contentHandler.startDocument(); } for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling()) { writeNode(n); } if (!fragment) { contentHandler.endDocument(); } } /** * Begin the scope of namespace prefix. Forward the event to the SAX handler * only if the prefix is unknown or it is mapped to a different URI. */ private boolean startPrefixMapping(String prefix, String uri) throws SAXException { boolean pushed = true; Stack uriStack = (Stack)prefixes.get(prefix); if (uriStack != null) { if (uriStack.isEmpty()) { contentHandler.startPrefixMapping(prefix, uri); uriStack.push(uri); } else { final String lastUri = (String) uriStack.peek(); if (!lastUri.equals(uri)) { contentHandler.startPrefixMapping(prefix, uri); uriStack.push(uri); } else { pushed = false; } } } else { contentHandler.startPrefixMapping(prefix, uri); uriStack = new Stack(); prefixes.put(prefix, uriStack); uriStack.push(uri); } return pushed; } /* * End the scope of a name prefix by popping it from the stack and passing * the event to the SAX Handler. */ private void endPrefixMapping(String prefix) throws SAXException { final Stack uriStack = (Stack)prefixes.get(prefix); if (uriStack != null) { contentHandler.endPrefixMapping(prefix); uriStack.pop(); } } /** * If the DOM was created using a DOM 1.0 API, the local name may be null. * If so, get the local name from the qualified name before generating the * SAX event. */ private static String getLocalName(Node node) { final String localName = node.getLocalName(); if (localName == null) { final String qname = node.getNodeName(); final int col = qname.lastIndexOf(":"); return (col > 0) ? qname.substring(col + 1) : qname; } return localName; } /** * Writes a node using the given writer. * @param node node to serialize * @throws SAXException In case of a problem while writing XML */ private void writeNode(Node node) throws SAXException { if (node == null) { return; } switch (node.getNodeType()) { case Node.ATTRIBUTE_NODE: // handled by ELEMENT_NODE case Node.DOCUMENT_FRAGMENT_NODE: case Node.DOCUMENT_TYPE_NODE: case Node.ENTITY_NODE: case Node.ENTITY_REFERENCE_NODE: case Node.NOTATION_NODE: // These node types are ignored!!! break; case Node.CDATA_SECTION_NODE: final String cdata = node.getNodeValue(); if (lexicalHandler != null) { lexicalHandler.startCDATA(); contentHandler.characters(cdata.toCharArray(), 0, cdata.length()); lexicalHandler.endCDATA(); } else { // in the case where there is no lex handler, we still // want the text of the cdate to make its way through. contentHandler.characters(cdata.toCharArray(), 0, cdata.length()); } break; case Node.ruMENT_NODE: // should be handled!!! if (lexicalHandler != null) { final String value = node.getNodeValue(); lexicalHandler.rument(value.toCharArray(), 0, value.length()); } break; case Node.DOCUMENT_NODE: contentHandler.startDocument(); Node next = node.getFirstChild(); while (next != null) { writeNode(next); next = next.getNextSibling(); } contentHandler.endDocument(); break; case Node.ELEMENT_NODE: String prefix; List pushedPrefixes = new java.util.ArrayList(); final AttributesImpl attrs = new AttributesImpl(); final NamedNodeMap map = node.getAttributes(); final int length = map.getLength(); // Process all namespace declarations for (int i = 0; i < length; i++) { final Node attr = map.item(i); final String qnameAttr = attr.getNodeName(); // Ignore everything but NS declarations here if (qnameAttr.startsWith(XMLNS_PREFIX)) { final String uriAttr = attr.getNodeValue(); final int colon = qnameAttr.lastIndexOf(":"); prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING; if (startPrefixMapping(prefix, uriAttr)) { pushedPrefixes.add(prefix); } } } // Process all other attributes for (int i = 0; i < length; i++) { final Node attr = map.item(i); final String qnameAttr = attr.getNodeName(); // Ignore NS declarations here if (!qnameAttr.startsWith(XMLNS_PREFIX)) { final String uriAttr = attr.getNamespaceURI(); // Uri may be implicitly declared if (uriAttr != null) { final int colon = qnameAttr.lastIndexOf(":"); prefix = (colon > 0) ? qnameAttr.substring(0, colon) : EMPTYSTRING; if (startPrefixMapping(prefix, uriAttr)) { pushedPrefixes.add(prefix); } } // Add attribute to list attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr), qnameAttr, "CDATA", attr .getNodeValue()); } } // Now process the element itself final String qname = node.getNodeName(); final String uri = node.getNamespaceURI(); final String localName = getLocalName(node); // Uri may be implicitly declared if (uri != null) { final int colon = qname.lastIndexOf(":"); prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING; if (startPrefixMapping(prefix, uri)) { pushedPrefixes.add(prefix); } } // Generate SAX event to start element contentHandler.startElement(uri, localName, qname, attrs); // Traverse all child nodes of the element (if any) next = node.getFirstChild(); while (next != null) { writeNode(next); next = next.getNextSibling(); } // Generate SAX event to close element contentHandler.endElement(uri, localName, qname); // Generate endPrefixMapping() for all pushed prefixes final int nPushedPrefixes = pushedPrefixes.size(); for (int i = 0; i < nPushedPrefixes; i++) { endPrefixMapping((String)pushedPrefixes.get(i)); } break; case Node.PROCESSING_INSTRUCTION_NODE: contentHandler.processingInstruction(node.getNodeName(), node.getNodeValue()); break; case Node.TEXT_NODE: final String data = node.getNodeValue(); contentHandler.characters(data.toCharArray(), 0, data.length()); break; default: //nop } } }</source>
SAX Error Checking: A Simple Implementation of the ErrorHandler Interface
<source lang="java">
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); }
}</source>
SAX parer with all its action displayed
<source lang="java">
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 TrySAX extends DefaultHandler {
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 TrySAX(); 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)); } private static TrySAX handler = null; private SAXParser parser = null;
}</source>
Sax to DOM converter
<source lang="java">
/* Copyright 2004 The Apache Software Foundation
* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
// Revised from xmlbeans import org.w3c.dom.Node; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.rument; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.ContentHandler; import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.ext.LexicalHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; import java.util.Stack; import java.util.Vector; public class Sax2Dom
extends DefaultHandler implements ContentHandler, LexicalHandler
{
public static final String EMPTYSTRING = ""; public static final String XML_PREFIX = "xml"; public static final String XMLNS_PREFIX = "xmlns"; public static final String XMLNS_STRING = "xmlns:"; public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; private Node _root = null; private Document _document = null; private Stack _nodeStk = new Stack(); private Vector _namespaceDecls = null; public Sax2Dom() throws ParserConfigurationException { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); _document = factory.newDocumentBuilder().newDocument(); _root = _document; } public Sax2Dom(Node root) throws ParserConfigurationException { _root = root; if (root instanceof Document) { _document = (Document) root; } else if (root != null) { _document = root.getOwnerDocument(); } else { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); _document = factory.newDocumentBuilder().newDocument(); _root = _document; } } public Node getDOM() { return _root; } public void characters(char[] ch, int start, int length) { final Node last = (Node) _nodeStk.peek(); // No text nodes can be children of root (DOM006 exception) if (last != _document) { final String text = new String(ch, start, length); last.appendChild(_document.createTextNode(text)); } } public void startDocument() { _nodeStk.push(_root); } public void endDocument() { _nodeStk.pop(); } public void startElement(String namespace, String localName, String qName, Attributes attrs) { final Element tmp = (Element) _document.createElementNS(namespace, qName); // Add namespace declarations first if (_namespaceDecls != null) { final int nDecls = _namespaceDecls.size(); for (int i = 0; i < nDecls; i++) { final String prefix = (String) _namespaceDecls.elementAt(i++); if (prefix == null || prefix.equals(EMPTYSTRING)) { tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, (String) _namespaceDecls.elementAt(i)); } else { tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, (String) _namespaceDecls.elementAt(i)); } } _namespaceDecls.clear(); } // Add attributes to element final int nattrs = attrs.getLength(); for (int i = 0; i < nattrs; i++) { if (attrs.getLocalName(i) == null) { tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); } else { tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i)); } } // Append this new node onto current stack node Node last = (Node) _nodeStk.peek(); last.appendChild(tmp); // Push this node onto stack _nodeStk.push(tmp); } public void endElement(String namespace, String localName, String qName) { _nodeStk.pop(); } public void startPrefixMapping(String prefix, String uri) { if (_namespaceDecls == null) { _namespaceDecls = new Vector(2); } _namespaceDecls.addElement(prefix); _namespaceDecls.addElement(uri); } public void endPrefixMapping(String prefix) { // do nothing } /** * This class is only used internally so this method should never * be called. */ public void ignorableWhitespace(char[] ch, int start, int length) { } /** * adds processing instruction node to DOM. */ public void processingInstruction(String target, String data) { final Node last = (Node) _nodeStk.peek(); ProcessingInstruction pi = _document.createProcessingInstruction( target, data); if (pi != null) last.appendChild(pi); } /** * This class is only used internally so this method should never * be called. */ public void setDocumentLocator(Locator locator) { } /** * This class is only used internally so this method should never * be called. */ public void skippedEntity(String name) { }
/** * Lexical Handler method to create comment node in DOM tree. */ public void comment(char[] ch, int start, int length) { final Node last = (Node) _nodeStk.peek(); Comment comment = _document.createComment(new String(ch, start, length)); if (comment != null) last.appendChild(comment); } // Lexical Handler methods- not implemented public void startCDATA() { } public void endCDATA() { } public void startEntity(java.lang.String name) { } public void endEntity(String name) { } public void startDTD(String name, String publicId, String systemId) throws SAXException { } public void endDTD() { }
}</source>
The XMLReader interface
<source lang="java">
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()); reader.parse("http://yourURL/TextDoc3.xml"); }
}</source>
Using XML locator to indicate current parser position
<source lang="java">
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; 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"); } } 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()); }
}</source>