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 namespaceMapp