import java.io.FileReader; import java.io.IOException; import java.io.File; import java.util.Map; import java.util.HashMap; import org.xml.sax.XMLReader; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.XMLReaderFactory; import org.xml.sax.ext.DefaultHandler2; public class SAXDemo{ public static void main(String[] args) throws SAXException, IOException{ if(args.length<1 || args.length>2){ System.err.println("usage: java SAXDemo xmlFile [v]"); return; } XMLReader xmlr = XMLReaderFactory.createXMLReader(); if(args.length==2 && args[1].equalsIgnoreCase("v")){ xmlr.setFeature("http://xml.org/sax/features/validation", true); } xmlr.setFeature("http://xml.org/sax/features/namespace-prefixes", true); Handler handler = new Handler(); xmlr.setContentHandler(handler); xmlr.setDTDHandler(handler); xmlr.setEntityResolver(handler); xmlr.setErrorHandler(handler); xmlr.setProperty("http://xml.org/sax/properties/lexical-handler", handler); xmlr.parse(new InputSource(new FileReader(args[0]))); } } class Handler extends DefaultHandler2{ private Locator locator; private Map dtdMapping; Handler(){ super(); // Improve the entity resolve efficiency through local dtd resource. File file = new File("recipeml.dtd"); if(file.exists()&&file.isFile()){ dtdMapping = new HashMap(); dtdMapping.put("-//FormatData//DTD RecipeML 0.5//EN", "recipeml.dtd"); // the DTD file is in current directory } } @Override public void characters(char[] ch, int start, int length){ System.out.print("characters() ["); for(int i=start;i