Java & XML學(xué)習(xí)筆記
1、需要軟件
java,解析器(例如Xerces),API(例如SAX,DOM)
2、SAX機(jī)制
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);
這樣一個(gè)xml文檔解析過(guò)程就完成了。因?yàn)镾AX是采用時(shí)間處理機(jī)制來(lái)解析XML
文檔的,在解析過(guò)程中會(huì)觸發(fā)一些事件,也就是執(zhí)行特定的方法,你可以實(shí)現(xiàn)
這些方法,就可以通過(guò)解析xml來(lái)做一些事情了
2)處理
SAX2.0定義的核心處理接口一共有
org.xml.sax.ContentHandler
org.xml.sax.ErrorHandler
org.xml.sax.DTDHandler
org.xml.sax.EntityResolver
這些接口是通過(guò)
org.xml.sax.XMLReader的setContentHandler(),setEroorHandler(),
setDTDHandler(),setEntityHandler()注冊(cè)到解析器,這里面最重要的是
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;
}
通過(guò)setContentHandler()將你實(shí)現(xiàn)的ContentHandler注冊(cè)給XMLReader之后,
在解析過(guò)程中,系統(tǒng)根據(jù)各種條件執(zhí)行接口中的方法,下面簡(jiǎn)單說(shuō)明一下
1)文檔定位器
private Locator locator;
public void setDocumentLocator(Locator locator){
this.locator = locator;
}
通常情況下,你只要如此實(shí)現(xiàn)就可以了,這個(gè)主要是得到當(dāng)前解析的位置,
通過(guò)得到的locator,你可以使用它的getLineNumber(),getColumnName()等
方法,可以得到文檔當(dāng)前的位置,但要注意的是,這個(gè)locator不能保存,只
針對(duì)當(dāng)前的解析有效
2)文檔的開(kāi)頭和結(jié)尾
public void startDocument() throws SAXException{
//解析過(guò)程中僅位于setDocumentLocator()方法后調(diào)用
}
public void endDocument() throws SAXException{
//解析過(guò)程中最后調(diào)用
}
大多數(shù)情況下你可以不用理他們,只要寫(xiě)個(gè)空方法就可以了
3)名字空間的開(kāi)始和結(jié)束
public void startPrefixMapping(String prefix,String uri)
throws SAXException{
}
public void endPrefixMapping(String prifix)
throws SAXException{
}
4)元素的開(kāi)始和結(jié)束
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)元素的數(shù)據(jù)
public void characters(char ch[],int start,int length)
throws SAXException{
String s = new String(ch,start,length);
}
這個(gè)是得到當(dāng)前的元素的文本數(shù)據(jù)
6)可以忽略的空白
public void ignorableWhitespace(char ch[],int start,int length)
throws SAXException{
}
7)實(shí)體
public void skippedEntity(String name)
throws SAXException{
}
8)指令處理
public void processingInstruction(String target,String data)
throws SAXException{
}
3)例子:這個(gè)是從Java & XML 中復(fù)制過(guò)來(lái)的,
/*
* 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 = " reader.setFeature(featureURI,true);
featureURI = " setNamespaceProcessing(reader,true);
featureURI = " reader.setFeature(featureURI,true);
featureURI = " 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文件如下:你可以不用這個(gè)xml,用別的xml文件也可以
<?xml version="1.0"?>
<!DOCTYPE book SYSTEM "DTD/JavaXML.dtd">
<!-- Java and XML Contents -->
<book xmlns=" <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>
聯(lián)系客服