Java & xml学习笔记 SAX篇 1、需要软件 java,解析器(例如Xerces),API(例如SAX,DOM) 2、SAX机制 1)解析 String xmlURI = "c:/test.xml"; String vendorParserClass = "org.apache.xerces.parsers.SAXParser"; XMLReaer reader = XMLReaderFactory.createXMLReader(vendorParserClass);
InputSource inputSource = new InputSource(xmlURI); reader.parse(inputSource);
这样一个xml文档解析过程就完成了。因为SAX是采用时间处理机制来解析XML 文档的,在解析过程中会触发一些事件,也就是执行特定的方法,你可以实现 这些方法,就可以通过解析xml来做一些事情了 2)处理 SAX2.0定义的核心处理接口一共有 org.xml.sax.ContentHandler org.xml.sax.ErrorHandler org.xml.sax.DTDHandler org.xml.sax.EntityResolver 这些接口是通过 org.xml.sax.XMLReader的setContentHandler(),setEroorHandler(), setDTDHandler(),setEntityHandler()注册到解析器,这里面最重要的是 org.xml.sax.ContentHandler接口,它具体如下 public interface ContentHandler{ public void setDocumentLocator(Locator locator); public void startDocument() throws SAXException; public void endDocument() throws SAXException; public void startPrefixMapping(String prefix,String uri) throws SAXException; public void endPrefixMapping(String prifix) throws SAXException; public void startElement(String namespaceURI,String localName, String qName,Attributes atts) throws SAXException; public void endElement(String namespaceURI,String localName, String qName) throws SAXException; public void characters(char ch[],int start,int length) throws SAXException; public void ignorableWhitespace(char ch[],int start,int length) throws SAXException; public void processingInstruction(String target,String data) throws SAXException; public void skippedEntity(String name) throws SAXException; } 通过setContentHandler()将你实现的ContentHandler注册给XMLReader之后, 在解析过程中,系统根据各种条件执行接口中的方法,下面简单说明一下 1)文档定位器 private Locator locator;
public void setDocumentLocator(Locator locator){ this.locator = locator; }
通常情况下,你只要如此实现就可以了,这个主要是得到当前解析的位置, 通过得到的locator,你可以使用它的getLineNumber(),getColumnName()等 方法,可以得到文档当前的位置,但要注意的是,这个locator不能保存,只 针对当前的解析有效 2)文档的开头和结尾 public void startDocument() throws SAXException{ //解析过程中仅位于setDocumentLocator()方法后调用 } public void endDocument() throws SAXException{ //解析过程中最后调用 }
大多数情况下你可以不用理他们,只要写个空方法就可以了 3)名字空间的开始和结束 public void startPrefixMapping(String prefix,String uri) throws SAXException{ } public void endPrefixMapping(String prifix) throws SAXException{ } 4)元素的开始和结束 public void startElement(String namespaceURI,String localName, String qName,Attributes atts) throws SAXException{ } public void endElement(String namespaceURI,String localName, String qName) throws SAXException{ } 5)元素的数据 public void characters(char ch[],int start,int length) throws SAXException{ String s = new String(ch,start,length); } 这个是得到当前的元素的文本数据 6)可以忽略的空白 public void ignorableWhitespace(char ch[],int start,int length) throws SAXException{ } 7)实体 public void skippedEntity(String name) throws SAXException{ } 8)指令处理 public void processingInstruction(String target,String data) throws SAXException{ } 3)例子:这个是从Java & XML 中复制过来的, /* * Created on 2004-11-30 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package javaxml2;
/** * @author yuangfang * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */
import java.io.*; import java.util.*; import org.xml.sax.*; import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.XMLReaderFactory;
import java.awt.*; import javax.swing.*; import javax.swing.tree.*;
public class SAXTreeViewer extends JFrame{ private String vendorParserClass = "org.apache.xerces.parsers.SAXParser";
private JTree jTree; DefaultTreeModel defaultTreeModel; public SAXTreeViewer(){ super("SAX Tree Viewer"); setSize(600,450); } public void init(String xmlURI) throws IOException,SAXException{ DefaultMutableTreeNode base = new DefaultMutableTreeNode("XML Document:" + xmlURI); defaultTreeModel = new DefaultTreeModel(base); jTree = new JTree(defaultTreeModel); buildTree(defaultTreeModel,base,xmlURI); getContentPane().add(new JScrollPane(jTree),BorderLayout.CENTER); } public void buildTree(DefaultTreeModel treeModel,DefaultMutableTreeNode base,String xmlURI) throws IOException,SAXException{ String featureURI = ""; try{ XMLReader reader = XMLReaderFactory.createXMLReader(vendorParserClass); ContentHandler jTreeContentHandler = new JTreeContentHandler(treeModel,base); ErrorHandler jTreeErrorHandler = new JTreeErrorHandler(); reader.setContentHandler(jTreeContentHandler); reader.setErrorHandler(jTreeErrorHandler); reader.setEntityResolver(new SimpleEntityResolver()); featureURI = "http://xml.org/sax/features/validation"; reader.setFeature(featureURI,true); featureURI = "http://xml.org/sax/features/namespaces"; setNamespaceProcessing(reader,true); featureURI = "http://xml.org/sax/features/string-interning"; reader.setFeature(featureURI,true); featureURI = "http://apache.org/xml/features/validation/schema"; reader.setFeature(featureURI,false); InputSource inputSource = new InputSource(xmlURI); reader.parse(inputSource); } catch(SAXNotRecognizedException e){ System.out.println("The parse class " + vendorParserClass + " does not recognize the feature URI " + featureURI); System.exit(0); } catch(SAXNotSupportedException e){ System.out.println("The parser class " + vendorParserClass + " does not support the feature URI " + featureURI); } } private void setNamespaceProcessing(XMLReader reader,boolean state) throws SAXNotSupportedException,SAXNotRecognizedException { reader.setFeature("http://xml.org/sax/features/namespaces",state); reader.setFeature("http://xml.org/sax/features/namespace-prefixes",!state); } public static void main(String[] args) { try{ if(args.length != 1){ System.out.println("Usage:Java javaxml2.SAXTreeViewer " + "[XML Document URI]"); System.exit(0); } SAXTreeViewer viewer = new SAXTreeViewer(); viewer.init(args[0]); viewer.setVisible(true); }catch(Exception e) { e.printStackTrace(); } } }
class JTreeContentHandler implements ContentHandler,LexicalHandler{ private DefaultTreeModel treeModel; private DefaultMutableTreeNode current; private Locator locator; private Map namespaceMappings; /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int) */ public void comment(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub
} /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#endCDATA() */ public void endCDATA() throws SAXException { // TODO Auto-generated method stub
} /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#endDTD() */ public void endDTD() throws SAXException { // TODO Auto-generated method stub
} /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String) */ public void endEntity(String name) throws SAXException { // TODO Auto-generated method stub current = (DefaultMutableTreeNode)current.getParent(); } /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#startCDATA() */ public void startCDATA() throws SAXException { // TODO Auto-generated method stub
} /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String) */ public void startDTD(String name, String publicId, String systemId) throws SAXException { // TODO Auto-generated method stub System.out.println("start DTD"); DefaultMutableTreeNode dtdReference = new DefaultMutableTreeNode("DTD for '" + name + "'"); if(publicId != null) { DefaultMutableTreeNode publicIDNode = new DefaultMutableTreeNode("Public ID: " + publicId + "'"); dtdReference.add(publicIDNode); } if(systemId != null) { DefaultMutableTreeNode systemIDNode = new DefaultMutableTreeNode("System ID: " + systemId + "'"); dtdReference.add(systemIDNode); } current.add(dtdReference); } /* (non-Javadoc) * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String) */ public void startEntity(String name) throws SAXException { // TODO Auto-generated method stub DefaultMutableTreeNode entity = new DefaultMutableTreeNode("Entity: '" + name + "'"); current.add(entity); current = entity; } public JTreeContentHandler(DefaultTreeModel treeModel,DefaultMutableTreeNode base) { this.treeModel = treeModel; this.current = base; this.namespaceMappings = new HashMap(); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator) */ public void setDocumentLocator(Locator locator) { // TODO Auto-generated method stub this.locator = locator; }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#startDocument() */ public void startDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("start document"); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#endDocument() */ public void endDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("end document"); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String) */ public void startPrefixMapping(String prefix, String uri) throws SAXException { // TODO Auto-generated method stub namespaceMappings.put(uri,prefix); System.out.println("start PrefixMapping " + prefix); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String) */ public void endPrefixMapping(String prefix) throws SAXException { // TODO Auto-generated method stub for(Iterator i = namespaceMappings.keySet().iterator();i.hasNext();) { String uri = (String) i.next(); String thisPrefix = (String)namespaceMappings.get(uri); if(prefix.equals(thisPrefix)){ namespaceMappings.remove(uri); break; } } System.out.println("end PrefixMapping " + prefix); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { // TODO Auto-generated method stub DefaultMutableTreeNode element = new DefaultMutableTreeNode("Element: " + localName + " at line " + locator.getLineNumber()); current.add(element); current = element; if(uri.length() > 0) { String prefix = (String)namespaceMappings.get(uri); if(prefix.equals("")){ prefix = "[None]"; } DefaultMutableTreeNode namespace = new DefaultMutableTreeNode("Namespace: prefix = '" + prefix + "',URI = '" + uri + "'"); current.add(namespace); } for(int i = 0;i<atts.getLength();i++) { DefaultMutableTreeNode attribute = new DefaultMutableTreeNode("Attribute (name = '" + atts.getLocalName(i) + "',value = '" + atts.getValue(i) + "')"); String attURI = atts.getURI(i); if(attURI.length() > 0) { String attPrefix = (String)namespaceMappings.get(attURI); if(attPrefix.equals("")){ attPrefix = "[None]"; } DefaultMutableTreeNode attNamespace = new DefaultMutableTreeNode("Namespace: prefix = '" + attPrefix + "',URI = '" + attURI + "'"); attribute.add(attNamespace); } current.add(attribute); } }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub current = (DefaultMutableTreeNode)current.getParent(); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub String s = new String(ch,start,length); DefaultMutableTreeNode data = new DefaultMutableTreeNode("Character Data: '" + s + "'"); current.add(data); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int) */ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String) */ public void processingInstruction(String target, String data) throws SAXException { // TODO Auto-generated method stub DefaultMutableTreeNode pi = new DefaultMutableTreeNode("PI (target = '" + target + "', data = '" + data + "')"); current.add(pi); }
/* (non-Javadoc) * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String) */ public void skippedEntity(String name) throws SAXException { // TODO Auto-generated method stub DefaultMutableTreeNode skipped = new DefaultMutableTreeNode("Skipped Entity: '" + name + "'"); current.add(skipped); } }
class JTreeErrorHandler implements ErrorHandler{
/* (non-Javadoc) * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) */ public void warning(SAXParseException exception) throws SAXException { // TODO Auto-generated method stub System.out.println("**Parsing Warning**\n" + " Line: " + exception.getLineNumber() + "\n" + " URI: " + exception.getSystemId() + "\n" + " Message:" + exception.getMessage()); throw new SAXException("Warning encountered"); }
/* (non-Javadoc) * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) */ public void error(SAXParseException exception) throws SAXException { // TODO Auto-generated method stub System.out.println("**Parsing Error**\n" + " Line: " + exception.getLineNumber() + "\n" + " URI: " + exception.getSystemId() + "\n" + " Message:" + exception.getMessage()); throw new SAXException("Error encounted"); }
/* (non-Javadoc) * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) */ public void fatalError(SAXParseException exception) throws SAXException { // TODO Auto-generated method stub System.out.println("**Parsing Fatal Error**\n" + " Line: " + exception.getLineNumber() + "\n" + " URI: " + exception.getSystemId() + "\n" + " Message:" + exception.getMessage()); throw new SAXException("Fatal Error encounted"); } } xml文件如下:你可以不用这个xml,用别的xml文件也可以 <?xml version="1.0"?> <!DOCTYPE book SYSTEM "DTD/JavaXML.dtd"> <!-- Java and XML Contents --> <book xmlns="http://www.oreilly.com/javaxml2" xmlns:ora="http://www.oreilly.com" > <title ora:series="Java">Java and XML</title> <!-- Chapter List --> <contents> <chapter title="Introduction" number="1"> <topic name="XML Matters"/> <topic name="What's Important"/> <topic name="The Essentials"/> <topic name="What's Next?"/> </chapter> <chapter title="Nuts and Bolts" number="2"> <topic name="The Basics"/> <topic name="Constraints"/> <topic name="Transformations"/> <topic name="And More..."/> <topic name="What's Next?"/> </chapter> <chapter title="SAX" number="3"> <topic name="Getting Prepared"/> <topic name="SAX Readers"/> <topic name="Content Handlers"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="Advanced SAX" number="4"> <topic name="Properties and Features"/> <topic name="More Handlers"/> <topic name="Filters and Writers"/> <topic name="Even More Handlers"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="DOM" number="5"> <topic name="The Document Object Model"/> <topic name="Serialization"/> <topic name="Mutability"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="Advanced DOM" number="6"> <topic name="DOM and Mutation"/> <topic name="Namespaces and DOM Level 2"/> <topic name="DOM and HTML"/> <topic name="DOM Level 3"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="JDOM" number="7"> <topic name="The Basics"/> <topic name="PropsToXML"/> <topic name="XMLProperties"/> <topic name="Is JDOM a Standard?"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="Advanced JDOM" number="8"> <topic name="The Whole Ball of Wax"/> <topic name="JDOM and Factories"/> <topic name="Wrappers and Decorators"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="JAXP" number="9"> <topic name="API or Abstraction?"/> <topic name="JAXP 1.0"/> <topic name="JAXP 1.1"/> <topic name="Gotcha!"/> <topic name="What's Next?"/> </chapter> <chapter title="Web Publishing Frameworks" number="10"> <topic name="Selecting a Framework"/> <topic name="Installation"/> <topic name="Using a Publishing Framework"/> <topic name="XSP"/> <topic name="Cocoon 2.0 and Beyond"/> <topic name="What's Next?"/> </chapter> <chapter title="XML-RPC" number="11"> <topic name="RPC Versus RMI"/> <topic name="Saying Hello"/> <topic name="The Real World"/> <topic name="What's Next?"/> </chapter> <chapter title="SOAP" number="12"> <topic name="Starting Out"/> <topic name="Setting Up"/> <topic name="Getting Dirty"/> <topic name="Going Further"/> <topic name="What's Next?"/> </chapter> <chapter title="Web Services" number="13"> <topic name="Web Services"/> <topic name="UDDI"/> <topic name="WSDL"/> <topic name="Putting It All Together"/> <topic name="What's Next?"/> </chapter> <chapter title="Content Syndication" number="14"> <topic name="The Foobar Public Library"/> <topic name="mytechbooks.comI"/> <topic name="Push Versus Pull"/> <topic name="What's Next?"/> </chapter> <chapter title="XML Data Binding" number="15"> <topic name="First Principles"/> <topic name="Castor"/> <topic name="Zeus"/> <topic name="JAXB"/> <topic name="What's Next?"/> </chapter> <chapter title="Looking Forward" number="16"> <topic name="XLink"/> <topic name="XPointer"/> <topic name="XML Schema Bindings"/> <topic name="And the Rest..."/> <topic name="What's Next?"/> </chapter> </contents> <ora:copyright>&OReillyCopyright;</ora:copyright> </book>
作者Blog:http://blog.csdn.net/flysyq/

|