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
1<atts.getlength();i++) (name='" +
2atts.getLocalName(i) + "' )");="" ,value='" + atts.getValue(i) + "' attribute="new" atturi="atts.getURI(i);" defaultmutabletreenode="" defaultmutabletreenode("attribute="" if(atturi.length()="" string="" {=""> 0)
3{
4String attPrefix = (String)namespaceMappings.get(attURI);
5if(attPrefix.equals("")){
6attPrefix = "[None]";
7}
8DefaultMutableTreeNode attNamespace = new DefaultMutableTreeNode("Namespace: prefix = '" +
9attPrefix + "',URI = '" + attURI + "'");
10attribute.add(attNamespace);
11}
12current.add(attribute);
13}
14}
15
16/* (non-Javadoc)
17* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
18*/
19public void endElement(String uri, String localName, String qName) throws SAXException {
20// TODO Auto-generated method stub
21current = (DefaultMutableTreeNode)current.getParent();
22}
23
24/* (non-Javadoc)
25* @see org.xml.sax.ContentHandler#characters(char[], int, int)
26*/
27public void characters(char[] ch, int start, int length) throws SAXException {
28// TODO Auto-generated method stub
29String s = new String(ch,start,length);
30DefaultMutableTreeNode data = new DefaultMutableTreeNode("Character Data: '" + s + "'");
31current.add(data);
32}
33
34/* (non-Javadoc)
35* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
36*/
37public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
38// TODO Auto-generated method stub
39
40}
41
42/* (non-Javadoc)
43* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
44*/
45public void processingInstruction(String target, String data) throws SAXException {
46// TODO Auto-generated method stub
47DefaultMutableTreeNode pi = new DefaultMutableTreeNode("PI (target = '"
48\+ target + "', data = '" + data + "')");
49current.add(pi);
50}
51
52/* (non-Javadoc)
53* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
54*/
55public void skippedEntity(String name) throws SAXException {
56// TODO Auto-generated method stub
57DefaultMutableTreeNode skipped = new DefaultMutableTreeNode("Skipped Entity: '" + name + "'");
58current.add(skipped);
59}
60}
61
62class JTreeErrorHandler implements ErrorHandler{
63
64/* (non-Javadoc)
65* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
66*/
67public void warning(SAXParseException exception) throws SAXException {
68// TODO Auto-generated method stub
69System.out.println("**Parsing Warning**\n" +
70" Line: " +
71exception.getLineNumber() + "\n" +
72" URI: " +
73exception.getSystemId() + "\n" +
74" Message:" +
75exception.getMessage());
76throw new SAXException("Warning encountered");
77}
78
79/* (non-Javadoc)
80* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
81*/
82public void error(SAXParseException exception) throws SAXException {
83// TODO Auto-generated method stub
84System.out.println("**Parsing Error**\n" +
85" Line: " +
86exception.getLineNumber() + "\n" +
87" URI: " +
88exception.getSystemId() + "\n" +
89" Message:" +
90exception.getMessage());
91throw new SAXException("Error encounted");
92}
93
94/* (non-Javadoc)
95* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
96*/
97public void fatalError(SAXParseException exception) throws SAXException {
98// TODO Auto-generated method stub
99System.out.println("**Parsing Fatal Error**\n" +
100" Line: " +
101exception.getLineNumber() + "\n" +
102" URI: " +
103exception.getSystemId() + "\n" +
104" Message:" +
105exception.getMessage());
106throw new SAXException("Fatal Error encounted");
107}
108
109}
110xml文件如下:你可以不用这个xml,用别的xml文件也可以
111<?xml version="1.0"?>
112<!DOCTYPE book SYSTEM "DTD/JavaXML.dtd">
113
114<!-- Java and XML Contents -->
115<book xmlns=" http://www.oreilly.com/javaxml2 " xmlns:ora=" http://www.oreilly.com ">
116<title ora:series="Java">Java and XML</title>
117<!-- Chapter List -->
118<contents>
119<chapter number="1" title="Introduction">
120<topic name="XML Matters"></topic>
121<topic name="What's Important"></topic>
122<topic name="The Essentials"></topic>
123<topic name="What's Next?"></topic>
124</chapter>
125<chapter number="2" title="Nuts and Bolts">
126<topic name="The Basics"></topic>
127<topic name="Constraints"></topic>
128<topic name="Transformations"></topic>
129<topic name="And More..."></topic>
130<topic name="What's Next?"></topic>
131</chapter>
132<chapter number="3" title="SAX">
133<topic name="Getting Prepared"></topic>
134<topic name="SAX Readers"></topic>
135<topic name="Content Handlers"></topic>
136<topic name="Gotcha!"></topic>
137<topic name="What's Next?"></topic>
138</chapter>
139<chapter number="4" title="Advanced SAX">
140<topic name="Properties and Features"></topic>
141<topic name="More Handlers"></topic>
142<topic name="Filters and Writers"></topic>
143<topic name="Even More Handlers"></topic>
144<topic name="Gotcha!"></topic>
145<topic name="What's Next?"></topic>
146</chapter>
147<chapter number="5" title="DOM">
148<topic name="The Document Object Model"></topic>
149<topic name="Serialization"></topic>
150<topic name="Mutability"></topic>
151<topic name="Gotcha!"></topic>
152<topic name="What's Next?"></topic>
153</chapter>
154<chapter number="6" title="Advanced DOM">
155<topic name="DOM and Mutation"></topic>
156<topic name="Namespaces and DOM Level 2"></topic>
157<topic name="DOM and HTML"></topic>
158<topic name="DOM Level 3"></topic>
159<topic name="Gotcha!"></topic>
160<topic name="What's Next?"></topic>
161</chapter>
162<chapter number="7" title="JDOM">
163<topic name="The Basics"></topic>
164<topic name="PropsToXML"></topic>
165<topic name="XMLProperties"></topic>
166<topic name="Is JDOM a Standard?"></topic>
167<topic name="Gotcha!"></topic>
168<topic name="What's Next?"></topic>
169</chapter>
170<chapter number="8" title="Advanced JDOM">
171<topic name="The Whole Ball of Wax"></topic>
172<topic name="JDOM and Factories"></topic>
173<topic name="Wrappers and Decorators"></topic>
174<topic name="Gotcha!"></topic>
175<topic name="What's Next?"></topic>
176</chapter>
177<chapter number="9" title="JAXP">
178<topic name="API or Abstraction?"></topic>
179<topic name="JAXP 1.0"></topic>
180<topic name="JAXP 1.1"></topic>
181<topic name="Gotcha!"></topic>
182<topic name="What's Next?"></topic>
183</chapter>
184<chapter number="10" title="Web Publishing Frameworks">
185<topic name="Selecting a Framework"></topic>
186<topic name="Installation"></topic>
187<topic name="Using a Publishing Framework"></topic>
188<topic name="XSP"></topic>
189<topic name="Cocoon 2.0 and Beyond"></topic>
190<topic name="What's Next?"></topic>
191</chapter>
192<chapter number="11" title="XML-RPC">
193<topic name="RPC Versus RMI"></topic>
194<topic name="Saying Hello"></topic>
195<topic name="The Real World"></topic>
196<topic name="What's Next?"></topic>
197</chapter>
198<chapter number="12" title="SOAP">
199<topic name="Starting Out"></topic>
200<topic name="Setting Up"></topic>
201<topic name="Getting Dirty"></topic>
202<topic name="Going Further"></topic>
203<topic name="What's Next?"></topic>
204</chapter>
205<chapter number="13" title="Web Services">
206<topic name="Web Services"></topic>
207<topic name="UDDI"></topic>
208<topic name="WSDL"></topic>
209<topic name="Putting It All Together"></topic>
210<topic name="What's Next?"></topic>
211</chapter>
212<chapter number="14" title="Content Syndication">
213<topic name="The Foobar Public Library"></topic>
214<topic name="mytechbooks.comI"></topic>
215<topic name="Push Versus Pull"></topic>
216<topic name="What's Next?"></topic>
217</chapter>
218<chapter number="15" title="XML Data Binding">
219<topic name="First Principles"></topic>
220<topic name="Castor"></topic>
221<topic name="Zeus"></topic>
222<topic name="JAXB"></topic>
223<topic name="What's Next?"></topic>
224</chapter>
225<chapter number="16" title="Looking Forward">
226<topic name="XLink"></topic>
227<topic name="XPointer"></topic>
228<topic name="XML Schema Bindings"></topic>
229<topic name="And the Rest..."></topic>
230<topic name="What's Next?"></topic>
231</chapter>
232</contents>
233<ora:copyright>&OReillyCopyright</ora:copyright>
234</book>
235
236作者Blog: http://blog.csdn.net/flysyq/</atts.getlength();i++)>