📄 jaxpsax3.html
字号:
emit("START DOCUMENT"); nl(); </code> emit("<?xml version='1.0' encoding='UTF-8'?>");<code class="cCodeStruck"> nl();</code>}public void endDocument()throws SAXException{<code class="cCodeBold"> nl(); emit("END DOCUMENT");</code> try { ...}public void startElement(...)throws SAXException{ echoText(); <code class="cCodeBold">nl(); emit("ELEMENT: ");</code> String eName = sName; // element name if ("".equals(eName)) eName = qName; // not namespaceAware emit("<"+eName); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String aName = attrs.getLocalName(i); // Attr name if ("".equals(aName)) aName = attrs.getQName(i);<code class="cCodeStruck"> emit(" "); emit(aName+"=\""+attrs.getValue(i)+"\"");</code> <code class="cCodeBold">nl(); emit(" ATTR: "); emit(aName); emit("\t\""); emit(attrs.getValue(i)); emit("\"");</code> } } <code class="cCodeBold">if (attrs.getLength() > 0) nl();</code> emit(">");}<a name="wp67644"> </a>public void endElement(...)throws SAXException{ echoText(); <code class="cCodeBold">nl(); emit("END_ELM: ");</code> String eName = sName; // element name if ("".equals(eName)) eName = qName; // not namespaceAware emit("<"+eName+">");}...<a name="wp71619"> </a>private void echoText()throws SAXException{ if (textBuffer == null) return; <code class="cCodeBold">nl(); emit("CHARS: |"); </code> String s = ""+textBuffer; emit(s); <code class="cCodeBold">emit("|");</code> textBuffer = null;}<a name="wp71624"> </a></pre></div><a name="wp64350"> </a><p class="pBody">Compile and run this version of the program to produce a more informative output listing. The attributes are now shown one per line, which is nice. But, more importantly, output lines like this one:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> <code class="cCode">CHARS: |</code>|<a name="wp71712"> </a></pre></div><a name="wp71713"> </a><p class="pBody">show that both the indentation space and the newlines that separate the attributes come from the data that the parser passes to the <code class="cCode">characters()</code> method.</p><hr><a name="wp64355"> </a><p class="pNote">Note: The XML specification requires all input line separators to be normalized to a single newline. The newline character is specified as in Java, C, and UNIX systems, but goes by the alias "linefeed" in Windows systems.</p><hr><a name="wp64357"> </a><h3 class="pHeading2">Compressing the Output</h3><a name="wp64358"> </a><p class="pBody">To make the output more readable, modify the program so that it only outputs characters containing something other than whitespace.</p><hr><a name="wp64359"> </a><p class="pNote">Note: The code discussed in this section is in <code class="cCode"><a href="../examples/jaxp/sax/samples/Echo03.java" target="_blank">Echo03.java</a></code>. </p><hr><a name="wp64360"> </a><p class="pBody">Make the changes shown below to suppress output of characters that are all whitespace:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public void echoText()throws SAXException{ nl(); <code class="cCodeStruck">emit("CHARS: |");</code><code class="cCodeBold"> emit("CHARS: ");</code> String s = ""+textBuffer; <code class="cCodeBold">if (!s.trim().equals("")) </code>emit(s);<code class="cCodeStruck"> emit("|");</code>}<a name="wp64361"> </a></pre></div><a name="wp64362"> </a><p class="pBody">Next, add the code highlighted below to echo each set of characters delivered by the parser:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public void characters(char buf[], int offset, int len)throws SAXException{ <code class="cCodeBold">if (textBuffer != null) { echoText(); textBuffer = null; }</code> String s = new String(buf, offset, len); ...}<a name="wp71811"> </a></pre></div><a name="wp71794"> </a><p class="pBody">If you run the program now, you will see that you have eliminated the indentation as well, because the indent space is part of the whitespace that precedes the start of an element. Add the code highlighted below to manage the indentation:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">static private Writer out;<a name="wp64363"> </a><code class="cCodeBold">private String indentString = " "; // Amount to indentprivate int indentLevel = 0;</code>...<a name="wp64364"> </a>public void startElement(...)throws SAXException{ <code class="cCodeBold">indentLevel++;</code> nl(); emit("ELEMENT: "); ...}<a name="wp64365"> </a>public void endElement(...)throws SAXException{ nl(); emit("END_ELM: "); emit("</"+sName+">"); <code class="cCodeBold">indentLevel--;</code>}...private void nl()throws SAXException{ ... try { out.write(lineEnd); <code class="cCodeBold">for (int i=0; i < indentLevel; i++) out.write(indentString);</code> } catch (IOException e) { ... }<a name="wp67702"> </a></pre></div><a name="wp64368"> </a><p class="pBody">This code sets up an indent string, keeps track of the current indent level, and outputs the indent string whenever the <code class="cCode">nl</code> method is called. If you set the indent string to "", the output will be un-indented (Try it. You'll see why it's worth the work to add the indentation.)</p><a name="wp64369"> </a><p class="pBody">You'll be happy to know that you have reached the end of the "mechanical" code you have to add to the Echo program. From here on, you'll be doing things that give you more insight into how the parser works. The steps you've taken so far, though, have given you a lot of insight into how the parser sees the XML data it processes. It's also given you a helpful debugging tool you can use to see what the parser sees.</p><a name="wp64371"> </a><h3 class="pHeading2">Inspecting the Output</h3><a name="wp64372"> </a><p class="pBody">There is part of the output from this version of the program:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">ELEMENT: <slideshow...>CHARS: CHARS: ELEMENT: <slide ... END_ELM: </slide>CHARS: CHARS: <a name="wp64373"> </a></pre></div><hr><a name="wp64374"> </a><p class="pNote">Note: The complete output is <code class="cCode"><a href="../examples/jaxp/sax/samples/Echo03-01.txt" target="_blank">Echo03-01.txt</a></code>. (The browsable version is <code class="cCode"><a href="../examples/jaxp/sax/samples/Echo03-01.html" target="_blank">Echo03-01.html</a></code>)</p><hr><a name="wp95444"> </a><p class="pBody">Note that the <code class="cCode">characters</code> method was invoked twice in a row. Inspecting the source file <code class="cCode"><a href="../examples/xml/samples/slideSample01.xml" target="_blank">slideSample01.xml</a></code> shows that there is a comment before the first slide. The first call to <code class="cCode">characters</code> comes before that comment. The second call comes after. (Later on, you'll see how to be notified when the parser encounters a comment, although in most cases you won't need such notifications.)</p><a name="wp64375"> </a><p class="pBody">Note, too, that the <code class="cCode">characters</code> method is invoked after the first slide element, as well as before. When you are thinking in terms of hierarchically structured data, that seems odd. After all, you intended for the <code class="cCode">slideshow</code> element to contain <code class="cCode">slide</code> elements, not text. Later on, you'll see how to restrict the <code class="cCode">slideshow</code> element using a DTD. When you do that, the <code class="cCode">characters</code> method will no longer be invoked. </p><a name="wp64376"> </a><p class="pBody">In the absence of a DTD, though, the parser must assume that any element it sees contains text like that in the first item element of the overview slide:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><item>Why <em>WonderWidgets</em> are great</item><a name="wp64377"> </a></pre></div><a name="wp64378"> </a><p class="pBody">Here, the hierarchical structure looks like this:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCode">ELEMENT: <item></code>CHARS: Why ELEMENT: <em> CHARS: WonderWidgets END_ELM: </em>CHARS: are greatEND_ELM: </item><a name="wp64379"> </a></pre></div><a name="wp64381"> </a><h3 class="pHeading2">Documents and Data</h3><a name="wp64382"> </a><p class="pBody">In this example, it's clear that there are characters intermixed with the hierarchical structure of the elements. The fact that text can surround elements (or be prevented from doing so with a DTD or schema) helps to explain why you sometimes hear talk about "XML data" and other times hear about "XML documents". XML comfortably handles both structured data and text documents that include markup. The only difference between the two is whether or not text is allowed between the elements.</p><hr><a name="wp64383"> </a><p class="pNote">Note: In an upcoming section of this tutorial, you will work with the <code class="cCode">ignorableWhitespace</code> method in the <code class="cCode">ContentHandler</code> interface. This method can only be invoked when a DTD is present. If a DTD specifies that <code class="cCode">slideshow</code> does not contain text, then all of the whitespace surrounding the <code class="cCode">slide</code> elements is by definition ignorable. On the other hand, if <code class="cCode">slideshow</code> can contain text (which must be assumed to be true in the absence of a DTD), then the parser must assume that spaces and lines it sees between the <code class="cCode">slide</code> elements are significant parts of the document. </p><hr> </blockquote> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"> <table width="550" summary="layout" id="SummaryNotReq1"> <tr> <td align="left" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a> </td> <td align="center" valign="center"><a accesskey="p" href="JAXPSAX2.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="JAXPSAX4.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a> </td> <td align="right" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font> </font> </td> </tr> </table> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"><p><font size="-1">All of the material in <em>The J2EE(TM) 1.4 Tutorial</em> is <a href="J2EETutorialFront2.html">copyright</a>-protected and may not be published in other workswithout express written permission from Sun Microsystems.</font> </body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -