📄 2a_echo.html
字号:
to throw a <a href="../../api/org/xml/sax/SAXException.html"><code>SAXException</code></a>.
An exception thrown here is sent back to the parser, which sends it on to the
code that invoked the parser. In the current program, that means it winds up
back at the <code>Throwable</code> exception handler at the bottom of the <code>main</code>
method. </p>
<p>When a start tag or end tag is encountered, the name of the tag is passed as
a String to the <code>startElement</code> or <code>endElement</code> method,
as appropriate. When a start tag is encountered, any attributes it defines are
also passed in an <a href="../../api/org/xml/sax/AttributeList.html"><code>AttributeList</code></a>.
Characters found within the element are passed as an array of characters, along
with the number of characters (<code>length</code>) and an offset into the array
that points to the first character.</p>
<h3><a name="writing"></a>Writing the Output</h3>
<p>The <code>DocumentHandler</code> methods throw <code>SAXException</code>s but
not <code>IOException</code>s, which can occur while writing. The <code>SAXException</code>
can wrap another exception, though, so it makes sense to do the output in a
method that takes care of the exception-handling details. Add the code highlighted
below to define an <code>emit</code> method that does that:</p>
<blockquote>
<pre>public void characters (char buf [], int offset, int Len)
throws SAXException
{
}
<b>private void emit (String s)
throws SAXException
{
try {
out.write (s);
out.flush ();
} catch (IOException e) {
throw new SAXException ("I/O error", e);
}
}
</b>...
</pre>
</blockquote>
<p>When emit is called, any I/O error is wrapped in <code>SAXException</code>
along with a message that identifies it. That exception is then thrown back
to the SAX parser. You'll learn more about SAX exceptions later on. For now,
keep in mind that <code>emit</code> is a small method that handles the string
output. (You'll see it called a lot in the code ahead.)</p>
<h4></h4>
<h3><a name="spacing"></a>Spacing the Output</h3>
<p>There is one last bit of infrastructure we need before doing some real processing.
Add the code highlighted below to define an <code>nl</code> method that writes
the kind of line-ending character used by the current system:</p>
<pre> private void emit (String s)
...
}
<b> private void nl ()
throws SAXException
{
String lineEnd = System.getProperty("line.separator");
try {
out.write (lineEnd);
} catch (IOException e) {
throw new SAXException ("I/O error", e);
}
</b> }
</pre>
<blockquote>
<p><b>Note: </b>Although it seems like a bit of a nuisance, you will be invoking
<code>nl()</code> many times in the code ahead. Defining it now will simplify
the code later on. It also provides a place to indent the output when we get
to that section of the tutorial.</p>
</blockquote>
<h3><a name="events"></a>Handling Document Events</h3>
<p>Finally, let's write some code that actually processes the <a href="../../api/org/xml/sax/DocumentHandler.html"><code>DocumentHandler</code></a>
events we added methods for.</p>
<p> Add the code highlighted below to handle the start-document and end-document
events:</p>
<pre> public void startDocument ()
throws SAXException
{
<b> emit ("<?xml version='1.0' encoding='UTF-8'?>");
nl();
</b> }
public void endDocument ()
throws SAXException
{
<b> try {
nl();
out.flush ();
} catch (IOException e) {
throw new SAXException ("I/O error", e);
}
</b> }
</pre>
<p> Here, you are echoing an XML declaration when the parser encounters the start
of the document. Since you set up the <code>OutputStreamWriter</code> using
the UTF-8 encoding, you include that specification as part of the declaration.</p>
<blockquote>
<p><b>Note: </b>However, the IO classes don't understand the hyphenated encoding
names, so you specified "UTF8" rather than "UTF-8".</p>
</blockquote>
<p>At the end of the document, you simply put out a final newline and flush the
output stream. Not much going on there. Now for the interesting stuff. Add the
code highlighted below to process the start-element and end-element events:</p>
<pre> public void startElement (String name, AttributeList attrs)
throws SAXException
{
<b> emit ("<"+name);
if (attrs != null) {
for (int i = 0; i < attrs.getLength (); i++) {
emit (" ");
emit (attrs.getName(i)+"=\""+attrs.getValue (i)+"\"");
}
}
emit (">");
</b> }
public void endElement (String name)
throws SAXException
{
<b> emit ("</"+name+">");
</b> }
</pre>
With this code, you echoed the element tags, including any attributes defined
in the start tag. To finish this version of the program, add the code highlighted
below to echo the characters the parser sees:<br>
<br>
<pre> public void characters (char buf [], int offset, int len)
throws SAXException
{
<b> String s = new String(buf, offset, len);
emit (s);
</b> }
</pre>
<p>Congratulations! You've just written a SAX parser application. The next step
is to compile and run it.</p>
<blockquote>
<p> <b>Note: </b>To be strictly accurate, the character handler should scan
the buffer for ampersand characters ('&') and left-angle bracket characters
('<') and replace them with the strings "<code>&amp;</code>"
or "<code>&lt;</code>", as appropriate. You'll find out more
about that kind of processing when we discuss entity references in <a href="4_refs.html">Substituting
and Inserting Text</a>. </p>
</blockquote>
<h3><a name="compiling"></a>Compiling the Program</h3>
<p>To compile the program you created, you'll execute the appropriate command
for your system (or use one of the command scripts mentioned below):</p>
<blockquote>
<p><b>Windows:</b></p>
<blockquote>
<pre>javac -classpath %XML_HOME%\jaxp.jar;%XML_HOME%\parser.jar Echo.java </pre>
</blockquote>
<p><b>Unix:</b></p>
<blockquote>
<pre>javac -classpath ${XML_HOME}/jaxp.jar:${XML_HOME}/parser.jar Echo.java </pre>
</blockquote>
<p>where:</p>
<ul>
<li> <code>XML_HOME</code> is where you installed the JAXP and Project X libraries.</li>
<li><tt>jaxp.jar</tt> contains the JAXP-specific APIs</li>
<li><tt>parser.jar</tt> contains the interfaces and classes that make up the
SAX and DOM APIs, as well as Sun's reference implementation, Project X.
</li>
</ul>
<p><b>Note:</b><br>
If you are using version 1.1 of the platform you also need to add <tt>%JAVA_HOME%\lib\classes.zip</tt>
to both the compile script and run script (below), where <code>JAVA_HOME</code>
is the location of the Java platform.</p>
</blockquote>
<h3><a name="running"></a>Running the Program</h3>
<p>To run the program, you'll once again execute the appropriate command for your
system (or use one of the command scripts mentioned below):</p>
<blockquote>
<p><b>Windows:</b></p>
<blockquote>
<pre>java -classpath .;%XML_HOME%\jaxp.jar;%XML_HOME%\parser.jar Echo slideSample.xml </pre>
</blockquote>
<p> <b>Unix:</b></p>
<blockquote>
<pre>java -classpath .:${XML_HOME}/jaxp.jar:${XML_HOME}/parser.jar Echo slideSample.xml </pre>
</blockquote>
</blockquote>
<h3><a name="scripts"></a>Command Scripts</h3>
<p>To make life easier, here are some command scripts you can use to compile and
run your apps as you work through this tutorial.<br>
</p>
<blockquote>
<table width="95%" border="1">
<tr>
<td width="22%"> </td>
<td width="29%"><i><b>Unix</b></i></td>
<td width="49%"><i><b>Windows</b></i></td>
</tr>
<tr>
<td width="22%">Scripts</td>
<td width="29%"><code><a href="../bin/build">build</a></code>, <a href="../bin/run"><code>run</code></a></td>
<td width="49%"><code><a href="../bin/build.bat">build.bat</a></code>, <code><a href="../bin/run.bat">run.bat</a></code></td>
</tr>
<tr>
<td width="22%">Netscape<br>
</td>
<td width="29%">Click, choose <b>File-->Save As</b></td>
<td width="49%">Right click, choose <b><br>
Save Link As</b>.</td>
</tr>
<tr>
<td width="22%">Internet<br>
Explorer </td>
<td width="29%">
<div align="center">-/-</div>
</td>
<td width="49%">Right click, choose <b>Save Target As</b>.</td>
</tr>
</table>
</blockquote>
<h3><a name="checking"></a>Checking the Output</h3>
<p>The program's output as stored in <a href="work/Echo01-01.log"><code>Echo01-01.log</code></a>.
Here is part of it, showing some of its weird-looking spacing:</p>
<blockquote>
<pre>...
<slideshow title="Sample Slide Show" date="Date of publication" author="Yours Truly">
<slide type="all">
<title>Wake up to WonderWidgets!</title>
</slide>
...</pre>
</blockquote>
<a name="LexicalEventListener"></a>Looking at this output, a number of questions
arise. Namely, where is the excess vertical whitespace coming from? And why is
it that the elements are indented properly, when the code isn't doing it? We'll
answer those questions in a moment. First, though, there are a few points to note
about the output:
<ul>
<li>The comment defined at the top of the file </li>
</ul>
<blockquote>
<pre><!-- A SAMPLE set of slides --></pre>
<p>does not appear in the listing. Comments are ignored by definition, unless
you implement a <a href="../../api/internal/com/sun/xml/parser/LexicalEventListener.html"><code>LexicalEventListener</code></a>
instead of a <code>DocumentHandler</code>. You'll see more about that later
on in this tutorial.</p>
</blockquote>
<ul>
<li>
<p>Element attributes are listed all together on a single line. If your window
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -