﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-&lt;h1&gt;&lt;font color="red" size="36"&gt;︻┳═一Java&lt;/font&gt;&lt;/h1&gt;-文章分类-XSLT</title><link>http://www.blogjava.net/rain1102/category/15291.html</link><description>&lt;b&gt;&lt;font color="#3C1435"&gt;08年奋斗目标：&lt;/font&gt;&lt;font color="maroon"&gt;赚钱买个房子！&lt;/font&gt;&lt;/b&gt;</description><language>zh-cn</language><lastBuildDate>Sat, 29 Mar 2008 08:27:25 GMT</lastBuildDate><pubDate>Sat, 29 Mar 2008 08:27:25 GMT</pubDate><ttl>60</ttl><item><title>RSS</title><link>http://www.blogjava.net/rain1102/articles/176345.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Fri, 18 Jan 2008 14:14:00 GMT</pubDate><guid>http://www.blogjava.net/rain1102/articles/176345.html</guid><wfw:comment>http://www.blogjava.net/rain1102/comments/176345.html</wfw:comment><comments>http://www.blogjava.net/rain1102/articles/176345.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rain1102/comments/commentRss/176345.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rain1102/services/trackbacks/176345.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1．RSS 介绍RSS是利用XML把一个网站的内容发送给其他网站的方式。RSS允许快速浏览新闻与更新。什么是RSS？RSS是在线共享内容的一种简易方式（也叫聚合内容，Really Simple Syndication），Rss允许联合站点内容，Rss定义了一个简单的方式来共享和查看标题及内容。Rss文件可以自动更新，Rss允许个人查看不同站点，Rss是用XML编写的。为什么要使用R...&nbsp;&nbsp;<a href='http://www.blogjava.net/rain1102/articles/176345.html'>阅读全文</a><img src ="http://www.blogjava.net/rain1102/aggbug/176345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rain1102/" target="_blank">Eric.Zhou</a> 2008-01-18 22:14 <a href="http://www.blogjava.net/rain1102/articles/176345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML/XSL-FO</title><link>http://www.blogjava.net/rain1102/articles/176203.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Fri, 18 Jan 2008 06:36:00 GMT</pubDate><guid>http://www.blogjava.net/rain1102/articles/176203.html</guid><wfw:comment>http://www.blogjava.net/rain1102/comments/176203.html</wfw:comment><comments>http://www.blogjava.net/rain1102/articles/176203.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rain1102/comments/commentRss/176203.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rain1102/services/trackbacks/176203.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在学习XSL-FO之前，你应该已经掌握了XML和XML命名空间的基本知识。1．什么是XSL-FO？XSL-FO 是用于将结果格式化成XML数据的语言，XSL-FO全称为（Extensible Stylesheet Language Formatting Objects：扩展格式化对象样式表语言），XSL-FO 是W3C的推荐标准，XSL-FO 现在通常被称为XSL。XSL-FO 是用于...&nbsp;&nbsp;<a href='http://www.blogjava.net/rain1102/articles/176203.html'>阅读全文</a><img src ="http://www.blogjava.net/rain1102/aggbug/176203.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rain1102/" target="_blank">Eric.Zhou</a> 2008-01-18 14:36 <a href="http://www.blogjava.net/rain1102/articles/176203.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Schema (XSD) 教程</title><link>http://www.blogjava.net/rain1102/articles/175861.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Thu, 17 Jan 2008 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/rain1102/articles/175861.html</guid><wfw:comment>http://www.blogjava.net/rain1102/comments/175861.html</wfw:comment><comments>http://www.blogjava.net/rain1102/articles/175861.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/rain1102/comments/commentRss/175861.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rain1102/services/trackbacks/175861.html</trackback:ping><description><![CDATA[<a href="http://www.w3pop.com/learn/index/f/6/c/30/o/0/size/20/p/1/" target="_blank"><span style="font-size: 10pt">Schema (XSD) 教程</span></a><span style="font-size: 10pt"> <br />
</span><img src ="http://www.blogjava.net/rain1102/aggbug/175861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rain1102/" target="_blank">Eric.Zhou</a> 2008-01-17 10:53 <a href="http://www.blogjava.net/rain1102/articles/175861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 语言的 XPath API</title><link>http://www.blogjava.net/rain1102/articles/70267.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Mon, 18 Sep 2006 05:34:00 GMT</pubDate><guid>http://www.blogjava.net/rain1102/articles/70267.html</guid><wfw:comment>http://www.blogjava.net/rain1102/comments/70267.html</wfw:comment><comments>http://www.blogjava.net/rain1102/articles/70267.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rain1102/comments/commentRss/70267.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rain1102/services/trackbacks/70267.html</trackback:ping><description><![CDATA[
		<blockquote>XPath 表达式比繁琐的文档对象模型（DOM）导航代码要容易编写得多。如果需要从 XML 文档中提取信息，最快捷、最简单的办法就是在 Java™ 程序中嵌入 XPath 表达式。Java 5 推出了 javax.xml.xpath 包，这是一个用于 XPath 文档查询的独立于 XML 对象模型的库。</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>如果要告诉别人买一加仑牛奶，您会怎么说？“请去买一加仑牛奶回来” 还是 “从前门出去，向左转，走三个街区向右转，再走半个街区向右转进入商店。走向四号通道，沿通道走五米向左，拿一瓶一加仑装的牛奶然后到收银台付款。再沿原路回家。” 简直太可笑了。只要在 “请去买一加仑牛奶回来” 的基础上稍加指示，多数成人都能自己买回牛奶来。 </p>
		<p>查询语言和计算机搜索与此类似。直接说 “找一个 Cryptonomicon 的副本” 要比编写搜索某个数据库的详细逻辑容易得多。由于搜索操作的逻辑非常相似，可以发明一种通用语言让您使用 “找到 Neal Stephenson 的所有著作” 这样的命令，然后编写对特定数据存储执行此类查询的引擎。 </p>
		<p>
				<a name="N1006A">
						<span class="atitle">
								<font face="Arial" size="4">XPath</font>
						</span>
				</a>
		</p>
		<p>在众多查询语言之中，结构化查询语言（SQL）是一种针对查询特定类型的关系库而设计和优化的语言。其他不那么常见的查询语言还有对象查询语言（OQL）和 XQuery。但本文的主题是 XPath，一种为查询 XML 文档而设计的查询语言。比如，下面这个简单的 XPath 查询可以在文档中找到作者为 Neal Stephenson 的所有图书的标题：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">//book[author="Neal Stephenson"]/title</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>作为对照，查询同样信息的纯 DOM 搜索代码如 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing1"><font color="#996699">清单 1</font></a> 所示：</p>
		<br />
		<a name="listing1">
				<b>清单 1. 找到 Neal Stephenson 所有著作 title 元素的 DOM 代码</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">        ArrayList result = new ArrayList();
        NodeList books = doc.getElementsByTagName("book");
        for (int i = 0; i &lt; books.getLength(); i++) {
            Element book = (Element) books.item(i);
            NodeList authors = book.getElementsByTagName("author");
            boolean stephenson = false;
            for (int j = 0; j &lt; authors.getLength(); j++) {
                Element author = (Element) authors.item(j);
                NodeList children = author.getChildNodes();
                StringBuffer sb = new StringBuffer();
                for (int k = 0; k &lt; children.getLength(); k++) {
                    Node child = children.item(k);
                    // really should to do this recursively
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        sb.append(child.getNodeValue());
                    }
                }
                if (sb.toString().equals("Neal Stephenson")) {
                    stephenson = true;
                    break;
                }

            }

            if (stephenson) {
                NodeList titles = book.getElementsByTagName("title");
                for (int j = 0; j &lt; titles.getLength(); j++) {
                    result.add(titles.item(j));
                }
            }

        }</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>不论您是否相信，<a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing1"><font color="#996699">清单 1</font></a> 中的 DOM 显然不如简单的 XPath 表达式通用或者健壮。您愿意编写、调试和维护哪一个？我想答案很明显。 </p>
		<p>但是虽然有很强的表达能力，XPath 并不是 Java 语言，事实上 XPath 不是一种完整的编程语言。有很多东西用 XPath 表达不出来，甚至有些查询也无法表达。比方说，XPath 不能查找国际标准图书编码（ISBN）检验码不匹配的所有图书，或者找出境外帐户数据库显示欠帐的所有作者。幸运的是，可以把 XPath 结合到 Java 程序中，这样就能发挥两者的优势了：Java 做 Java 所擅长的，XPath 做 XPath 所擅长的。 </p>
		<p>直到最近，Java 程序执行 XPath 查询所需要的应用程序编程接口（API）还因形形色色的 XPath 引擎而各不相同。Xalan 有一种 API，Saxon 使用另一种，其他引擎则使用其他的 API。这意味着代码往往把您限制到一种产品上。理想情况下，最好能够试验具有不同性能特点的各种引擎，而不会带来不适当的麻烦或者重新编写代码。 </p>
		<p>于是，Java 5 推出了 <code>javax.xml.xpath</code> 包，提供一个引擎和对象模型独立的 XPath 库。这个包也可用于 Java 1.3 及以后的版本，但需要单独安装 Java API for XML Processing (JAXP) 1.3。Xalan 2.7 和 Saxon 8 以及其他产品包含了这个库的实现。 </p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1009B">
						<span class="atitle">
								<font face="Arial" size="4">一个简单的例子</font>
						</span>
				</a>
		</p>
		<p>我将举例说明如何使用它。然后再讨论一些细节问题。假设要查询一个图书列表，寻找 Neal Stephenson 的著作。具体来说，这个图书列表的形式如 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing2"><font color="#996699">清单 2</font></a> 所示： </p>
		<br />
		<a name="listing2">
				<b>清单 2. 包含图书信息的 XML 文档</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;inventory&gt;
    &lt;book year="2000"&gt;
        &lt;title&gt;Snow Crash&lt;/title&gt;
        &lt;author&gt;Neal Stephenson&lt;/author&gt;
        &lt;publisher&gt;Spectra&lt;/publisher&gt;
        &lt;isbn&gt;0553380958&lt;/isbn&gt;
        &lt;price&gt;14.95&lt;/price&gt;
    &lt;/book&gt;
 
    &lt;book year="2005"&gt;
        &lt;title&gt;Burning Tower&lt;/title&gt;
        &lt;author&gt;Larry Niven&lt;/author&gt;
        &lt;author&gt;Jerry Pournelle&lt;/author&gt;
        &lt;publisher&gt;Pocket&lt;/publisher&gt;
        &lt;isbn&gt;0743416910&lt;/isbn&gt;
        &lt;price&gt;5.99&lt;/price&gt;
    &lt;book&gt;
 
    &lt;book year="1995"&gt;
        &lt;title&gt;Zodiac&lt;/title&gt;
        &lt;author&gt;Neal Stephenson&lt;author&gt;
        &lt;publisher&gt;Spectra&lt;/publisher&gt;
        &lt;isbn&gt;0553573862&lt;/isbn&gt;
        &lt;price&gt;7.50&lt;/price&gt;
    &lt;book&gt;

    &lt;!-- more books... --&gt;
 
&lt;/inventory&gt;</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table cellspacing="0" cellpadding="0" width="65%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N100B3">
																				<b>抽象工厂</b>
																		</a>
																		<br />
																		<p>
																				<code>XPathFactory</code> 是一个抽象工厂。抽象工厂设计模式使得这一种 API 能够支持不同的对象模型，如 DOM、JDOM 和 XOM。为了选择不同的模型，需要向 <code>XPathFactory.newInstance()</code> 方法传递标识对象模型的统一资源标识符（URI）。比如 http://xom.nu/ 可以选择 XOM。但实际上，到目前为止 DOM 是该 API 支持的惟一对象模型。 </p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>查找所有图书的 XPath 查询非常简单：<code>//book[author="Neal Stephenson"]</code>。为了找出这些图书的标题，只要增加一步，表达式就变成了 <code>//book[author="Neal Stephenson"]/title</code>。最后，真正需要的是 <code>title</code> 元素的文本节点孩子。这就要求再增加一步，完整的表达式就是 <code>//book[author="Neal Stephenson"]/title/text()</code>。 </p>
		<p>现在我提供一个简单的程序，它从 Java 语言中执行这个查询，然后把找到的所有图书的标题打印出来。首先，需要将文档加载到一个 DOM <code>Document</code> 对象中。为了简化起见，假设该文档在当前工作目录的 books.xml 文件中。下面的简单代码片段解析文档并建立对应的 <code>Document</code> 对象： </p>
		<br />
		<a name="listing3">
				<b>清单 3. 用 JAXP 解析文档</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse("books.xml");</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>到目前为止，这仅仅是标准的 JAXP 和 DOM，没有什么新鲜的。 </p>
		<p>接下来创建 <code>XPathFactory</code>：</p>
		<table cellspacing="0" cellpadding="5" width="60%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">XPathFactory factory = XPathFactory.newInstance();</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>然后使用这个工厂创建 <code>XPath</code> 对象： </p>
		<table cellspacing="0" cellpadding="5" width="60%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">XPath xpath = factory.newXPath();</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<code>XPath</code> 对象编译 XPath 表达式： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">PathExpression expr = xpath.compile("//book[author='Neal Stephenson']/title/text()");</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table cellspacing="0" cellpadding="0" width="65%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N10114">
																				<b>直接求值</b>
																		</a>
																		<br />
																		<p>如果 XPath 表达式只使用一次，可以跳过编译步骤直接对 <code>XPath</code> 对象调用 <code>evaluate()</code> 方法。但是，如果同一个表达式要重复使用多次，编译可能更快一些。 </p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>最后，计算 XPath 表达式得到结果。表达式是针对特定的上下文节点计算的，在这个例子中是整个文档。还必须指定返回类型。这里要求返回一个节点集： </p>
		<table cellspacing="0" cellpadding="5" width="60%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">Object result = expr.evaluate(doc, XPathConstants.NODESET);</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>可以将结果强制转化成 DOM <code>NodeList</code>，然后遍历列表得到所有的标题： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">        NodeList nodes = (NodeList) result;
        for (int i = 0; i &lt; nodes.getLength(); i++) {
            System.out.println(nodes.item(i).getNodeValue()); 
        }</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing4">
						<font color="#996699">清单 4</font>
				</a> 把上述片段组合到了一个程序中。还要注意，这些方法可能抛出一些检查异常，这些异常必须在 <code>throws</code> 子句中声明，但是我在上面把它们掩盖起来了： </p>
		<br />
		<a name="listing4">
				<b>清单 4. 用固定的 XPath 表达式查询 XML 文档的完整程序</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">import java.io.IOException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import javax.xml.xpath.*;

public class XPathExample {

  public static void main(String[] args) 
   throws ParserConfigurationException, SAXException, 
          IOException, XPathExpressionException {

    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true); // never forget this!
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse("books.xml");

    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    XPathExpression expr 
     = xpath.compile("//book[author='Neal Stephenson']/title/text()");

    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    for (int i = 0; i &lt; nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getNodeValue()); 
    }

  }

}</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="N1014E">
						<span class="smalltitle">
								<strong>
										<font face="Arial">XPath 数据模型</font>
								</strong>
						</span>
				</a>
		</p>
		<p>每当混合使用诸如 XPath 和 Java 这样两种不同的语言时，必定会有某些将两者粘合在一起的明显接缝。并非一切都很合拍。XPath 和 Java 语言没有同样的类型系统。XPath 1.0 只有四种基本数据类型：</p>
		<ul>
				<li>node-set 
</li>
				<li>number 
</li>
				<li>boolean 
</li>
				<li>string </li>
		</ul>
		<p>当然，Java 语言有更多的数据类型，包括用户定义的对象类型。</p>
		<p>多数 XPath 表达式，特别是位置路径，都返回节点集。但是还有其他可能。比如，XPath 表达式 <code>count(//book)</code> 返回文档中的图书数量。XPath 表达式 <code>count(//book[@author="Neal Stephenson"]) &gt; 10</code> 返回一个布尔值：如果文档中 Neal Stephenson 的著作超过 10 本则返回 true，否则返回 false。 </p>
		<p>
				<code>evaluate()</code> 方法被声明为返回 <code>Object</code>。实际返回什么依赖于 XPath 表达式的结果以及要求的类型。一般来说，XPath 的</p>
		<ul>
				<li>number 映射为 <code>java.lang.Double</code></li>
				<li>string 映射为 <code>java.lang.String</code></li>
				<li>boolean 映射为 <code>java.lang.Boolean</code></li>
				<li>node-set 映射为 <code>org.w3c.dom.NodeList</code></li>
		</ul>
		<table cellspacing="0" cellpadding="0" width="55%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N1019C">
																				<b>XPath 2</b>
																		</a>
																		<br />
																		<p>前面一直假设您使用的是 XPath 1.0。XPath 2 大大扩展和修改了类型系统。Java XPath API 支持 XPath 2 所需的主要修改是为返回 XPath 2 新数据类型增加常量。 </p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>在 Java 中计算 XPath 表达式时，第二个参数指定需要的返回类型。有五种可能，都在 <code>javax.xml.xpath.XPathConstants</code> 类中命名了常量： </p>
		<ul>
				<li>
						<code>XPathConstants.NODESET</code>
				</li>
				<li>
						<code>XPathConstants.BOOLEAN</code>
				</li>
				<li>
						<code>XPathConstants.NUMBER</code>
				</li>
				<li>
						<code>XPathConstants.STRING</code>
				</li>
				<li>
						<code>XPathConstants.NODE</code>
				</li>
		</ul>
		<p>最后一个 <code>XPathConstants.NODE</code> 实际上没有匹配的 XPath 类型。只有知道 XPath 表达式只返回一个节点或者只需要一个节点时才使用它。如果 XPath 表达式返回了多个节点并且指定了 <code>XPathConstants.NODE</code>，则 <code>evaluate()</code> 按照文档顺序返回第一个节点。如果 XPath 表达式选择了一个空集并指定了 <code>XPathConstants.NODE</code>，则 <code>evaluate()</code> 返回 null。 </p>
		<p>如果不能完成要求的转换，<code>evaluate()</code> 将抛出 <code>XPathException</code>。 </p>
		<hr />
		<p>
				<a name="N101EB">
						<span class="atitle">
								<font face="Arial" size="4">名称空间上下文</font>
						</span>
				</a>
		</p>
		<p>若 XML 文档中的元素在名称空间中，查询该文档的 XPath 表达式必须使用相同的名称空间。XPath 表达式不一定要使用相同的前缀，只需要名称空间 URI 相同即可。事实上，如果 XML 文档使用默认名称空间，那么尽管目标文档没有使用前缀，XPath 表达式也必须使用前缀。 </p>
		<p>但是，Java 程序不是 XML 文档，因此不能用一般的名称空间解析。必须提供一个对象将前缀映射到名称空间 URI。该对象是 <code>javax.xml.namespace.NamespaceContext</code> 接口的实例。比如，假设图书文档放在 http://www.example.com/books 名称空间中，如 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing5"><font color="#996699">清单 5</font></a> 所示： </p>
		<br />
		<a name="listing5">
				<b>清单 5. 使用默认名称空间的 XML 文档</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;inventory xmlns="http://www.example.com/books"&gt;
    &lt;book year="2000"&gt;
        &lt;title&gt;Snow Crash&lt;/title&gt;
        &lt;author&gt;Neal Stephenson&lt;/author&gt;
        &lt;publisher&gt;Spectra&lt;/publisher&gt;
        &lt;isbn&gt;0553380958&lt;/isbn&gt;
        &lt;price&gt;14.95&lt;price&gt;
    &lt;/book&gt;

    &lt;!-- more books... --&gt;

&lt;inventory&gt;</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>查找 Neal Stephenson 全部著作标题的 XPath 表达式就要改为 <code>//pre:book[pre:author="Neal Stephenson"]/pre:title/text()</code>。但是，必须将前缀 <code>pre</code> 映射到 URI http://www.example.com/books。<code>NamespaceContext</code> 接口在 Java 软件开发工具箱（JDK）或 JAXP 中没有默认实现似乎有点笨，但确实如此。不过，自己实现也不难。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing6"><font color="#996699">清单 6</font></a> 对一个名称空间给出了简单的实现。还需要映射 <code>xml</code> 前缀。 </p>
		<br />
		<a name="listing6">
				<b>清单 6. 绑定一个名称空间和默认名称空间的简单上下文</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">import java.util.Iterator;
import javax.xml.*;
import javax.xml.namespace.NamespaceContext;

public class PersonalNamespaceContext implements NamespaceContext {

    public String getNamespaceURI(String prefix) {
        if (prefix == null) throw new NullPointerException("Null prefix");
        else if ("pre".equals(prefix)) return "http://www.example.org/books";
        else if ("xml".equals(prefix)) return XMLConstants.XML_NS_URI;
        return XMLConstants.NULL_NS_URI;
    }

    // This method isn't necessary for XPath processing.
    public String getPrefix(String uri) {
        throw new UnsupportedOperationException();
    }

    // This method isn't necessary for XPath processing either.
    public Iterator getPrefixes(String uri) {
        throw new UnsupportedOperationException();
    }

}</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>使用映射存储绑定和增加 setter 方法实现名称空间上下文的重用也不难。 </p>
		<p>创建 <code>NamespaceContext</code> 对象后，在编译表达式之前将其安装到 <code>XPath</code> 对象上。以后就可以像以前一样是用这些前缀查询了。比如： </p>
		<br />
		<a name="listing7">
				<b>清单 7. 使用名称空间的 XPath 查询</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  xpath.setNamespaceContext(new PersonalNamespaceContext());
  XPathExpression expr 
    = xpath.compile("//pre:book[pre:author='Neal Stephenson']/pre:title/text()");

  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  NodeList nodes = (NodeList) result;
  for (int i = 0; i &lt; nodes.getLength(); i++) {
      System.out.println(nodes.item(i).getNodeValue()); 
  }</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<hr />
		<p>
				<a name="N1023E">
						<span class="atitle">
								<font face="Arial" size="4">函数求解器</font>
						</span>
				</a>
		</p>
		<p>有时候，在 Java 语言中定义用于 XPath 表达式的扩展函数很有用。这些函数可以执行用纯 XPath 很难或者无法执行的任务。不过必须是真正的函数，而不是随意的方法。就是说不能有副作用。（XPath 函数可以按照任意的顺序求值任意多次。） </p>
		<p>通过 Java XPath API 访问的扩展函数必须实现 <code>javax.xml.xpath.XPathFunction</code> 接口。这个接口只声明了一个方法 evaluate： </p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">public Object evaluate(List args) throws XPathFunctionException</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>该方法必须返回 Java 语言能够转换到 XPath 的五种类型之一： </p>
		<ul>
				<li>
						<code>String</code>
				</li>
				<li>
						<code>Double</code>
				</li>
				<li>
						<code>Boolean</code>
				</li>
				<li>
						<code>Nodelist</code>
				</li>
				<li>
						<code>Node</code>
				</li>
		</ul>
		<p>比如，<a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing8"><font color="#996699">清单 8</font></a> 显示了一个扩展函数，它检查 ISBN 的校验和并返回 <code>Boolean</code>。这个校验和的基本规则是前九位数的每一位乘上它的位置（即第一位数乘上 1，第二位数乘上 2，依次类推）。将这些数加起来然后取除以 11 的余数。如果余数是 10，那么最后一位数就是 X。 </p>
		<br />
		<a name="listing8">
				<b>清单 8. 检查 ISBN 的 XPath 扩展函数</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">import java.util.List;
import javax.xml.xpath.*;
import org.w3c.dom.*;

public class ISBNValidator implements XPathFunction {

  // This class could easily be implemented as a Singleton.
    
  public Object evaluate(List args) throws XPathFunctionException {

    if (args.size() != 1) {
      throw new XPathFunctionException("Wrong number of arguments to valid-isbn()");
    }

    String isbn;
    Object o = args.get(0);

    // perform conversions
    if (o instanceof String) isbn = (String) args.get(0);
    else if (o instanceof Boolean) isbn = o.toString();
    else if (o instanceof Double) isbn = o.toString();
    else if (o instanceof NodeList) {
        NodeList list = (NodeList) o;
        Node node = list.item(0);
        // getTextContent is available in Java 5 and DOM 3.
        // In Java 1.4 and DOM 2, you'd need to recursively 
        // accumulate the content.
        isbn= node.getTextContent();
    }
    else {
        throw new XPathFunctionException("Could not convert argument type");
    }

    char[] data = isbn.toCharArray();
    if (data.length != 10) return Boolean.FALSE;
    int checksum = 0;
    for (int i = 0; i &lt; 9; i++) {
        checksum += (i+1) * (data[i]-'0');
    }
    int checkdigit = checksum % 11;

    if (checkdigit + '0' == data[9] || (data[9] == 'X' &amp;&amp; checkdigit == 10)) {
        return Boolean.TRUE;
    }
    return Boolean.FALSE;

  }

}</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>下一步让这个扩展函数能够在 Java 程序中使用。为此，需要在编译表达式之前向 XPath 对象安装 <code>javax.xml.xpath.XPathFunctionResolver</code>。函数求解器将函数的 XPath 名称和名称空间 URI 映射到实现该函数的 Java 类。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing9"><font color="#996699">清单 9</font></a> 是一个简单的函数求解器，将扩展函数 <code>valid-isbn</code> 和名称空间 http://www.example.org/books 映射到 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-javaxpathapi.html#listing8"><font color="#996699">清单 8</font></a> 中的类。比如，XPath 表达式 <code>//book[not(pre:valid-isbn(isbn))]</code> 可以找到 ISBN 校验和不匹配的所有图书。 </p>
		<br />
		<a name="listing9">
				<b>清单 9. 识别 valid-isbn 扩展函数的上下文</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">iimport javax.xml.namespace.QName;
import javax.xml.xpath.*;

public class ISBNFunctionContext implements XPathFunctionResolver {

  private static final QName name 
   = new QName("http://www.example.org/books", "valid-isbn");

  public XPathFunction resolveFunction(QName name, int arity) {
      if (name.equals(ISBNFunctionContext.name) &amp;&amp; arity == 1) {
          return new ISBNValidator();
      }
      return null;
  }

}</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>由于扩展函数必须有名称空间，所以计算包含扩展函数的表达式时必须使用 <code>NamespaceResolver</code>，即便查询的文档没有使用任何名称空间。由于 <code>XPathFunctionResolver</code>、<code>XPathFunction</code> 和 <code>NamespaceResolver</code> 都是接口，如果方便的话可以将它们放在所有的类中。
</p>
		<hr />
		<p>
				<a name="N102B8">
						<span class="atitle">
								<font face="Arial" size="4">结束语</font>
						</span>
				</a>
		</p>
		<p>用 SQL 和 XPath 这样的声明性语言编写查询，要比使用 Java 和 C 这样的命令式语言容易得多。但是，用 Java 和 C 这样的图灵完整语言编写复杂的逻辑，又比 SQL 和 XPath 这样的声明性语言容易得多。所幸的是，通过使用 Java Database Connectivity (JDBC) 和 <code>javax.xml.xpath</code> 之类的 API 可以将两者结合起来。随着世界上越来越多的数据转向 XML，<code>javax.xml.xpath</code> 将与 <code>java.sql</code> 一样变得越来越重要。</p>
<img src ="http://www.blogjava.net/rain1102/aggbug/70267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rain1102/" target="_blank">Eric.Zhou</a> 2006-09-18 13:34 <a href="http://www.blogjava.net/rain1102/articles/70267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XPath的语法</title><link>http://www.blogjava.net/rain1102/articles/70209.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Mon, 18 Sep 2006 01:18:00 GMT</pubDate><guid>http://www.blogjava.net/rain1102/articles/70209.html</guid><wfw:comment>http://www.blogjava.net/rain1102/comments/70209.html</wfw:comment><comments>http://www.blogjava.net/rain1102/articles/70209.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rain1102/comments/commentRss/70209.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rain1102/services/trackbacks/70209.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 当前位置		当我们使用XSLT处理XML源文档是，我们用Context来表示当前正在被模板处理的节点位置。比如xsl:template match="/"语句中表示Context在文档的根(root)节点。我不知道如何准确的翻译Context这个词，它类似于C语言里的指针，表示程序当前运行的位置。理解Context对于正确处理XSL模板非常重要，当您的XSL模板输出的文档和您想要的不一样，最先...&nbsp;&nbsp;<a href='http://www.blogjava.net/rain1102/articles/70209.html'>阅读全文</a><img src ="http://www.blogjava.net/rain1102/aggbug/70209.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rain1102/" target="_blank">Eric.Zhou</a> 2006-09-18 09:18 <a href="http://www.blogjava.net/rain1102/articles/70209.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xsl过程解析</title><link>http://www.blogjava.net/rain1102/articles/70207.html</link><dc:creator>Eric.Zhou</dc:creator><author>Eric.Zhou</author><pubDate>Mon, 18 Sep 2006 01:14:00 GMT</pubDate><guid>http://www.blogjava.net/rain1102/articles/70207.html</guid><wfw:comment>http://www.blogjava.net/rain1102/comments/70207.html</wfw:comment><comments>http://www.blogjava.net/rain1102/articles/70207.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rain1102/comments/commentRss/70207.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rain1102/services/trackbacks/70207.html</trackback:ping><description><![CDATA[
		<p>&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;</p>
		<p>这是标准的XML文档的首行代码，因为XSLT本身也是XML文档。<br />encoding属性用来定义文档使用的编码形式，iso-8859-1主要支持西欧和北美的语言编码。<br />如果你想使用简体中文，那么就应该写成：</p>
		<p>&lt;?xml version="1.0" encoding="GB2312"?&gt;</p>
		<p>接下去的代码是:</p>
		<p>&lt;xsl:stylesheet  xmlns:xsl="<a href="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform</a>"  version="1.0"&gt;</p>
		<p>这是标准的XSLT文件首行代码。xsl:stylesheet代码的意思是将文档作为一个样式表来(stylesheet)处理。<br />xmlns:xsl属性是一个名字空间声明，和XML中的名字空间使用方法一样，用来防止元素名称重复和混乱。<br />其中前缀xsl的意思是文档中使用的元素遵守W3C的XSLT规范。<br />最后的version属性说明样式表只采用XSLT 1.0的标准功能，这也是目前仅有的标准。</p>
		<p>&lt;xsl:template match="/"&gt;</p>
		<p>一个&lt;xsl:template&gt;元素定义一个模板规则。属性match="/"说明XML源文档中，这个模板规则作用的起点。"/"是一种XPath语法，我们在后面将详细讲述，这里的"/"代表XML结构树的根(root)。</p>
		<p>接下去的代码是:</p>
		<p>&lt;html&gt;</p>
		<p>&lt;head&gt;</p>
		<p>&lt;title&gt;First XSLT Example&lt;/title&gt;</p>
		<p>&lt;/head&gt;</p>
		<p>&lt;body&gt;</p>
		<p>&lt;p&gt;&lt;xsl:value-of select="greeting"/&gt;&lt;/p&gt;</p>
		<p>&lt;/body&gt;</p>
		<p>&lt;/html&gt;</p>
		<p>说明：当模板规则被触发，模板的内容就会控制输出的结果。例子中，模板大部分内容由HTML元<br />素和文本构成。只有&lt;xsl:value-of&gt;元素是XSLT语法，这里&lt;xsl:value-of&gt;的作用是拷贝原文档中的<br />一个节点的值到输出文档。而select属性则详细指定要处理的节点名称。这是XPath语法，"greeting"<br />的意思就是寻找根节点名为greeting的元素，并用模板来处理这个节点。具体的就是找到&lt;greeting&gt;<br />元素，然后将元素的值"hello world"按模板样式拷贝到输出文件。 </p>
		<p>提示：由于XML文档是严格的层级结构(用IE5查看XML文件，会看见XML文档类似多级关联菜单)，<br />所以我们形象的称XML文档为文档树，其中每一对元素称作树的一个节点。根元素就是根节点。</p>
		<p>最后关闭所有元素：</p>
		<p>&lt;/xsl:template&gt;</p>
		<p>&lt;/xsl:stylesheet&gt;</p>
		<p> </p>
<img src ="http://www.blogjava.net/rain1102/aggbug/70207.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rain1102/" target="_blank">Eric.Zhou</a> 2006-09-18 09:14 <a href="http://www.blogjava.net/rain1102/articles/70207.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>