📄 jaxpxslt6.html
字号:
</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><?xml version="1.0" encoding="ISO-8859-1"?><code class="cCodeBold"><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" ></xsl:stylesheet></code><a name="wp64975"> </a></pre></div><a name="wp64976"> </a><p class="pBody">Now, set it up to produce HTML-compatible output: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><xsl:stylesheet ... ><code class="cCodeBold"> <xsl:output method="html"/></code> ...</xsl:stylesheet><a name="wp64977"> </a></pre></div><a name="wp64978"> </a><p class="pBody">We'll get into the detailed reasons for that entry later on in this section. But for now, note that if you want to output anything besides well-formed XML, then you'll need an <code class="cCode"><xsl:output></code> tag like the one shown, specifying either <code class="cCode">"text"</code> or <code class="cCode">"html"</code>. (The default value is <code class="cCode">"xml"</code>.)</p><hr><a name="wp64979"> </a><p class="pNote">Note: When you specify XML output, you can add the <code class="cCode">indent</code> attribute to produce nicely indented XML output. The specification looks like this: <code class="cCode"><xsl:output method="xml" indent="yes"/></code>. </p><hr><a name="wp64981"> </a><h3 class="pHeading2">Processing the Basic Structure Elements</h3><a name="wp64982"> </a><p class="pBody">You'll start filling in the stylesheet by processing the elements that go into creating a table of contents -- the root element, the title element, and headings. You'll also process the <code class="cCode">PARA</code> element defined in the test document. </p><hr><a name="wp64983"> </a><p class="pNote">Note: If on first reading you skipped the section of this tutorial that discusses the XPAth addressing mechanisms, <a href="JAXPXSLT3.html#wp72547">How XPath Works</a>, now is a good time to go back and review that section.</p><hr><a name="wp64987"> </a><p class="pBody">Begin by adding the main instruction that processes the root element:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> <code class="cCodeBold"><xsl:template match="/"></code><code class="cCode"> <html><body></code><code class="cCodeBold"> <xsl:apply-templates/></code><code class="cCode"> </body></html></code><code class="cCodeBold"> </xsl:template></code><code class="cCode"></xsl:stylesheet></code><a name="wp67067"> </a></pre></div><a name="wp64989"> </a><p class="pBody">The new XSL commands are shown in bold. (Note that they are defined in the <code class="cCode">"xsl"</code> namespace.) The instruction <code class="cCode"><xsl:apply-templates></code> processes the children of the current node. In this case, the current node is the root node.</p><a name="wp64990"> </a><p class="pBody">Despite its simplicity, this example illustrates a number of important ideas, so it's worth understanding thoroughly. The first concept is that a stylesheet contains a number of <span style="font-style: italic">templates</span>, defined with the <code class="cCode"><xsl:template></code> tag. Each template contains a <code class="cCode">match</code> attribute, which selects the elements that the template will be applied to, using the XPath addressing mechanisms described in <a href="JAXPXSLT3.html#wp72547">How XPath Works</a>. </p><a name="wp64994"> </a><p class="pBody">Within the template, tags that do not start with the <code class="cCode">xsl:</code> namespace prefix are simply copied. The newlines and whitespace that follow them are also copied, which helps to make the resulting output readable.</p><hr><a name="wp64995"> </a><p class="pNote">Note: When a newline is not present, whitespace is generally ignored. To include whitespace in the output in such cases, or to include other text, you can use the <code class="cCode"><xsl:text></code> tag. Basically, an XSLT stylesheet expects to process tags. So everything it sees needs to be either an <code class="cCode"><xsl:..></code> tag, some other tag, or whitespace.</p><hr><a name="wp64996"> </a><p class="pBody">In this case, the non-XSL tags are HTML tags. So when the root tag is matched, XSLT outputs the HTML start-tags, processes any templates that apply to children of the root, and then outputs the HTML end-tags.</p><a name="wp64997"> </a><h4 class="pHeading3">Process the <TITLE> Element</h4><a name="wp64998"> </a><p class="pBody">Next, add a template to process the article title: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> <code class="cCodeBold"><xsl:template match="/ARTICLE/TITLE"> <h1 align="center"> <xsl:apply-templates/> </h1> </xsl:template></code></xsl:stylesheet><a name="wp64999"> </a></pre></div><a name="wp65000"> </a><p class="pBody">In this case, you specified a complete path to the <code class="cCode">TITLE</code> element, and output some HTML to make the text of the title into a large, centered heading. In this case, the <code class="cCode">apply-templates</code> tag ensures that if the title contains any inline tags like italics, links, or underlining, they will be processed as well.</p><a name="wp65001"> </a><p class="pBody">More importantly, the <code class="cCode">apply-templates</code> instruction causes the <span style="font-style: italic">text </span>of the title to be processed. Like the DOM data model, the XSLT data model is based on the concept of <span style="font-style: italic">text nodes</span> contained in <span style="font-style: italic">element nodes</span> (which, in turn, can be contained in other element nodes, and so on). That hierarchical structure constitutes the source tree. There is also a result tree, which contains the output. </p><a name="wp65002"> </a><p class="pBody">XSLT works by transforming the source tree into the result tree. To visualize the result of XSLT operations, it is helpful to understand the structure of those trees, and their contents. (For more on this subject, see <a href="JAXPXSLT3.html#wp69428">The XSLT/XPath Data Model</a>.)</p><a name="wp65006"> </a><h4 class="pHeading3">Process Headings</h4><a name="wp65007"> </a><p class="pBody">To continue processing the basic structure elements, add a template to process the top-level headings:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCodeBold"> <xsl:template match="/ARTICLE/SECT"> <h2> <xsl:apply-templates select="text()|B|I|U|DEF|LINK"/> </h2> <xsl:apply-templates select="SECT|PARA|LIST|NOTE"/> </xsl:template></code><a name="wp65008"> </a></xsl:stylesheet><a name="wp65009"> </a></pre></div><a name="wp65010"> </a><p class="pBody">Here, you've specified the path to the topmost <code class="cCode">SECT</code> elements. But this time, you've applied templates in two stages, using the <code class="cCode">select</code> attribute. For the first stage, you selected text nodes using the XPath <code class="cCode">text()</code> function, as well as inline tags like bold and italics. (The vertical pipe (|) is used to match multiple items -- text, <span style="font-style: italic">or</span> a bold tag, <span style="font-style: italic">or</span> an italics tag, etc.) In the second stage, you selected the other structure elements contained in the file, for sections, paragraphs, lists, and notes.</p><a name="wp65011"> </a><p class="pBody">Using the <code class="cCode">select</code> attribute let you put the text and inline elements between the <code class="cCode"><h2>...</h2></code> tags, while making sure that all of the structure tags in the section are processed afterwards. In other words, you made sure that the nesting of the headings in the XML document is <span style="font-style: italic">not</span> reflected in the HTML formatting, which is important for HTML output. </p><a name="wp65012"> </a><p class="pBody">In general, using the <code class="cCode">select</code> clause lets you apply all templates to a subset of the information available in the current context. As another example, this template selects all attributes of the current node: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><xsl:apply-templates select="@*"/></attributes><a name="wp65013"> </a></pre></div><a name="wp65014"> </a><p class="pBody">Next, add the virtually identical template to process subheadings that are nested one level deeper: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCodeBold"> <xsl:template match="/ARTICLE/SECT/SECT"> <h3> <xsl:apply-templates select="text()|B|I|U|DEF|LINK"/> </h3> <xsl:apply-templates select="SECT|PARA|LIST|NOTE"/> </xsl:template></code></xsl:stylesheet><a name="wp65015"> </a></pre></div><a name="wp65016"> </a><h4 class="pHeading3">Generate a Runtime Message</h4><a name="wp65017"> </a><p class="pBody">You could add templates for deeper headings, too, but at some point you have to stop, if only because HTML only goes down to five levels. But for this example, you'll stop at two levels of section headings. But if the XML input happens to contain a third level, you'll want to deliver an error message to the user. This section shows you how to do that.</p><hr><a name="wp65018"> </a><p class="pNote">Note: We <span style="font-style: italic">could</span> continue processing SECT elements that are further down, by selecting them with the expression <code class="cCode">/SECT/SECT//SECT</code>. The <code class="cCode">//</code> selects any SECT elements, at any depth, as defined by the XPath addressing mechanism. But we'll take the opportunity to play with messaging, instead. </p><hr><a name="wp65019"> </a><p class="pBody">Add the following template to generate an error when a section is encountered that is nested too deep:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCodeBold"> <xsl:template match="/ARTICLE/SECT/SECT/SECT"> <xsl:message terminate="yes"> Error: Sections can only be nested 2 deep. </xsl:message> </xsl:template></code></xsl:stylesheet><a name="wp65020"> </a></pre></div><a name="wp65021"> </a><p class="pBody">The <code class="cCode">terminate="yes"</code> clause causes the transformation process to stop after the message is generated. Without it, processing could still go on with everything in that section being ignored.</p><a name="wp65022"> </a><p class="pBody">As an additional exercise, you could expand the stylesheet to handle sections nested up to four sections deep, generating <code class="cCode"><h2>...<h5></code> tags. Generate an error on any section nested five levels deep. </p><a name="wp65024"> </a><p class="pBody">Finally, finish up the stylesheet by adding a template to process the <code class="cCode">PARA</code> tag:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> <code class="cCodeBold"><xsl:template match="PARA"> <p><xsl:apply-templates/></p> </xsl:template></code></xsl:stylesheet><a name="wp65025"> </a></pre></div><a name="wp69139"> </a><h3 class="pHeading2">Writing the Basic Program </h3><a name="wp69140"> </a><p class="pBody">In this part of the tutorial, you'll modify the program that used XSLT to echo an XML file unchanged, changing it so it uses your stylesheet.</p><hr><a name="wp65030"> </a><p class="pNote">Note: The code shown in this section is contained in <code class="cCode"><a href="../examples/jaxp/xslt/samples/Stylizer.java" target="_blank">Stylizer.java</a></code>. The result is <code class="cCode"><a href="../examples/jaxp/xslt/samples/stylizer1a.html" target="_blank">stylizer1a.html</a></code>. (The browser-displayable version of the HTML source is <code class="cCode"><a href="../examples/jaxp/xslt/samples/stylizer1a-src.html" target="_blank">stylizer1a-src.html</a></code>.)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -