|
CSCI A348/548
|
import java.io.IOException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
// Import your vendor's XMLReader implementation here
//import org.apache.xerces.parsers.SAXParser;
/**
* <b><code>SAXParserDemo</code></b> will take an XML file and parse it
* using SAX, displaying the callbacks in the parsing lifecycle.
*
* @author
* <a href="mailto:brettmclaughlin@earthlink.net">Brett McLaughlin</a>
* @version 1.0
*/
public class SAXParserDemo {
/**
* <p>
* This parses the file, using registered SAX handlers, and outputs
* the events in the parsing process cycle.
* </p>
*
* @param uri <code>String</code> URI of file to parse.
*/
public void performDemo(String uri) {
System.out.println("Parsing XML File: " + uri + "\n\n");
// Get instances of our handlers
ContentHandler contentHandler = new MyContentHandler();
ErrorHandler errorHandler = new MyErrorHandler();
try {
// Instantiate a parser
XMLReader parser =
XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser");
// Register the content handler
parser.setContentHandler(contentHandler);
// Register the error handler
parser.setErrorHandler(errorHandler);
// Parse the document
parser.parse(uri);
} catch (IOException e) {
System.out.println("Error reading URI: " + e.getMessage());
} catch (SAXException e) {
System.out.println("Error in parsing: " + e.getMessage());
}
}
/**
* <p>
* This provides a command-line entry point for this demo.
* </p>
*/
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: java SAXParserDemo [XML URI]");
System.exit(0);
}
String uri = args[0];
SAXParserDemo parserDemo = new SAXParserDemo();
parserDemo.performDemo(uri);
}
}
/**
* <b><code>MyContentHandler</code></b> implements the SAX
* <code>ContentHandler</code> interface and defines callback
* behavior for the SAX callbacks associated with an XML
* document's content.
*/
class MyContentHandler implements ContentHandler {
/** Hold onto the locator for location information */
private Locator locator;
/**
* <p>
* Provide reference to <code>Locator</code> which provides
* information about where in a document callbacks occur.
* </p>
*
* @param locator <code>Locator</code> object tied to callback
* process
*/
public void setDocumentLocator(Locator locator) {
System.out.println(" * setDocumentLocator() called");
// We save this for later use if desired.
this.locator = locator;
}
/**
* <p>
* This indicates the start of a Document parse—this precedes
* all callbacks in all SAX Handlers with the sole exception
* of <code>{@link #setDocumentLocator}</code>.
* </p>
*
* @throws <code>SAXException</code> when things go wrong
*/
public void startDocument() throws SAXException {
System.out.println("Parsing begins...");
}
/**
* <p>
* This indicates the end of a Document parse—this occurs after
* all callbacks in all SAX Handlers.</code>.
* </p>
*
* @throws <code>SAXException</code> when things go wrong
*/
public void endDocument() throws SAXException {
System.out.println("...Parsing ends.");
}
/**
* <p>
* This indicates that a processing instruction (other than
* the XML declaration) has been encountered.
* </p>
*
* @param target <code>String</code> target of PI
* @param data <code>String</code containing all data sent to the PI.
* This typically looks like one or more attribute value
* pairs.
* @throws <code>SAXException</code> when things go wrong
*/
public void processingInstruction(String target, String data)
throws SAXException {
System.out.println("PI: Target:" + target + " and Data:" + data);
}
/**
* <p>
* This indicates the beginning of an XML Namespace prefix
* mapping. Although this typically occurs within the root element
* of an XML document, it can occur at any point within the
* document. Note that a prefix mapping on an element triggers
* this callback <i>before</i> the callback for the actual element
* itself (<code>{@link #startElement}</code>) occurs.
* </p>
*
* @param prefix <code>String</code> prefix used for the namespace
* being reported
* @param uri <code>String</code> URI for the namespace
* being reported
* @throws <code>SAXException</code> when things go wrong
*/
public void startPrefixMapping(String prefix, String uri) {
System.out.println("Mapping starts for prefix " + prefix +
" mapped to URI " + uri);
}
/**
* <p>
* This indicates the end of a prefix mapping, when the namespace
* reported in a <code>{@link #startPrefixMapping}</code> callback
* is no longer available.
* </p>
*
* @param prefix <code>String</code> of namespace being reported
* @throws <code>SAXException</code> when things go wrong
*/
public void endPrefixMapping(String prefix) {
System.out.println("Mapping ends for prefix " + prefix);
}
/**
* <p>
* This reports the occurrence of an actual element. It includes
* the element's attributes, with the exception of XML vocabulary
* specific attributes, such as
* <code>xmlns:[namespace prefix]</code> and
* <code>xsi:schemaLocation</code>.
* </p>
*
* @param namespaceURI <code>String</code> namespace URI this element
* is associated with, or an empty <code>String</code>
* @param localName <code>String</code> name of element (with no
* namespace prefix, if one is present)
* @param rawName <code>String</code> XML 1.0 version of element name:
* [namespace prefix]:[localName]
* @param atts <code>Attributes</code> list for this element
* @throws <code>SAXException</code> when things go wrong
*/
public void startElement(String namespaceURI, String localName,
String rawName, Attributes atts)
throws SAXException {
System.out.print("startElement: " + localName);
if (!namespaceURI.equals("")) {
System.out.println(" in namespace " + namespaceURI +
" (" + rawName + ")");
} else {
System.out.println(" has no associated namespace");
}
for (int i=0; i<atts.getLength(); i++) {
System.out.println(" Attribute: " + atts.getLocalName(i) +
"=" + atts.getValue(i));
}
}
/**
* <p>
* Indicates the end of an element
* (<code></[element name]></code>) is reached. Note that
* the parser does not distinguish between empty
* elements and non-empty elements, so this occurs uniformly.
* </p>
*
* @param namespaceURI <code>String</code> URI of namespace this
* element is associated with
* @param localName <code>String</code> name of element without prefix
* @param rawName <code>String</code> name of element in XML 1.0 form
* @throws <code>SAXException</code> when things go wrong
*/
public void endElement(String namespaceURI, String localName,
String rawName)
throws SAXException {
System.out.println("endElement: " + localName + "\n");
}
/**
* <p>
* This reports character data (within an element).
* </p>
*
* @param ch <code>char[]</code> character array with character data
* @param start <code>int</code> index in array where data starts.
* @param end <code>int</code> index in array where data ends.
* @throws <code>SAXException</code> when things go wrong
*/
public void characters(char[] ch, int start, int end)
throws SAXException {
String s = new String(ch, start, end);
System.out.println("characters: " + s);
}
/**
* <p>
* This reports whitespace that can be ignored in the
* originating document. This is typically invoked only when
* validation is ocurring in the parsing process.
* </p>
*
* @param ch <code>char[]</code> character array with character data
* @param start <code>int</code> index in array where data starts.
* @param end <code>int</code> index in array where data ends.
* @throws <code>SAXException</code> when things go wrong
*/
public void ignorableWhitespace(char[] ch, int start, int end)
throws SAXException {
String s = new String(ch, start, end);
System.out.println("ignorableWhitespace: [" + s + "]");
}
/**
* <p>
* This reports an entity that is skipped by the parser. This
* should only occur for non-validating parsers, and then is still
* implementation-dependent behavior.
* </p>
*
* @param name <code>String</code> name of entity being skipped
* @throws <code>SAXException</code> when things go wrong
*/
public void skippedEntity(String name) throws SAXException {
System.out.println("Skipping entity " + name);
}
}
/**
* <b><code>MyErrorHandler</code></b> implements the SAX
* <code>ErrorHandler</code> interface and defines callback
* behavior for the SAX callbacks associated with an XML
* document's errors.
*/
class MyErrorHandler implements ErrorHandler {
/**
* <p>
* This will report a warning that has occurred; this indicates
* that while no XML rules were broken, something appears
* to be incorrect or missing.
* </p>
*
* @param exception <code>SAXParseException</code> that occurred.
* @throws <code>SAXException</code> when things go wrong
*/
public void warning(SAXParseException exception)
throws SAXException {
System.out.println("**Parsing Warning**\n" +
" Line: " +
exception.getLineNumber() + "\n" +
" URI: " +
exception.getSystemId() + "\n" +
" Message: " +
exception.getMessage());
throw new SAXException("Warning encountered");
}
/**
* <p>
* This will report an error that has occurred; this indicates
* that a rule was broken, typically in validation, but that
* parsing can reasonably continue.
* </p>
*
* @param exception <code>SAXParseException</code> that occurred.
* @throws <code>SAXException</code> when things go wrong
*/
public void error(SAXParseException exception)
throws SAXException {
System.out.println("**Parsing Error**\n" +
" Line: " +
exception.getLineNumber() + "\n" +
" URI: " +
exception.getSystemId() + "\n" +
" Message: " +
exception.getMessage());
throw new SAXException("Error encountered");
}
/**
* <p>
* This will report a fatal error that has occurred; this indicates
* that a rule has been broken that makes continued parsing either
* impossible or an almost certain waste of time.
* </p>
*
* @param exception <code>SAXParseException</code> that occurred.
* @throws <code>SAXException</code> when things go wrong
*/
public void fatalError(SAXParseException exception)
throws SAXException {
System.out.println("**Parsing Fatal Error**\n" +
" Line: " +
exception.getLineNumber() + "\n" +
" URI: " +
exception.getSystemId() + "\n" +
" Message: " +
exception.getMessage());
throw new SAXException("Fatal Error encountered");
}
}
and place it somewhere in your directory.
I'd keep it in ~/xml or something similar.
Now compile it.
If you can't, you need some .jar files.
Take all of these files:
Place them where you can access them and point your CLASSPATH to them.burrowww.cs.indiana.edu% ls /u/dgerman/xalan/*.jar /u/dgerman/xalan/ant.jar /u/dgerman/xalan/xalanjdoc.jar /u/dgerman/xalan/bsf.jar /u/dgerman/xalan/xalansamples.jar /u/dgerman/xalan/stylebook-1.0-b2.jar /u/dgerman/xalan/xerces.jar burrowww.cs.indiana.edu%
I'd put all of them in $TOMCAT_HOME/lib or similar.
Then change your ~/.cshrc to update your CLASSPATH.
After you compile it, try to parse the output of mysetenv CLASSPATH .:$TOMCAT_HOME/lib/servlet.jar setenv CLASSPATH $TOMCAT_HOME/lib/xalan.jar:$CLASSPATH setenv CLASSPATH $TOMCAT_HOME/lib/xerces.jar:$CLASSPATH setenv CLASSPATH $TOMCAT_HOME/lib/ant.jar:$CLASSPATH setenv CLASSPATH $TOMCAT_HOME/lib/bsf.jar:$CLASSPATH setenv CLASSPATH $TOMCAT_HOME/lib/stylebook-1.0-b2.jar:$CLASSPATH setenv CLASSPATH $TOMCAT_HOME/lib/xalanjdoc.jar:$CLASSPATH
supplyBooks.pl as follows:
Let's make a servlet out of it.burrowww.cs.indiana.edu% java SAXParserDemo http://burrowww.cs.indiana.edu:20006/cgi-bin/supplyBooks.pl Parsing XML File: http://burrowww.cs.indiana.edu:20006/cgi-bin/supplyBooks.pl ^Cburrowww.cs.indiana.edu%
Start with:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MTBDC extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head><title>Books, books!</title></head>" +
"<BODY>\n" +
"<H1>You want books?</H1>\n" +
"</BODY></HTML>");
}
}
Compile and run this, first. Once it runs, change it a bit.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MTBDC extends HttpServlet {
PrintWriter out;
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
out = response.getWriter();
out.println("<html><head><title>Books, yes!" +
"</title></head><BODY>\n<pre>");
out.println("</pre></BODY></HTML>");
}
}
Bring SAXParserDemo in the same place, and change it.
import java.io.*;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
// Import your vendor's XMLReader implementation here
//import org.apache.xerces.parsers.SAXParser;
/**
* <b><code>SAXParserDemo</code></b> will take an XML file and parse it
* using SAX, displaying the callbacks in the parsing lifecycle.
*
* @author
* <a href="mailto:brettmclaughlin@earthlink.net">Brett McLaughlin</a>
* @version 1.0
*/
public class SAXParserDemo {
PrintWriter out;
public SAXParserDemo(PrintWriter out) {
this.out = out;
}
/**
* <p>
* This parses the file, using registered SAX handlers, and outputs
* the events in the parsing process cycle.
* </p>
*
* @param uri <code>String</code> URI of file to parse.
*/
public void performDemo(String uri) {
out.println("Parsing XML File: " + uri + "\n\n");
// Get instances of our handlers
ContentHandler contentHandler = new MyContentHandler(out);
ErrorHandler errorHandler = new MyErrorHandler(out);
try {
// Instantiate a parser
XMLReader parser =
XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser");
// Register the content handler
parser.setContentHandler(contentHandler);
// Register the error handler
parser.setErrorHandler(errorHandler);
// Parse the document
parser.parse(uri);
} catch (IOException e) {
out.println("Error reading URI: " + e.getMessage());
} catch (SAXException e) {
out.println("Error in parsing: " + e.getMessage());
}
}
/**
* <p>
* This provides a command-line entry point for this demo.
* </p>
*/
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: java SAXParserDemo [XML URI]");
System.exit(0);
}
String uri = args[0];
SAXParserDemo parserDemo = new SAXParserDemo(
new PrintWriter(System.out)
);
parserDemo.performDemo(uri);
}
}
/**
* <b><code>MyContentHandler</code></b> implements the SAX
* <code>ContentHandler</code> interface and defines callback
* behavior for the SAX callbacks associated with an XML
* document's content.
*/
class MyContentHandler implements ContentHandler {
PrintWriter out;
public MyContentHandler(PrintWriter out) {
this.out = out;
}
/** Hold onto the locator for location information */
private Locator locator;
/**
* <p>
* Provide reference to <code>Locator</code> which provides
* information about where in a document callbacks occur.
* </p>
*
* @param locator <code>Locator</code> object tied to callback
* process
*/
public void setDocumentLocator(Locator locator) {
out.println(" * setDocumentLocator() called");
// We save this for later use if desired.
this.locator = locator;
}
/**
* <p>
* This indicates the start of a Document parse—this precedes
* all callbacks in all SAX Handlers with the sole exception
* of <code>{@link #setDocumentLocator}</code>.
* </p>
*
* @throws <code>SAXException</code> when things go wrong
*/
public void startDocument() throws SAXException {
out.println("Parsing begins...");
}
/**
* <p>
* This indicates the end of a Document parse—this occurs after
* all callbacks in all SAX Handlers.</code>.
* </p>
*
* @throws <code>SAXException</code> when things go wrong
*/
public void endDocument() throws SAXException {
out.println("...Parsing ends.");
}
/**
* <p>
* This indicates that a processing instruction (other than
* the XML declaration) has been encountered.
* </p>
*
* @param target <code>String</code> target of PI
* @param data <code>String</code containing all data sent to the PI.
* This typically looks like one or more attribute value
* pairs.
* @throws <code>SAXException</code> when things go wrong
*/
public void processingInstruction(String target, String data)
throws SAXException {
out.println("PI: Target:" + target + " and Data:" + data);
}
/**
* <p>
* This indicates the beginning of an XML Namespace prefix
* mapping. Although this typically occurs within the root element
* of an XML document, it can occur at any point within the
* document. Note that a prefix mapping on an element triggers
* this callback <i>before</i> the callback for the actual element
* itself (<code>{@link #startElement}</code>) occurs.
* </p>
*
* @param prefix <code>String</code> prefix used for the namespace
* being reported
* @param uri <code>String</code> URI for the namespace
* being reported
* @throws <code>SAXException</code> when things go wrong
*/
public void startPrefixMapping(String prefix, String uri) {
out.println("Mapping starts for prefix " + prefix +
" mapped to URI " + uri);
}
/**
* <p>
* This indicates the end of a prefix mapping, when the namespace
* reported in a <code>{@link #startPrefixMapping}</code> callback
* is no longer available.
* </p>
*
* @param prefix <code>String</code> of namespace being reported
* @throws <code>SAXException</code> when things go wrong
*/
public void endPrefixMapping(String prefix) {
out.println("Mapping ends for prefix " + prefix);
}
/**
* <p>
* This reports the occurrence of an actual element. It includes
* the element's attributes, with the exception of XML vocabulary
* specific attributes, such as
* <code>xmlns:[namespace prefix]</code> and
* <code>xsi:schemaLocation</code>.
* </p>
*
* @param namespaceURI <code>String</code> namespace URI this element
* is associated with, or an empty <code>String</code>
* @param localName <code>String</code> name of element (with no
* namespace prefix, if one is present)
* @param rawName <code>String</code> XML 1.0 version of element name:
* [namespace prefix]:[localName]
* @param atts <code>Attributes</code> list for this element
* @throws <code>SAXException</code> when things go wrong
*/
public void startElement(String namespaceURI, String localName,
String rawName, Attributes atts)
throws SAXException {
out.print("startElement: " + localName);
if (!namespaceURI.equals("")) {
out.println(" in namespace " + namespaceURI +
" (" + rawName + ")");
} else {
out.println(" has no associated namespace");
}
for (int i=0; i<atts.getLength(); i++) {
out.println(" Attribute: " + atts.getLocalName(i) +
"=" + atts.getValue(i));
}
}
/**
* <p>
* Indicates the end of an element
* (<code></[element name]></code>) is reached. Note that
* the parser does not distinguish between empty
* elements and non-empty elements, so this occurs uniformly.
* </p>
*
* @param namespaceURI <code>String</code> URI of namespace this
* element is associated with
* @param localName <code>String</code> name of element without prefix
* @param rawName <code>String</code> name of element in XML 1.0 form
* @throws <code>SAXException</code> when things go wrong
*/
public void endElement(String namespaceURI, String localName,
String rawName)
throws SAXException {
out.println("endElement: " + localName + "\n");
}
/**
* <p>
* This reports character data (within an element).
* </p>
*
* @param ch <code>char[]</code> character array with character data
* @param start <code>int</code> index in array where data starts.
* @param end <code>int</code> index in array where data ends.
* @throws <code>SAXException</code> when things go wrong
*/
public void characters(char[] ch, int start, int end)
throws SAXException {
String s = new String(ch, start, end);
out.println("characters: " + s);
}
/**
* <p>
* This reports whitespace that can be ignored in the
* originating document. This is typically invoked only when
* validation is ocurring in the parsing process.
* </p>
*
* @param ch <code>char[]</code> character array with character data
* @param start <code>int</code> index in array where data starts.
* @param end <code>int</code> index in array where data ends.
* @throws <code>SAXException</code> when things go wrong
*/
public void ignorableWhitespace(char[] ch, int start, int end)
throws SAXException {
String s = new String(ch, start, end);
out.println("ignorableWhitespace: [" + s + "]");
}
/**
* <p>
* This reports an entity that is skipped by the parser. This
* should only occur for non-validating parsers, and then is still
* implementation-dependent behavior.
* </p>
*
* @param name <code>String</code> name of entity being skipped
* @throws <code>SAXException</code> when things go wrong
*/
public void skippedEntity(String name) throws SAXException {
out.println("Skipping entity " + name);
}
}
/**
* <b><code>MyErrorHandler</code></b> implements the SAX
* <code>ErrorHandler</code> interface and defines callback
* behavior for the SAX callbacks associated with an XML
* document's errors.
*/
class MyErrorHandler implements ErrorHandler {
PrintWriter out;
public MyErrorHandler(PrintWriter out) {
this.out = out;
}
/**
* <p>
* This will report a warning that has occurred; this indicates
* that while no XML rules were broken, something appears
* to be incorrect or missing.
* </p>
*
* @param exception <code>SAXParseException</code> that occurred.
* @throws <code>SAXException</code> when things go wrong
*/
public void warning(SAXParseException exception)
throws SAXException {
out.println("**Parsing Warning**\n" +
" Line: " +
exception.getLineNumber() + "\n" +
" URI: " +
exception.getSystemId() + "\n" +
" Message: " +
exception.getMessage());
throw new SAXException("Warning encountered");
}
/**
* <p>
* This will report an error that has occurred; this indicates
* that a rule was broken, typically in validation, but that
* parsing can reasonably continue.
* </p>
*
* @param exception <code>SAXParseException</code> that occurred.
* @throws <code>SAXException</code> when things go wrong
*/
public void error(SAXParseException exception)
throws SAXException {
out.println("**Parsing Error**\n" +
" Line: " +
exception.getLineNumber() + "\n" +
" URI: " +
exception.getSystemId() + "\n" +
" Message: " +
exception.getMessage());
throw new SAXException("Error encountered");
}
/**
* <p>
* This will report a fatal error that has occurred; this indicates
* that a rule has been broken that makes continued parsing either
* impossible or an almost certain waste of time.
* </p>
*
* @param exception <code>SAXParseException</code> that occurred.
* @throws <code>SAXException</code> when things go wrong
*/
public void fatalError(SAXParseException exception)
throws SAXException {
out.println("**Parsing Fatal Error**\n" +
" Line: " +
exception.getLineNumber() + "\n" +
" URI: " +
exception.getSystemId() + "\n" +
" Message: " +
exception.getMessage());
throw new SAXException("Fatal Error encountered");
}
}
Then use it in the servlet.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MTBDC extends HttpServlet {
PrintWriter out;
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
out = response.getWriter();
out.println("<html><head><title>Books, yes!" +
"</title></head><BODY>\n<pre>");
String uri = "http://burrowww.cs.indiana.edu" +
":20006/cgi-bin/supplyBooks.pl";
SAXParserDemo parserDemo = new SAXParserDemo(out);
parserDemo.performDemo(uri);
out.println("</pre></BODY></HTML>");
}
}
The communication link is established. Now we need to improve the output to make it like this.
A348/A548