Java & xml学习笔记 SAX篇

Java & XML学习笔记
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  {
   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文件也可以




 Java and XML
 
 
  
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
   
  

  
   
   
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
   
  

  
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
  

  
   
   
   
   
   
  

  
   
   
   
   
   
  

 

 &OReillyCopyright;


     
     


     

你可能感兴趣的:(Java & xml学习笔记 SAX篇)