📄 3_error.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Handling Errors with the Non-Validating Parser</title>
<style type="text/css">
</style></head>
<body BGCOLOR="#ffffff">
<table width="100%">
<tr>
<td align=left> <a href="2b_echo.html"><img src="../images/PreviousArrow.gif" width=26 height=26 align=bottom border=0 alt="Previous | "></a><a
href="4_refs.html"><img src="../images/NextArrow.gif" width=26 height=26 align=bottom border=0 alt="Next | "></a><a href="../alphaIndex.html"><img src="../images/xml_IDX.gif" width=26 height=26 align=bottom border=0 alt="Index | "></a><a href="../TOC.html"><img
src="../images/xml_TOC.gif" width=26 height=26 align=bottom border=0 alt="TOC | "></a><a href="../index.html"><img
src="../images/xml_Top.gif" width=26 height=26 align=bottom border=0 alt="Top | "></a>
</td>
<td align=right><strong><em><a href="index.html">Top</a></em></strong> <a href="../TOC.html#intro"><strong><em>Contents</em></strong></a> <a href="../alphaIndex.html"><strong><em>Index</em></strong></a> <a href="../glossary.html"><strong><em>Glossary</em></strong></a>
</td>
</tr>
</table>
<p>
<center>
<IMG SRC="../images/shoeline2.gif" ALIGN="BOTTOM" BORDER="0" WIDTH="202"
HEIGHT="25" NATURALSIZEFLAG="3"> <IMG SRC="../images/shoeline2.gif" ALIGN="BOTTOM" BORDER="0" WIDTH="202"
HEIGHT="25" NATURALSIZEFLAG="3">
</center>
<blockquote>
<blockquote>
<hr size=4>
</blockquote>
</blockquote>
<h2>3. Handling Errors with the Nonvalidating Parser</h2>
<table width="40%" border="1" align="right">
<tr>
<td>
<div align="center"><b><i>Link Summary</i></b></div>
</td>
</tr>
<tr>
<td>
<dl>
<dt><b><i>Exercises</i></b></dt>
</dl>
<ul>
<li><a href="samples/slideSampleBad1.xml">slideSampleBad1.xml</a> </li>
<li><a href="work/Echo05-Bad1.log">Echo05-Bad1.log</a></li>
<li><a href="work/Echo06.java">Echo06.java</a></li>
<li><a href="work/Echo06-Bad1.log">Echo06-Bad1.log</a></li>
<li><a href="samples/slideSampleBad2.xml">slideSampleBad2.xml</a></li>
<li><a href="work/Echo06-Bad2.log">Echo06-Bad2.log</a></li>
<li><a href="work/Echo07.java">Echo07.java</a></li>
<li><a href="work/Echo07-Bad2.log">Echo07-Bad2.log</a></li>
</ul>
<p><b><i>API Links</i></b></p>
<ul>
<li><a href="../../api/org/xml/sax/DocumentHandler.html">DocumentHandler</a></li>
<li><a href="../../api/internal/com/sun/xml/parser/ValidatingParser.html">ValidatingParser</a></li>
<li><a href="../../api/org/xml/sax/ErrorHandler.html">ErrorHandler</a></li>
<li><a href="../../api/org/xml/sax/HandlerBase.html">HandlerBase</a></li>
</ul>
<p><b><i>Glossary Terms</i></b></p>
<dl>
<dd><a href="../glossary.html#DTD">DTD</a>, <a href="../glossary.html#error">error</a>,
<a href="../glossary.html#fatalError">fatal error</a>, <a href="../glossary.html#valid">valid</a>,
<a href="../glossary.html#warning">warning</a>, <a href="../glossary.html#wellFormed">well-formed</a>
</dd>
</dl>
</td>
</tr>
</table>
<p>This version of the Echo program uses the nonvalidating parser. So it can't
tell if the XML document contains the right tags, or if those tags are in the
right sequence. In other words, it can't tell you if the document is <a href="../glossary.html#valid">valid</a>.
It can, however, tell whether or not the document is <a href="../glossary.html#wellFormed">well-formed</a>.
<p> In this section of the tutorial, you'll modify the slideshow file to generate
different kinds of errors and see how the parser handles them. You'll also find
out which error conditions are ignored, by default, and see how to handle them.
<h3><a name="introducing"></a>Introducing an Error</h3>
<p>The parser can generate one of three kinds of errors: <a href="../glossary.html#fatalError">fatal
error</a>, <a href="../glossary.html#error">error</a>, and <a href="../glossary.html#warning">warning</a>.
In this exercise, you'll make a simple modification to the XML file to introduce
a fatal error. Then you'll see how it's handled in the Echo app.</p>
<blockquote>
<p><b>Note:</b> The XML structure you'll create in this exercise is in <a href="samples/slideSampleBad1.xml"><code>slideSampleBad1.xml</code></a>.
The output is in <a href="work/Echo05-Bad1.log"><code>Echo05-Bad1.log</code></a>.</p>
</blockquote>
<p> One easy way to introduce a fatal error is to remove the final "<code>/</code>"
from the empty <code>item</code> element to create a tag that does not have
a corresponding end tag. That constitutes a fatal error, because all XML documents
must, by definition, be well formed. Do the following:</p>
<ol>
<li>
<p>Copy <code>slideSample.xml</code> to <code>badSample.xml</code>.</p>
</li>
<li>Edit <code>badSample.xml</code> and remove the character shown below:</li>
<pre> ...
<!-- OVERVIEW -->
<slide type="all">
<title>Overview</title>
<item>Why <em>WonderWidgets</em> are great</item>
<item<b><s>/</s></b>>
<item>Who <em>buys</em> WonderWidgets</item>
</slide>
...
</pre>
<p>to produce:</p>
<pre> ...
<item>Why <em>WonderWidgets</em> are great</item>
<item<b></b>>
<item>Who <em>buys</em> WonderWidgets</item>
...</pre>
<li>Run the Echo program on the new file. <br>
</ol>
<p>The output you get now looks like this:</p>
<blockquote>
<pre>...
ELEMENT: <item>
CHARS: The
ELEMENT: <em>
CHARS: Only
END_ELM: </em>
CHARS: Section
END_ELM: </item>
CHARS:
END_ELM:
CHARS: <b>org.xml.sax.SAXParseException: Expected "</item>"
to terminate element starting on line 20.</b>
at com.sun.xml.parser.Parser.fatal(Parser.java:2800)
at com.sun.xml.parser.Parser.fatal(Parser.java:2794)
at com.sun.xml.parser.Parser.maybeElement(Parser.java:1406)
at com.sun.xml.parser.Parser.content(Parser.java:1499)
at com.sun.xml.parser.Parser.maybeElement(Parser.java:1400)
at com.sun.xml.parser.Parser.content(Parser.java:1499)
at com.sun.xml.parser.Parser.maybeElement(Parser.java:1400)
at com.sun.xml.parser.Parser.parseInternal(Parser.java:492)
at com.sun.xml.parser.Parser.parse(Parser.java:284)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:168)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:104)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:131)
at Echo05.main(Echo05.java:59)</pre>
</blockquote>
<p>When a fatal error occurs, the parser is unable to continue. So, if the application
does not generate an exception (which you'll see how to do a moment), then the
default error-event handler generates one. The stack trace is generated by the
<code>Throwable</code> exception handler in your main method:</p>
<blockquote>
<pre>
...
} catch (Throwable t) {
<b>t.printStackTrace ();</b>
}
</pre>
</blockquote>
<p>That stack trace is not too useful, though. Next, you'll see how to generate
better diagnostics when an error occurs.</p>
<h3><a name="SAXParseException"></a>Handling a SAXParseException</h3>
<p>When the error was encountered, the parser generated a <code>SAXParseException</code>
-- a subclass of <code>SAXException</code> that identifies the file and location
where the error occurred. </p>
<blockquote>
<p><b>Note:</b> The code you'll create in this exercise is in <a href="work/Echo06.java"><code>Echo06.java</code></a>.
The output is in <a href="work/Echo06-Bad1.log"><code>Echo06-Bad1.log</code></a>.</p>
</blockquote>
<p>Add the code highlighted below to generate a better diagnostic message when
the exception occurs: </p>
<blockquote>
<pre><b> ...
} catch (SAXParseException spe) {
// Error generated by the parser
System.out.println ("\n** Parsing error"
+ ", line " + spe.getLineNumber ()
+ ", uri " + spe.getSystemId ());
System.out.println(" " + spe.getMessage() );
</b>} catch (Throwable t) {
t.printStackTrace ();
}
</pre>
</blockquote>
<p>Running the program now generates an error message which is a bit more helpful,
like this:</p>
<blockquote>
<pre>** Parsing error, line 22, uri file:<i><path></i>/slideSampleBad1.xml
Next character must be...
</pre>
<b>Note:<br>
</b>Catching all throwables like this is <i>not</i> a good idea for production
applications.<b> </b>We're just doing it now so we can build up to full error
handling gradually.<b><br>
</b></blockquote>
<h3><a name="SAXException"></a>Handling a SAXException</h3>
<p>A more general <code>SAXException</code> instance may sometimes be generated
by the parser, but it more frequently occurs when an error originates in one
of application's event handling methods. For example, the signature of the <code>startDocument</code>
method in the <a href="../../api/org/xml/sax/DocumentHandler.html"><code>DocumentHandler</code></a>
interface is defined as returning a <code>SAXException</code>: </p>
<blockquote>
<pre>public void startDocument () <b>throws SAXException</b></pre>
</blockquote>
<p>All of the <code>DocumentHandler</code> methods (except for <code>setDocumentLocator</code>)
have that signature declaration.</p>
<p>A <code>SAXException</code> can be constructed using a message, another exception,
or both. So, for example, when <code>Echo.startDocument</code> outputs a string
using the <code>emit</code> method, any I/O exception that occurs is wrapped
in a <code>SAXException</code> and sent back to the parser:</p>
<blockquote>
<pre>private void emit (String s)
<b>throws SAXException</b>
{
try {
out.write (s);
out.flush ();
} <b>catch (IOException e)</b> {
<b> throw new SAXException ("I/O error", e);</b>
}
}
</pre>
<p><b>Note: </b>If you saved the <code>Locator</code> object when <code>setDocumentLocator</code>
was invoked, you could use it to generate a <code>SAXParseException</code>,
identifying the document and location, instead of generating a <code>SAXException</code>.</p>
</blockquote>
<p>When the parser delivers the exception back to the code that invoked the parser,
it makes sense to use the original exception to generate the stack trace. Add
the code highlighted below to do that:</p>
<blockquote>
<pre>
...
} catch (SAXParseException err) {
System.out.println ("** Parsing error"
+ ", line " + err.getLineNumber ()
+ ", uri " + err.getSystemId ());
System.out.println(" " + err.getMessage ());
<b>} catch (SAXException sxe) {
// Error generated by this application
// (or a parser-initialization error)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -