﻿<?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-VincentChen‘s Blog-文章分类-AJAX</title><link>http://www.blogjava.net/Vencent/category/7763.html</link><description>&lt;font color='orange'&gt;本博客仅为收集所用。在此对原作者表示感谢。&lt;/font&gt;
&lt;center&gt;
&lt;script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;div class="custom"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-6256612161572960";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text";
google_ad_channel ="";
google_page_url = document.location;
google_color_border = ["FFDDAA","FFDDAA","FFDDAA","FFDDAA"];
google_color_bg = ["EEEEEE","EEEEEE","EEEEEE","EEEEEE"];
google_color_link = ["FFDDAA","0033FF","00008B","99CC33"];
google_color_url = ["999999","0033FF","00008B","FFCC00"];
google_color_text = ["0033FF","AA9999","0033FF","AA9999"];
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;/div&gt;&lt;/center&gt;
&lt;bgsound src="http://www.blogjava.net/Files/Vencent/The%20Mass%20Era.zip" volume="10" loop="10"/&gt;</description><language>zh-cn</language><lastBuildDate>Mon, 14 May 2007 07:21:44 GMT</lastBuildDate><pubDate>Mon, 14 May 2007 07:21:44 GMT</pubDate><ttl>60</ttl><item><title>转载：On having layout</title><link>http://www.blogjava.net/Vencent/articles/117308.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 14 May 2007 04:53:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/117308.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/117308.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/117308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/117308.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/117308.html</trackback:ping><description><![CDATA[<h1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; On having layout</h1>
<p>　　译者注：一篇很好的文章，很久以前在blog上就推荐过，这两天断断续续花了点时间翻译了一下，推荐读读。<a href="http://www.satzansatz.de/cssd/onhavinglayout.htm"><u><font color=#0066cc>英文原文在此</font></u></a>。</p>
<p>　　文中所有的 layout 这个单词都未作翻译，一来本身这个单词意思就比较多，翻成啥都觉得别扭，二来它也是专有的属性，所以就意会一下吧。水平有限，很多地方都是模模糊糊地意译，发现错误欢迎留言指出。</p>
<p>　　引用一段来自<a href="http://dean.edwards.name/weblog/"><u><font color=#0066cc>Dean Edwards</font></u></a>的评价：</p>
<blockquote>
<p>　　I recommend that every CSS designer and DOM scripter read this. Understanding &#8220;layout&#8221; gives a huge insight into lots of other IE bugs and idiosyncrasies.</p>
</blockquote>
<p class=blockquotesource>(<a href="http://dean.edwards.name/weblog/2005/06/layout/"><u><font color=#0066cc>Dean Edwards</font></u></a>)</p>
<h4 id=intro>介绍</h4>
<p>　　Internet Explorer 中有很多奇怪的渲染问题可以通过赋予其&#8220;layout&#8221;得到解决。John Gallant 和 Holly Bergevin 把这些问题归类为&#8220;尺寸bug(dimensional bugs)&#8221;，意思是这些 bug 可以通过赋予相应元素某个宽度或高度解决。这便引出关于&#8220;layout&#8221;的一个问题：为什么它会改变元素的渲染特性，为什么它会影响到元素之间的关系？这个问题问得很好，但却很难回答。在这篇文章中，我们专注于这个复杂问题会有那些方面的表现，某一方面的具体讨论和范例请参考文中给出的相关链接。</p>
<h4 id=def>hasLayout — 定义</h4>
<p>　　&#8220;Layout&#8221;是一个 IE/Win 的私有概念，它决定了一个元素如何显示以及约束其包含的内容、如何与其他元素交互和建立联系、如何响应和传递应用程序事件/用户事件等，这有点类似于一个窗体的概念。</p>
<p>　　微软的开发者们认为盒状元素(box-type elements)应该具有一个&#8220;属性(property)&#8221;(这是面向对象编程中的一个概念)，于是他们便使用了 <code>layout</code> , 也就是 <code>hasLayout</code>。</p>
<p>　　<code>hasLayout</code> 其实既不是一个属性更不是一个行为，而是 IE 这个渲染引擎代代继承一贯拥有的一个渲染概念，在这个概念下渲染的元素将具有一种特性。</p>
<p>　　实际上这种渲染特性在有些 HTML 元素中与身俱来，而在另外一些元素中也可以通过一些 CSS 属性将其触发为 <code>true</code> ，且一旦触发将不可逆转。</p>
<div class=alpha>
<h5 id=nom>术语</h5>
<p>　　当我们说一个元素&#8220;拥有layout&#8221;或&#8220;得到layout&#8221;，或者说一个元素&#8220;has layout&#8221; 的时候，我们的意思是指它的微软专有属性 <a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp"><code><u><font color=#0066cc>hasLayout</font></u></code></a> 被设为了 <code>true</code> 。一个&#8220;layout元素&#8221;可以是一个默认就拥有 layout 的元素或者是一个通过设置某些 CSS 属性得到 layout 的元素。</p>
<p>　　而&#8220;无layout元素&#8221;，是指 hasLayout 未被触发的元素，比如一个未设定宽高尺寸的干净 div 元素就可以做为一个 &#8220;无layout祖先&#8221;。</p>
<p>　　给一个默认没有 layout 的元素赋予 layout 的方法包括设置可触发 <code>hasLayout = true</code> 的 CSS 属性。参考<a href="http://www.sharkui.com/articles/onhavinglayout.html#elem"><u><font color=#0066cc>默认 layout 元素</font></u></a>以及这些<a href="http://www.sharkui.com/articles/onhavinglayout.html#prop"><u><font color=#0066cc>属性</font></u></a>列表。没有办法设置 <code>hasLayout = false</code> ， 除非把一开始那些触发 <code>hasLayout = true</code> 的 CSS 属性去除。</p>
</div>
<h4 id=begin>问题种种</h4>
<p>　　<code>hasLayout</code> 的问题不管新手还是老手，不管设计师或者程序员可能都遇到过。具有 layout 的元素通常有着不同寻常而且难以预料的的显示效果，而且有时甚至会牵连到他们的孩子元素。</p>
<p>　　一个元素是否具有&#8220;layout&#8221;可能会引发如下的一些问题：</p>
<ul>
    <li>IE 很多常见的浮动 bug 。
    <li>元素本身对一些基本属性的异常处理问题。
    <li>容器和其子孙之间的边距重叠(margin collapsing)问题。
    <li>使用列表时遇到的诸多问题。
    <li>背景图像的定位偏差问题。
    <li>使用脚本时遇到的浏览器之间处理不一致的问题。 </li>
</ul>
<p>　　上面的列表只是列出一个大概，也不完善。下面的文章将尽可能详细彻底的描述有无&#8220;layout&#8221;所带来的各种问题。</p>
<h4 id=wherefrom>Layout 从何而来</h4>
<p>　　不同于标准属性，也不像某些浏览器的私有 CSS 属性，layout <em>无法通过某一个 CSS 声明直接设定</em> 。也就是说没有&#8220;layout属性&#8221;这么一个东西，元素要么本身自动拥有 layout，要么借助一些 CSS 声明悄悄地获得 layout。</p>
<div class=alpha>
<h5 id=elem>默认layout元素</h5>
<p>　　下列元素应该是默认具有 layout 的：</p>
<ul>
    <li><code>&lt;html&gt;, &lt;body&gt;</code>
    <li><code>&lt;table&gt;, &lt;tr&gt;, &lt;th&gt;, &lt;td&gt;</code>
    <li><code>&lt;img&gt;</code>
    <li><code>&lt;hr&gt;</code>
    <li><code>&lt;input&gt;, &lt;select&gt;, &lt;textarea&gt;, &lt;button&gt;</code>
    <li><code>&lt;iframe&gt;, &lt;embed&gt;, &lt;object&gt;, &lt;applet&gt;</code>
    <li><code>&lt;marquee&gt;</code> </li>
</ul>
<h5 id=prop>属性</h5>
<p>　　下列 CSS 属性和取值将会让一个元素获得 layout：</p>
<dl>
<dt><code>position: absolute</code>
<dd>绝对定位元素的包含区块(containing block)就会经常在这一方面出问题。
<dt><code>float: left|right</code>
<dd>由于 layout 元素的特性，浮动模型会有很多怪异的表现。
<dt><code>display: inline-block</code>
<dd>当一个内联级别的元素需要 layout 的时候往往就要用到它，这也可能也是这个 CSS 属性的唯一效果——让某个元素拥有 layout。&#8220;inline-block行为&#8221;在IE中是可以实现的，但是非常与众不同： <a title="查看Bruno Fassino的相关文章" href="http://www.brunildo.org/test/InlineBlockLayout.html"><u><font color=#0066cc>IE/Win: inline-block and hasLayout</font></u></a> 。
<dt><code>width: 任意值</code>
<dd>很多人遇到 layout 相关问题发生时，一般都会先尝试用这个来修复。
<dt><code>height: 任意值</code>
<dd>height: 1% 就在 Holly Hack 中用到。
<dt><code>zoom: 任意值</code> (<a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/zoom.asp"><u><font color=#0066cc>MSDN</font></u></a>)
<dd>MS专有属性，无法通过校验。 不过 <code>zoom: 1</code> 可以临时用做调试。
<dt><code>writing-mode: tb-rl</code> (<a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/writingmode.asp"><u><font color=#0066cc>MSDN</font></u></a>)
<dd>MS专有属性，无法通过校验。 </dd></dl>
<p>　　在 IE7 中，overflow 也变成了一个 layout 触发器：</p>
<dl>
<dt><code>overflow: hidden|scroll|auto</code>
<dd>这个属性在之前版本 IE 中没有触发 layout 的功能。
<dt><code>overflow-x|-y: hidden|scroll|auto</code>
<dd>overflow-x 和 overflow-y 是 CSS3 盒模型中的属性，尚未得到浏览器的广泛支持。他们在之前版本IE中没有触发 layout 的功能。 </dd></dl>
<p>　　另外 IE7 的荧幕上又新添了几个 haslayout 的演员，如果只从 hasLayout 这个方面考虑，min/max 和 width/height 的表现类似，position 的 fixed 和 absolute 也是一模一样。</p>
<dl>
<dt><code>position: fixed</code>
<dd>./.
<dt><code>min-width: 任意值</code>
<dd>就算设为0也可以让该元素获得 layout。
<dt><code>max-width: 除 none 之外的任意值</code>
<dd>./.
<dt><code>min-height: 任意值</code>
<dd>即使设为0也可以让该元素的 haslayout=true
<dt><code>max-height: 除 none 之外的任意值</code>
<dd>./. </dd></dl>
<p>　　以上结论借助 IE Developer Toobar 以及预先测试得出。</p>
<h5 id=inline>有关内联级别元素</h5>
<p>　　对于内联元素(可以是默认即为内联的比如 <code>span</code> 元素，也可以是 <code>display: inline</code> 的元素)</p>
<ul>
    <li><code>width</code> 和 <code>height</code> 只在 IE5.x 下和 IE6 的 quirks 模式下触发 <code>hasLayout</code> 。因为在 IE6 中，如果浏览器运行于标准兼容模式下，内联元素会忽略 width 或 height 属性，所以设置 width 或 height 不能在此种情况下令该元素具有 layout。
    <li><code>zoom</code> 总是可以触发 <code>hasLayout</code>，但是在 IE5.0 中不支持。 </li>
</ul>
<p>　　具有&#8220;layout&#8221; 的元素如果同时也 <code>display: inline</code> ，那么它的行为就和标准中所说的 inline-block 很类似了：在段落中和普通文字一样在水平方向和连续排列，受 vertical-align 影响，并且大小可以根据内容自适应调整。这也可以解释为什么单单在 IE/Win 中内联元素可以包含块级元素而少出问题，因为在别的浏览器中 <code>display: inline</code> 就是内联，不像 IE/Win 一旦内联元素拥有 layout 还会变成 inline-block。</p>
<h5 id=haslayoutprop>脚本属性 hasLayout</h5>
<p>　　我们这里称 hasLayout 为&#8220;脚本属性&#8221;是为了和我们熟知的 CSS 属性相区别。</p>
<p>　　注意一旦一个元素拥有了 layout，就没有办法再将其设成 <code>hasLayout = False</code> 了。</p>
<p>　　<a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp"><u><font color=#0066cc>hasLayout-property</font></u></a> 可以用来检测一个元素是否拥有 layout：举个例子，如果它的 <code>id</code> 是&#8220;eid&#8221;，那么只要在 IE5.5+ 的地址栏里输入 <code class=c1>javascript: alert(eid.currentStyle.hasLayout)</code> 即可检测它的状态。</p>
<p>　　IE的 <a title=MS提供的下载 href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en"><u><font color=#0066cc>Developer Toolbar</font></u></a> 可以实时检查一个元素的当前样式；如果 <code>hasLayout</code> 是 true ，那么它的值显示为 &#8220;-1&#8221;。 我们可以通过实时修改一个元素的属性将&#8220;zoom(css)&#8221;设置为&#8220;1&#8221;来触发 <code>hasLayout</code> 以便调试。</p>
<p>　　另外一个需要注意的是&#8220;layout&#8221;会影响脚本编程。如果一个元素没有&#8220;layout&#8221;，那么<code>clientWidth</code>/<code>clientHeight</code> 总是返回0。这会让一些脚本新手感到困惑，而且这和 Mozilla 浏览器的处理方式也不一样。不过我们可以利用这一点在 IE5.0 中检测&#8220;layout&#8221;：如果 <code>clientWidth</code> 是零那么这个元素就没有 layout。</p>
</div>
<h4 id=hack>CSS hacks</h4>
<p>　　下面用于触发 <code>haslayout</code> 的 hack 已经经过 IE6 及以下版本测试。今后版本的IE有可能会对此做不同处理。如果新版本浏览器发布我们会重新整理这部分内容。</p>
<p>　　John Gallant 和 Holly Bergevin 在2003年发布的 <a title=发表于communitymx href="http://www.communitymx.com/content/article.cfm?page=2&amp;cid=C37E0"><u><font color=#0066cc>Holly hack</font></u></a> ：</p>
<pre class=code>/* \*/
* html .gainlayout { height: 1%; }
/* */	</pre>
<ul>
    <li>可以让 IE5+ 的任意元素获得 layout，除了标准兼容模式 IE6 中的内联元素。
    <li>一般都很有效，除了在某些极少情况下，需要用 height:0 或者 1px 更好一些。
    <li>和 <code>overflow: hidden</code> 不相容，除非在 IE6 的标注兼容模式下(因为这时如果父元素没有定高，那么<code>height: 1%</code> 会被变回 <code>height: auto</code>)。 </li>
</ul>
<p>　　或者我们可以用 <a title="查看WellStyled Workshop中的文章" href="http://wellstyled.com/singlelang.php?lang=en&amp;page=css-underscore-hack.html"><u><font color=#0066cc>underscore hack</font></u></a>:</p>
<pre class=code>.gainlayout { _height: 0; }</pre>
<p>　　另外，更具有向后兼容性的方法是使用 <a title=查看MSDN href="http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp"><u><font color=#0066cc>条件注释(conditional comments)</font></u></a>:</p>
<pre class=code>&lt;!--[if lte IE 6]&gt;
&lt;style&gt;
.gainlayout { height: 1px; }
&lt;/style&gt;
&lt;![endif]--&gt;</pre>
<p>　　在条件注释中链接一个专门对 IE/Win 做修正的外部样式表文件，也不失为一个安全有效的好方法：</p>
<pre class=code>&lt;link rel="stylesheet" href="allbrowsers.css" type="text/css" /&gt;
&lt;!--[if lte IE 6]&gt;
&lt;link rel="stylesheet" href="iefix.css" type="text/css" /&gt;
&lt;![endif]--&gt;</pre>
<p>　　我们更倾向于使用 <code>height: 0</code> 和 <code>1px</code> —— 并主张始终使用 <code>height</code> 除非它和别的什么东西冲突 (<code>overflow: hidden</code>)。对于取值，我们则倾向于避免 <code>1%</code> ，因为它可能会(虽然很少)引起<a title=看看Fassino的测试样例 href="http://www.brunildo.org/test/relayout.html"><u><font color=#0066cc>一些问题</font></u></a>。</p>
<p>　　一个需要注意的情况是如果我们希望一个元素保持内联，那么就不能使用 <code>height</code> 了，这时可以用 <code>display: inline-block</code> 。我们只在早期调试阶段用 <code>zoom: 1</code> 来避免一些渲染错误。</p>
<p>　　我们曾看过一些把 Holly hack 真的当作 holy(神圣的) hack 盲目使用的情况，比如对浮动元素使用或者对已经具有特定宽度的元素也使用这个 hack。要记住这个 hack 的目的不是要给某个元素加一个高度，而只是要触发 <code>hasLayout = True</code> 而已。</p>
<p>　　不要给所有元素设置 layout：<code>* {_height: 1px;}</code>。所谓过犹不及，获得 layout 不等于获得灵丹妙药，它只是用来改变渲染模式。</p>
<div class=alpha>
<h5 id=hackmanagement>Hack整理</h5>
<p>　　但是浏览器总是会变的，我们需要面对很多问题，比如一些依赖 IE6 的 bug 所做的 hack 会在 IE7 或更高版本的新浏览器中因 bug 修复而失效(甚至有害)的问题；比如新版本浏览器中类似的布局 bug 依然存在但用于 hack 的过滤器比如 <code>* html</code> 却不能正常工作的问题。这种情况下，MS专有属性 <code>zoom</code> 就可以考虑使用了。</p>
<pre class=code>&lt;!--[if lt IE 7]&gt;&lt;style&gt;
/* IE 6 + IE5.5 + IE5.0 所用样式*/
.gainlayout { height: 0; }
&lt;/style&gt;&lt;![endif]--&gt;
&lt;!--[if IE 7]&gt;&lt;style&gt;
.gainlayout { zoom: 1;}
/* 或者其他任何以后可能需要的东西 */
&lt;/style&gt;&lt;![endif]--&gt;</pre>
<ul>
    <li><code>zoom: 1;</code> 可以让 IE5.5+ 的任何元素(包括内联元素)获得 layout，但是在 IE5.0 中无效。
    <li>没有其他附带效果(内联元素会变成 inline-block，这个当然)。
    <li>如果需要通过验证，应该用条件注释将 <code>zoom</code> 隐藏起来。 </li>
</ul>
<p>　　其实当我们考虑到&#8220;向后兼容&#8221;时是很自相矛盾的，我们强烈建议页面设计者回过头看一下自己页面中用的到的明显的或是不明显的&#8220;hacks&#8221;，并用条件注释针对不同浏览器重新处理以保万无一失。</p>
</div>
<h4 id=iemac>关于IE Mac 的小问题</h4>
<p>　　IE Mac 和 windows 下的 IE 是完全不同的两个东西，它们各自拥有自己的渲染引擎，IE Mac 就全然不知&#8220;hasLayout&#8221;(或contenteditable)所谓何物。相比之下 IE Mac 的渲染引擎要更标准兼容一点，比如 <code>height</code> 就是被当作 <code>height</code> 处理，没有别的效果。因此针对&#8220;hasLayout&#8221;的 hacks 和别的解决方法(特别是通过使用 <code>height</code> 或 <code>width</code> 属性的)往往对 IE Mac 来说是有害的，所以需要对其隐藏。更多的关于 IE Mac 相关的问题可以在 <a title="CSS problems in IE Mac" href="http://www.l-c-n.com/IE5tests/"><u><font color=#0066cc>IE Mac, bugs and oddities pages</font></u></a> 找到。</p>
<h4 id=docu>MSDN 文档</h4>
<p>　　MSDN 中涉及到 hasLayout 这个 MS 属性的地方寥寥无几，而具体解释 layout 和 IE 渲染模型之间关系的则少之又少。</p>
<p>　　在IE4的时候，除了未经绝对定位也未指定宽高的内联元素，几乎所有元素都有某种 layout(<a title="查看MSDN中的 measurement and location overview" href="http://msdn.microsoft.com/workshop/author/css/overview/measurementandlocation.asp"><u><font color=#0066cc>MSDN</font></u></a>)。在这种早期的layout概念中，像 <code>border, margin, padding</code> 这些属性被称作&#8220;layout属性&#8221;，它们是不能应用到一个简单的内联元素上的。换句话说，&#8220;拥有layout&#8221;就可以粗略理解成：&#8220;可以拥有这几个属性&#8221;。</p>
<p>　　MSDN 上仍然使用 layout 属性这种说法， 只是含义变了，它们和拥有 layout 的元素已经没有什么关系了。在 IE5.5 中方才引入了 MS 的这个专有属性 <a title=查看MSDN中的属性描述 href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/haslayout.asp"><code><u><font color=#0066cc>hasLayout</font></u></code></a>，也只是某种内部的标志位而已。</p>
<p>　　在 IE5.5 中，MSHTML Editing Platform(即可以通过设置<code>&lt;body contenteditable=true&gt;</code>来允许用户实时编辑、拖动 layout 元素以及调整其尺寸等)的文档中描述了三个和 layout 相关的重要特性：</p>
<div class=quote>
<blockquote title="来自MSDN规范： Editing Platform" cite=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/mshtmleditplatf.asp>
<p>　　如果一个 layout 元素中有内容，内容的排版布局将由它的边界矩形框决定。</p>
<p>　　拥有 layout 的意思基本上就是表示某元素是一个矩形。</p>
<p>　　从内部来说，拥有 layout 意思就是一个元素将自己负责绘制其内部内容。</p>
</blockquote>
<p class=blockquotesource>(<a title=查看MSDN规范 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/mshtmleditplatf.asp"><u><font color=#0066cc>Editing Platform</font></u></a>)</p>
</div>
<p>　　和 layout 自身相关的内部工作机制直到2005年8月才有相应文档描述，当时由于 <a title="meet the WaSP" href="http://www.webstandards.org/"><u><font color=#0066cc>The Web Standards Project</font></u></a> 和微软的特别工作小组的原因，Markus Mielke [MSFT] 打开了深入讨论的大门：</p>
<div class=quote>
<blockquote title="来自MSDN规范：Filters and Transitions" cite=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/cols/dnexpie/expie20050831.asp>
<p>　　一般来说，在 Internet Explorer 的 DHTML 引擎中，元素是不对自己的位置安排负责的。虽然一个 div 或者一个 p 元素都在源码中有一个位置，在文档流有一个位置，但是它们的内容却是由它们最近的一个 layout 祖先(经常是 body)控制安排的。这些元素依赖它们祖先的 layout 来为他们处理诸如决定大小尺寸和测量信息等诸多繁重的工作。</p>
</blockquote>
<p class=blockquotesource>(<a title=查看MSDN中的文章 href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/cols/dnexpie/expie20050831.asp"><u><font color=#0066cc>HasLayout概述</font></u></a>)</p>
</div>
<h4 id=interpr>分析</h4>
<p>　　我们的分析试图解释在已知案例下发生了什么事情，这种分析也应该可以作为未知案例下的指导。但我们这种试图利用种种测试案例投石探路的黑箱测试方法，是注定无法消除黑箱的神秘感的——我们无法回答&#8220;为什么&#8221;的问题。我们只能去尝试了解整个&#8220;hasLayout&#8221;模式的工作框架，以及它会怎样影响网页文档的渲染。因此，最终我们只能提供一些<em>指导方针</em>(而且只能是指导方针，而不是绝对的解决方案)。</p>
<p>　　我们认为他们所指的是一个小窗体。一个 layout 元素的内部内容是完全独立的，而且也无法影响其边界外的任何内容。</p>
<p>　　而 MS 属性 layout 只是某种标志位：一旦它被设定，这个元素就会拥有其特殊的 layout&#8220;特性&#8221;，这包括体现在其自身以及其非 layout 孩子身上的浮动、清除浮动、层叠、计数等等诸多方面的特殊性能。</p>
<p>　　这种独立性也许正可以解释为什么 layout 元素通常比较稳定，而且它们可以让某些 bug 消失。这种情况的代价有二，一是偏离了标准，二是它没有考虑到今后可能因此出现的 bug 和问题。</p>
<p>　　MS 的&#8220;页面&#8221;模式，从符号学角度考虑，可以看做是由很多互不相关的小的区块构成，而 HTML 和 W3C 的模式则认为&#8220;页面&#8221;模式应该是叙述完备的，故事性的相关信息区块构成的。</p>
<h4 id=rev>各种情况的详细说明</h4>
<div class=alpha>
<h5 id=clear>清除浮动和自动扩展适应高度</h5>
<p>　　浮动元素会被 layou 元素自动包含。这是很多新手经常遇到的问题：在 IE 下完成的页面到了标准兼容浏览器下所有未清除的浮动元素都伸出了其包含容器之外。</p>
<ul>
    <li><a title="查看Eric Meyer的文章" href="http://www.complexspiral.com/publications/containing-floats"><u><font color=#0066cc>Containing Floats</font></u></a>
    <li><a title=查看PIE上的文章 href="http://positioniseverything.net/easyclearing.html"><u><font color=#0066cc>how to clear floats without structural markup</font></u></a> </li>
</ul>
<p>　　相反的情况：如果确实需要一个浮动元素伸出其包含容器，也就是自动包含不是想要的效果时，该怎么办？你很可能也会遇到这种头疼的问题，下面的深入讨论就是一个例子：</p>
<ul>
    <li><a title=因haslayout触发的多此一举的浮动包含问题 href="http://www.satzansatz.de/cssd/acidicfloat.html"><u><font color=#0066cc>acidic float tests</font></u></a> </li>
</ul>
<p>　　在IE中，一个浮动元素总是&#8220;隶属于&#8221;它的 layout 包含容器。而后面的元素会受这个 layout 包含容器影响而不是这个浮动元素影响。</p>
<p>　　这个特性和IE6的那个自动扩展以适应内部内容宽度的特性，都可以看成是受这个规则影响的：&#8220;由它的边界矩形框决定&#8221;。</p>
<p>　　更糟的问题：<code>clear</code> 无法影响其 layout 包含容器之外的 float 元素。如果依赖这个 bug 在 IE 中布局的页面要转到标准兼容浏览器中，只有全部重做。</p>
<p>　　更多相关信息查看本文 &#8220;<a href="http://www.sharkui.com/articles/article.php?id=38#engineer"><u><font color=#0066cc>和 CSS 规范类似的地方</font></u></a>&#8221; 这一部分。</p>
<h5 id=nextfloat>浮动元素旁边的元素</h5>
<p>　　当一个块级元素紧跟在一个左浮动元素之后时，其中的文字内容应该沿着浮动元素的右边顺序排列并会滑到浮动元素下方。但是如果这个块级元素有 layout，比如由于某种原因被设置了宽度，那么这个 layout 元素就会表现为一个矩形，其中文字不会滑向浮动元素下方。其宽度也被错误计算——从浮动元素的右边开始算起了，所以如果给它设置 <code>width: 100%</code> 将会导致显示时这个 block 的宽度加上了浮动元素的宽度而出现横向滚动条。这种表现就和规范中描述的相去甚远了。</p>
<p>　　与此类似，和浮动元素相邻的相对定位元素，它的位置偏移量应该参照的是父元素的补白(padding)边缘(例如，<code>left: 0;</code> 应该将一个相对定位元素叠放于它前面的浮动元素之上)。在IE中，偏移量 <code>left: value;</code> 是从浮动元素的右边距(margin)边缘开始算起的，这会因浮动元素所占的宽度变化导致水平方向的错位(一个解决方法是用 <code>margin-left</code> 代替，但是也要注意如使用百分值时会有一些怪异问题)。</p>
<p>　　根据规范所述，浮动元素应该与其后的盒子<em>交织</em>在一起。而对于没有交叉的二维空间中的矩形而言这是无法实现的。</p>
<p>　　可以(再次)访问下面这个页面：</p>
<ul>
    <li><a title=查看PIE上的文章 href="http://positioniseverything.net/explorer/threepxtest.html"><u><font color=#0066cc>three pixel text-jog</font></u></a> </li>
</ul>
<p>　　我们可以看到跟在一个浮动元素后的 layout 元素不会显示这个3px间隙的 bug，因为浮动元素外围的3px硬边无法影响一个 layout 元素的内部内容，所以这个硬边将整个 layout 元素右推了3px。好比一个防护罩，layout 可以保护其内部内容不受影响，但是浮动元素的力量却将整个防护罩推了开来。</p>
<p>　　更多相关信息查看本文 &#8220;<a href="http://www.sharkui.com/articles/article.php?id=38#engineer"><u><font color=#0066cc>和 CSS 规范类似的地方</font></u></a>&#8221; 这一部分</p>
<h5 id=list>列表</h5>
<p>　　无论是列表本身(<code>ol, ul</code>) 还是单个的列表元素(<code>li</code>)，拥有 layout 后都会影响列表的表现。不同版本 IE 的表现又有不同。最明显的效果就体现在列表符号上(如果你的列表自定义了列表符号则不会受这个问题影响)。这些符号很可能是通过某种内部机制附到列表元素上的(通常是附着在它们外面)。不幸的是，由于是通过&#8220;内部机制&#8221;添加的，我们无法访问它们也无法修正它们的错误表现。</p>
<p>　　最明显的效果有：</p>
<ul>
    <li>列表获得 layout 后，列表符号会消失或者被放置在不同的或者错误的位置。 </li>
</ul>
<p>　　有时它们又可以通过改变列表元素的边距而重新出现。这看起来似乎是以下事实导致的结果：layout 元素会试图裁掉超出其边界的内部内容。</p>
<ul>
    <li>列表元素获得 layout 之后，会有和上面一样的问题出现，更多参考 (<a title="查看Bruno Fassino的测试样例" href="http://www.brunildo.org/test/IEWlispace.php"><u><font color=#0066cc>extra vertical space between list items</font></u></a>) </li>
</ul>
<p>　　进一步又有一个问题就是(在有序列表中)任何具有 layout 的列表元素似乎都有自己独立的计数器。比如我们有一个含五个列表元素的有序列表，只有第三个列表元素有 layout。我们会看到这样：</p>
<p>　　1&#8230; 2&#8230; 1&#8230; 4&#8230; 5&#8230;</p>
<p>　　此外，如果一个有 layout 的列表元素跨行显示时，列表符号会底部对齐(而不是按照预料的顶部对齐)。</p>
<p>　　以上某些问题还是无法解决的，所以如果需要列表符号的时候最好避免让列表和列表元素获得 layout。如果需要限定尺寸，最好给别的元素设定尺寸，比如给整个列表外面套一个元素并设定它的宽度，又或者比如给每个列表元素中的内容设定高度等等。</p>
<p>　　另一个IE中列表的常见问题出现在当某个 <code>li</code> 中的内容是一个 <code>display: block</code> 的锚点(anchor)时。在这种情况下，列表元素之间的空格将不会被忽略而且通常会显示成额外的一行夹在每个 <code>li</code> 之间。一种避免这种竖直方向多余空白的解决方法是赋予这些锚点 layout。这样还有一个好处就是可以让整个锚点的矩形区域都可以响应鼠标点击。</p>
<h5 id=tab>表格</h5>
<p>　　<code>table</code> 总是有 layout 的，它总表现为一个已定义宽度的对象。在IE6中，<a title=查看MSDN href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/tablelayout.asp"><code><u><font color=#0066cc>table-layout: fixed</font></u></code></a> 通常和一个宽度设为100%的表格相同，同时这也会带来很多问题(一些计算方面的错误)。另外在IE5.5和IE6的quirks模式下<a title="查看 Philippe Wittenbergh 的文章" href="http://dev.l-c-n.com/tables_2/"><u><font color=#0066cc>还有一些别的需要注意的情况</font></u></a>。</p>
<h5 id=rp>相对定位元素(r.p.)</h5>
<p>　　注意，由于 <code>position: relative</code> 并不触发 hasLayout，所以很多诸如内容消失或错位的渲染错误就会因此而起。这些现象可能会在刷新页面、调整窗口大小、滚动页面、选中内容等情况下出现。原因是 IE 在据这个属性对元素做偏移处理时，却似乎忘了发出信号让其 layout 孩子元素进行&#8220;重绘&#8221;(而如果是一个layout元素，那么在其重绘事件的信号链中，这个传给其孩子的信号是会正常发出的)。</p>
<ul>
    <li><a title="查看 Ingo Chao 的文章" href="http://www.satzansatz.de/cssd/rpfloat.html"><u><font color=#0066cc>r.p. parent and disappearing floated child</font></u></a>
    <li><a title="查看 PIE 上的文章" href="http://positioniseverything.net/explorer/ie-listbug.html"><u><font color=#0066cc>disappearing list-background bug</font></u></a> </li>
</ul>
<p>　　以上是一些相关问题的描述。作为经验之谈，相对定位一个元素时最好给予其 layout。再有，我们也需要检查拥有这种结构的父元素是否也需要 layout 或者<code>position: relative</code>亦或二者都需要，如果涉及到浮动元素这点就十分重要。</p>
<h5 id=cb>绝对定位元素(a.p.)：<br><span>包含区块，什么是包含区块？</span></h5>
<p>　　理解 CSS 的包含区块概念很重要，它回答了绝对定位元素是相对哪里定位的问题：包含区块决定了偏移起点，包含区块定义了百分比长度的计算参考。</p>
<p>　　对于绝对定位元素，包含区块是由其最近的定位祖先决定的。如果其祖先都没有被定位，那么就使用初始包含区块 <code>html</code>。</p>
<p>　　通常情况下我们会用 <code>position: relative</code> 来设定任意包含区块。这就是说，我们可以让一个绝对定位元素所参考的原点和长度等不依赖于元素的排列顺序，这可以满足诸如&#8220;内容优先&#8221;这种可访问性概念的需要，也可以给复杂的浮动布局带来方便。</p>
<p>　　但是由于 layout 概念的存在，这种设计理念的效果在IE中就要打个问号了。因为在IE中绝对定位的元素是相对于其最近的 <em>layout 定位</em>祖先而做偏移的，而百分比的尺寸却是参考这个 layout 定位祖先的下一个 <em>layout</em> 祖先计算的。注意这里的小差别，还有刚才提到 <code>position: relative</code> 是不会触发 hasLayout 的。</p>
<p>　　假设一个无 layout 的父元素被相对定位了——我们就得给它赋予 layout 才能使偏移量起作用：</p>
<ul>
    <li><a title="查看 PIE 上的文章" href="http://www.positioniseverything.net/abs_relbugs.html"><u><font color=#0066cc>Absolutely Buggy II</font></u></a> </li>
</ul>
<p>　　假设一个未定位的父元素需要特定尺寸，而且页面设计是基于百分比宽度的——我们就可以放弃这个想法了，因为浏览器支持不佳：</p>
<ul>
    <li><a title="查看 Ingo Chao 的测试样例" href="http://www.satzansatz.de/cssd/tmp/apboxpercentagewidth.html"><u><font color=#0066cc>absolutely positioned element and percentage width</font></u></a> </li>
</ul>
<h5 id=filter>滤镜</h5>
<p>　　MS专有的滤镜属性 <a title="查看 MSDN 规范" href="http://msdn.microsoft.com/workshop/author/filter/filters.asp"><u><font color=#0066cc>filter</font></u></a> 是只适用于 layout 元素的。有些滤镜扩展了对象的边界。它们会显示出自身特有的<a title="查看 Ingo Chao 如何试图使它们正常工作" href="http://www.satzansatz.de/cssd/tmp/alphatransparency.html"><u><font color=#0066cc>缺陷</font></u></a>。</p>
<h5 id=reflow>对已渲染元素的重排(re-flow)</h5>
<p>　　当所有元素都已渲染完成时，如果有一个因鼠标经过而引起的变化产生(比如某个链接的 <code>background</code> 有变化)，IE会对其 layout 包含区块进行重排。有时一些元素就会因此被排到了新的位置，因为当这个鼠标经过发生时，IE已经知道了所有相关元素的宽度、偏移量等数据了。这在文档首次载入时则不会发生，那时由于自动扩张的特性，宽度还无法确定。这种情况会导致在鼠标经过时页面出现跳变。</p>
<ul>
    <li><a title='查看 Ingo Chao 关于"伪CSS"的相关文章' href="http://www.satzansatz.de/cssd/pseudocss.html#hoverjump"><u><font color=#0066cc>Jump on :hover</font></u></a>
    <li><a title="查看 PIE 上文章" href="http://www.positioniseverything.net/explorer/percentages.html"><u><font color=#0066cc>quirky percentages: the reflow</font></u></a> </li>
</ul>
<p>　　这些和重排问题相关的 bug 会给百分比边距和补白使用较多的流动布局带来不少麻烦。</p>
<h5 id=bgorigin>背景原点</h5>
<p>　　MS专有的这个 hasLayout 还会影响背景的定位和扩展。比如，根据 <a title="查看 W3C 规范" href="http://www.w3.org/TR/CSS21/colors.html#q2"><u><font color=#0066cc>CSS 规范</font></u></a>，<code>background-position: 0 0</code> 应该指元素的&#8220;补白边缘(padding edge)&#8221;。而在 IE/Win 下，如果 <code>hasLayout = false</code> 则指的是&#8220;边框边缘(border edge)&#8221;，当 <code>hasLayout=true</code> 时指的才是补白边缘：</p>
<ul>
    <li><a title="查看 Bruno Fassino 的文章" href="http://www.brunildo.org/test/BackgroundBorderLayout.html"><u><font color=#0066cc>Background, Border, hasLayout</font></u></a> </li>
</ul>
<h5 id=uncollapse>边距重叠</h5>
<p>　　<code>hasLayout</code> 会影响一个盒子和其子孙的边距重叠。根据规范，一个盒子如果没有上补白和上边框，那么它的上边距应该和其文档流中的第一个孩子元素的上边距重叠：</p>
<ul>
    <li><a title="查看 W3C 规范" href="http://www.w3.org/TR/CSS21/box.html#collapsing-margins"><u><font color=#0066cc>Collapsing Margins</font></u></a>
    <li><a title="查看 Eric Meyer 的文章" href="http://complexspiral.com/publications/uncollapsing-margins"><u><font color=#0066cc>Uncollapsing Margins</font></u></a> </li>
</ul>
<p>　　在 IE/Win 中如果这个盒子有 layout 那么这种现象就不会发生了：似乎拥有 layout 会阻止其孩子的边距伸出包含容器之外。此外当 <code>hasLayout = true </code>时，不论包含容器还是孩子元素，都会有边距计算错误的问题出现。</p>
<ul>
    <li><a title="查看 Bruno Fassino 的文章" href="http://www.brunildo.org/test/IEMarginCollapseLayout.html"><u><font color=#0066cc>Margin collapsing and hasLayout</font></u></a> </li>
</ul>
<h5 id=link>块级别的链接</h5>
<p>　　hasLayout 会影响一个块级别链接的鼠标响应区域(可点击区域)。通常 hasLayout = false 时只有文字覆盖区域才能响应。而 hasLayout = true 则整个块状区域都可响应。添加了 onclick/onmouseover 等事件的任意块级元素也有同样的现象。</p>
<ul>
    <li><a title="查看 Bruno Fassino 的文章" href="http://www.brunildo.org/test/IEABlock1.html"><u><font color=#0066cc>Block anchors and hasLayout</font></u></a> </li>
</ul>
<h5 id=inpage>在页面内使用键盘浏览：探索中</h5>
<p>　　当使用 tab 在页面中浏览时，如果进入了一个页内链接(in-page link)，那么接下来再按的 <kbd>tab</kbd> 键就不会正常继续了：</p>
<ul>
    <li><a title="查看 Jim Thatcher 的文章" href="http://jimthatcher.com/news.htm#haslayout"><u><font color=#0066cc>hasLayout Property Characterizes IE6 Bug</font></u></a>
    <li><a title="查看 Gez Lemon 的文章" href="http://juicystudio.com/article/ie-keyboard-navigation.php"><u><font color=#0066cc>Keyboard Navigation and Internet Explorer</font></u></a> </li>
</ul>
<p>　　<kbd>tab</kbd> 键会把用户带到(这通常是错误的)其最近的 layout 祖先中的第一个目标(如果这个祖先是由 <code>table</code>， <code>div</code>， <code>span</code> 或某些别的标签构成)。</p>
</div>
<h4 id=stack>堆叠，分层和 layout </h4>
<p>　　IE/Win 中似乎有两种分层和堆叠顺序：</p>
<ul>
    <li>一种是(伪)试图采用CSS的模式：<a title="查看 Aleksandar Vacic 的系列文章" href="http://www.aplus.co.yu/css/z-pos/"><u><font color=#0066cc>Effect of z-index value to RP and AP blocks</font></u></a>
    <li>还有一种是由&#8220;hasLayout&#8221;及其孪生兄弟&#8220;contenteditable&#8221;的行为产生的堆叠顺序。正如在上面相对定位的例子中展现的那样，在 layout 影响下的堆叠现象就好像 Harry Houdini (译者注：魔术师，以纸牌魔术成名)的拿手戏法儿一样。 </li>
</ul>
<p>　　两种堆叠模式虽互不相容，但却共存于IE的渲染引擎中。经验之谈：调试的时候，两种情况都要考虑到。我们可能会有规律地在下拉菜单或者类似的复杂菜单中看到相关问题，因为它们往往牵涉到堆叠，定位和浮动等诸多令人头疼的问题。给那些 z-index 定位的元素 layout 是一种可能的修正方法，不过也不限于此，这里只是提醒一下。</p>
<h4 id=contenteditable>混乱的 contenteditable</h4>
<p>　　如果给一个 HTML 标签设定 <code>contenteditable=true</code> 属性，比如<code>&lt;body contenteditable=true&gt;</code>，将会允许对该元素以及其 layout 子元素进行实时的编辑、拖动改变尺寸等操作。你可以把这属性用在浮动元素或者一个有序列表中的 layout 列表元素上看看效果。</p>
<p>　　为了对元素进行操作(编辑它们)，&#8220;contenteditable&#8221;和&#8220;hasLayout&#8221;为那些 <code>hasLayout</code> 返回 <code>true</code> 的元素引入了一套单独的堆叠顺序。</p>
<p>　　<a title="查看 MSDN 规范" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmshtml/html/mshtmleditplatf.asp"><u><font color=#0066cc>Editing Platform</font></u></a> 继承了 layout 概念，对 layout 的误解多是因 contenteditable 而起即可作为证明(那些某种程度上集成了IE编辑引擎的应用软件多暗含着对layout概念的某种强制向后兼容性)。</p>
<ul>
    <li><a title="查看 Anne van Kesteren 的blog条目" href="http://annevankesteren.nl/2005/07/more-contenteditable"><u><font color=#0066cc>More on contenteditable</font></u></a> </li>
</ul>
<h4 id=engineer>和 CSS 规范类似的地方</h4>
<p>　　你的 MSIE 页面在别的浏览器中一团糟？我们可没必要让这种事情发生。如果使用恰当，任何好的浏览器都能摆平 MSIE 的页面——只要你使用一些正确的 CSS。</p>
<p>　　利用 <code>hasLayout</code> 和&#8220;<a title="CSS 2.1 规范 - 9.4.1" href="http://www.w3.org/TR/CSS21/visuren.html#q15"><u><font color=#0066cc>新的块级格式内容</font></u></a>&#8221;之间的<em>细微</em>相似之处，我们可以有几种方法在标准兼容浏览器中重新实现 <code>hasLayout</code> 的&#8220;<a title="Visual formatting model details - 10.6.7" href="http://www.w3.org/TR/CSS21/visudet.html#root-height"><u><font color=#0066cc>包含浮动元素</font></u></a>&#8221;效果，和一些&#8220;<a title="Visual formatting model - 9.5" href="http://www.w3.org/TR/CSS21/visuren.html#floats"><u><font color=#0066cc>浮动元素旁边的元素</font></u></a>&#8221;所特有的效果。</p>
<ul>
    <li><a title="查看 Georg S?rtun 的系列文章" href="http://www.gunlaug.no/contents/wd_example_01.html"><u><font color=#0066cc>Reverse engineering series</font></u></a>
    <li><a title="查看 Philippe Wittenbergh 模拟的 hasLayout：overflow，display:table，新的块级格式内容" href="http://dev.l-c-n.com/IEW/simulations.php"><u><font color=#0066cc>Simulations</font></u></a> </li>
</ul>
<h4 id=quirk>Quirks 模式</h4>
<p>　　某些 <a title="Henri Sivonen: Activating the Right Layout Mode Using the Doctype Declaration" href="http://hsivonen.iki.fi/doctype/"><u><font color=#0066cc>doctype</font></u></a>，或者 <code>&lt;xml&gt;</code> 声明，在 IE6 中会触发&#8220;quirks模式&#8221;或曰向后兼容模式。在这种模式下，IE6 就像 IE5.5，并且和它老弟拥有一样的bug，一样的问题和一样的行为。</p>
<p>　　而对于IE7，<code>&lt;xml&gt;</code> 声明不会再改变渲染模式了；要触发 quirks 模式，我们不得不插入一个注释才行。(IE7 的 quirks 模式和 IE6 的 quirks 模式是否一样还有待验证)</p>
<pre class=code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!-- ... 让 IE7 运行在 quirks 模式 --&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;</pre>
<h4 id=conclusion>Layout — 结论</h4>
<p>　　整个 layout 概念和一些基本 CSS 概念是不兼容的，即包含，排列，浮动，定位和层叠等。</p>
<p>　　由于页面中元素或有或没有 layout，会导致 IE/Win 的行为和 CSS 规范相违背。</p>
<h4 id=bottomline>拥有 layout — 另外一个引擎？</h4>
<div class=quote>
<blockquote title="Dean Edward 关于IE7的一些说明" cite=http://dean.edwards.name/IE7/notes/#layout>
<p>　　IE 的对象模型看起来是文档模型和他们传统的应用程序模型的糅合。我之所以提到这点是因为它对于理解IE如何渲染页面很重要。而从文档模型切换到应用程序模型的开关就是给一个元素&#8220;layout&#8221;。</p>
</blockquote>
<p class=blockquotesource>(<a title=查看关于IE7的一些说明 href="http://dean.edwards.name/IE7/notes/#layout"><u><font color=#0066cc>Dean Edwards</font></u></a>)</p>
</div>
<p>　　有时候要解释清楚某种行为是不可能的：就比如 hasLayout，会根据它的状态选择两种不同渲染引擎的一种使用，而且每一种都有其自己的 bug 和怪异之处。</p>
<h4 id=absurd>不可消除的 bug</h4>
<div class=quote>
<blockquote title="Molly 说到..." cite=http://www.gunlaug.no/contents/molly_1_15.html>
<p>　　软件 bug 是由于在制作过程中对完整性和逻辑问题考虑不周等人为错误而导致的。这是人类的固有缺陷，目前还没有什么好的解决方法。</p>
<p>　　同样由于这种缺陷，任何试图不重写软件而修复 bug 的做法，都将会不可避免的导致软件中出现更复杂的bug。</p>
<p>　　所有依赖别的软件的软件——当然包括依赖操作系统，也会同样依赖他们的 bug。于是我们会从所有关联的软件中得到一连串的 bug，这也更说明找到一个无 bug 软件是几乎不可能的。</p>
</blockquote>
<p class=blockquotesource>(<a title="Molly 说到..." href="http://www.gunlaug.no/contents/molly_1_15.html"><u><font color=#0066cc>Molly, the cat?</font></u></a>)</p>
</div>
<p>　　　　本文创建于2005年6月30日，最后一次修改于2006年4月2日。</p>
<dl id=editors>
<dt>编者：
<dd><a title="Holly on PIE" href="http://positioniseverything.net/"><u><font color=#0066cc>Holly Bergevin</font></u></a>
<dd><a title="Satzansatz — CSS" href="http://www.satzansatz.de/css.html"><u><font color=#0066cc>Ingo Chao</font></u></a>
<dd><a title="Brunildo — CSS" href="http://www.brunildo.org/"><u><font color=#0066cc>Bruno Fassino</font></u></a>
<dd><a title="Big John on PIE" href="http://positioniseverything.net/"><u><font color=#0066cc>John Gallant</font></u></a>
<dd><a title="Web-carpenter and farm assistent" href="http://www.gunlaug.no/"><u><font color=#0066cc>Georg S?rtun</font></u></a>
<dd><a title="Empty Spaces" href="http://emps.l-c-n.com/"><u><font color=#0066cc>Philippe Wittenbergh</font></u></a> </dd></dl>
<dl id=support>
<dt>特别致谢给予此项目支持的：
<dd><a title="" href="http://dean.edwards.name/"><u><font color=#0066cc>Dean Edwards</font></u></a>, and <a title="bug hunter" href="http://www.gunlaug.no/contents/molly_1.html"><u><font color=#0066cc>Molly ?the cat?</font></u></a> </dd></dl>
<dl id=translation>
<dt>各种语言版本：
<dd><a href="http://www.satzansatz.de/cssd/onhavinglayout.html"><u><font color=#0066cc>Original(English)</font></u></a>
<dd><a title="" href="http://www.maujor.com/tutorial/haslayout.php"><u><font color=#0066cc>Brazilian Portuguese</font></u></a> by <a title="" href="http://www.maujor.com/"><u><font color=#0066cc>Mauricio Samy Silva</font></u></a>
<dd><a href="http://old9.blogsome.com/2006/04/11/onhavinglayout/"><u><font color=#0066cc>中文版本</font></u></a> by <a href="http://old9.blogsome.com/"><u><font color=#0066cc>old9</font></u></a> </dd></dl>
<dl id=discussion>
<dt>相关讨论：
<dd><a title="" href="http://dean.edwards.name/weblog/2005/06/layout/"><u><font color=#0066cc>dean.edwards.name/weblog/</font></u></a>
<dt>联系作者：
<dd><del class=spam>spam.</del>layout@satzansatz.de </dd></dl>
<dl id=licence>
<dt>版权说明：
<dd>本文基于<a href="http://creativecommons.org/licenses/by-nc-sa/2.0/" rel=license><u><font color=#0066cc>创作共用协议</font></u></a>发布。 </dd></dl>
<img src ="http://www.blogjava.net/Vencent/aggbug/117308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2007-05-14 12:53 <a href="http://www.blogjava.net/Vencent/articles/117308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Web  显示层技术评估  </title><link>http://www.blogjava.net/Vencent/articles/58380.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 15 Jul 2006 17:46:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/58380.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/58380.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/58380.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/58380.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/58380.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Web				显示层技术评估								名词界定								显示层的意思就是				PresentationLayer				，也翻译成表现层、展现层、展示层。								本文讨论的范围只包括采用				HTMLTemplate				的显示层技术，不包括				Echo				，				GWT(google ...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/58380.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/58380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-07-16 01:46 <a href="http://www.blogjava.net/Vencent/articles/58380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dwr配置篇web.xml</title><link>http://www.blogjava.net/Vencent/articles/37105.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Thu, 23 Mar 2006 14:41:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/37105.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/37105.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/37105.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/37105.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/37105.html</trackback:ping><description><![CDATA[
		<span class="postbody">1、最小配置 <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;servlet&gt; <br />  &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />  &lt;servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt;uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">DWRServlet</span>&lt;/servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt; <br />&lt;/servlet&gt; <br />&lt;servlet-mapping&gt; <br />  &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />  &lt;url-pattern&gt;/dwr<span style="color: rgb(102, 102, 255);">/*&lt;/url-pattern&gt; <br />&lt;/servlet-mapping&gt;</span></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />2、当我们想看DWR自动生成的测试页（Using debug/test mode）时，可在</span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />servlet中加 <br />&lt;init-param&gt; <br />  &lt;param-name&gt;debug&lt;/param-name&gt; <br />  &lt;param-value&gt;<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">true</span>&lt;/param-value&gt; <br />&lt;/init-param&gt;</div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">这个参数DWR默认是false.如果选择true.我们可以通过url <a href="http://localhost/app/dwr" target="_blank">http://localhost:port/app/dwr</a> ,你就可以看到你部署的每个DWR class。并且可以测试java代码的每个方法是否运行正常。为了安全考虑，在正式环境下你一定把这个参数设为false. <br />3、logging信息配置。 <br />在
无java.util.logging的jdk1.3下运行DWR,我们不希望强制用户加一个logging包，而是用HttpServlet.log
()方法来输出日志。如果classpath中包括logging jar包，DWR自动切换用logging输出日志。 <br />如果用HttpServlet.log()方法，以下配置是有效的。 <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;init-param&gt; <br />&lt;param-name&gt;logLevel&lt;/param-name&gt; <br />&lt;param-value&gt;DEBUG&lt;/param-value&gt; <br />&lt;/init-param&gt;</div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">有效的值是 FATAL, ERROR, WARN (the default), INFO and DEBUG <br /><br />我是喜欢用log4j输出日志，那么在log4j.properties下加，log4j.logger.uk.ltd.getahead.dwr = debug。这样可以看DWR的调试日志。 <br />4、多dwr.xml文件的配置 <br />可能有几种情况，我们一一列举。 一个servlet,多个dwr.xml配置文件；多个servlet，每个servlet对应一个或多个dwr.xml. <br />一个servlet,多个dwr.xml配置文件； <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;servlet&gt; <br />    &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />    &lt;servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt;uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">DWRServlet</span>&lt;/servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt; <br />    &lt;init-param&gt; <br />      &lt;param-name&gt;config-<span style="color: rgb(0, 0, 0);" ?="">1</span>&lt;/param-name&gt; <br />      &lt;param-value&gt;WEB-INF/dwr1.<span style="color: rgb(0, 0, 0);">xml</span>&lt;/param-value&gt; <br />    &lt;/init-param&gt; <br />    &lt;init-param&gt; <br />      &lt;param-name&gt;config-<span style="color: rgb(0, 0, 0);" ?="">2</span>&lt;/param-name&gt; <br />      &lt;param-value&gt;WEB-INF/dwr2.<span style="color: rgb(0, 0, 0);">xml</span>&lt;/param-value&gt; <br />    &lt;/init-param&gt; <br />&lt;/servlet&gt;</div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">在
这种配置下，param-name的值必须以config开头。param-name可以有&gt;=0个。如果没有param-name，那么将会读取
WEB-INF/dwr.xml。如果有大于零个param-name，那么WEB-INF/dwr.xml文件将不会被读取。 <br /><br />多个servlet，每个servlet对应一个或多个dwr.xml <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />&lt;servlet&gt; <br />   &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />    &lt;servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt;uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">DWRServlet</span>&lt;/servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt; <br />&lt;!--用classes/dwr.<span style="color: rgb(0, 0, 0);">xml</span>--&gt; <br />&lt;/servlet&gt; <br />&lt;servlet&gt; <br />   &lt;servlet-name&gt;dwr-invoker1&lt;/servlet-name&gt; <br />   &lt;servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt;uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">DWRServlet</span>&lt;/servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt; <br />   &lt;init-param&gt; <br />     &lt;param-name&gt;config-admin&lt;/param-name&gt; <br />     &lt;param-value&gt;WEB-INF/dwr1.<span style="color: rgb(0, 0, 0);">xml</span>&lt;/param-value&gt; <br />   &lt;/init-param&gt; <br />   &lt;init-param&gt; <br />     &lt;param-name&gt;debug&lt;/param-name&gt; <br />     &lt;param-value&gt;<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">true</span>&lt;/param-value&gt; <br />   &lt;/init-param&gt; <br />&lt;/servlet&gt; <br />&lt;servlet-mapping&gt; <br />   &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />   &lt;url-pattern&gt;/dwr<span style="color: rgb(102, 102, 255);">/*&lt;/url-pattern&gt; <br />&lt;/servlet-mapping&gt; <br />&lt;servlet-mapping&gt; <br />   &lt;servlet-name&gt;dwr-invoker1&lt;/servlet-name&gt; <br />   &lt;url-pattern&gt;/dwr1/*&lt;/url-pattern&gt; <br />&lt;/servlet-mapping&gt;</span></div>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">在这种情况下，我们可以根据J2EE security来控制权限，针对不同url,加不同的角色。 <br />5、dwr的几个扩展点（Plug-ins） <br />DWR对以下接口提供的默认的实现，用户可以继承DWR的默认实现类来达到我们想要的效果。但这至少需要我们读了DWR源码才能做这些工作(dwr源码很是清晰，有兴趣可以学习一下)，以后可能补存这部分。 <br /></span>
		<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%">
				<tbody>
						<tr>
								<td>
										<span class="genmed">
												<b>java代码: </b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="code">
										<div style="font-family: 'Courier New',Courier,monospace;">
												<br />uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">AccessControl</span>    <br />uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">Configuration</span><br />uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">ConverterManager</span><br />uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">CreatorManager</span><br />uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">Processor</span><br />uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">ExecutionContext</span></div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/37105.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-23 22:41 <a href="http://www.blogjava.net/Vencent/articles/37105.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读了遍DWR1.1官方文档，提取的些东西</title><link>http://www.blogjava.net/Vencent/articles/37104.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Thu, 23 Mar 2006 14:40:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/37104.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/37104.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/37104.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/37104.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/37104.html</trackback:ping><description><![CDATA[
		<span class="postbody">1、java的方法避免用 java 和 javascript的关键字。 如 try()方法 或 delete()方法。 <br />2、在你的java类中不要出现重载 avoid overloaded methods. <br />3、
在生产环境下，你可以把deprecated.js engine.js util.js
合并成一个，并放到web容器内，直接在htm,jsp中引用。
（对于java代码转换成的javascript代码也可以这么做，免得每次生成javascript代码浪费时间） <br />4、研究一下Bean
Converters。POJOjava对象必须严格按照 getProperty() setProperty()定义。Bean
Converters是按照 java对象的 get set方法工作的。DWR1.1加了Object Converters,是按private
int property;这类属性工作的。 <br />&lt;convert converter="bean" match="example.Fred"/&gt; <br />&lt;param name="exclude" value="property1, property2"/&gt; <br />&lt;/convert&gt; <br />当你这样配置时，java对象转化成的javascript对象不包括property1和property2。 <br />&lt;convert converter="bean" match="example.Fred"/&gt; <br />&lt;param name="include" value="property1, property2"/&gt; <br />&lt;/convert&gt; <br />反过来java对象转化成的javascript对象直包括property1和property2。 <br />5、&lt;convert converter="collection" match="java.util.Collection"/&gt; <br />&lt;convert converter="map" match="java.util.Map"/&gt; <br />这也是容易出问题的地方. <br />如 <br />package example; <br />public class Person{ <br />private String name; <br />get ... set <br />private List relationPerson; <br />public List setRelationPerson(List relationPerson){ <br />this.relationPerson=relationPerson; <br />} <br />} <br />&lt;convert converter="bean" match="example.Person"/&gt; <br />&lt;/convert&gt; <br />&lt;signatures&gt; <br />&lt;![CDATA[ <br />import java.util.Set; <br />import example.Person; <br /><br />Person.setRelationPerson(List&lt;Person&gt;); <br />]]&gt; <br />&lt;/signatures&gt; <br /><br />在jdk1.5泛型中有写法区别 <br /><br /><br />6、另外在Set,List等做为方法参数时也会出现混淆。返回集合类型不会出现问题，想想就知道了。 <br />如
在Test类中有 public Set testBeanSetParam(Set test)
这个方法，客户端得到的javascript方法可能是Test.testBeanSetParam(p0,callback);当我们
javascript调用这个方法时，鬼才知道怎么确定p0的类型,也不可能知道Set集合中该放什么类型的java对象，所以dwr的
special signatures syntax 确定这些集合和内容的类型 <br />&lt;signatures&gt; <br />&lt;![CDATA[ <br />import java.util.Set; <br />import example.Test; <br /><br />Test.testBeanSetParam(Set&lt;TestBean&gt;); <br />&lt;!--Test.stringStringMapParam(Map&lt;String, String&gt;);--&gt; <br />]]&gt; <br />&lt;/signatures&gt; <br />7、Creators <br />&lt;allow&gt; <br />&lt;create creator="..." javascript="..." scope="..."&gt; <br />&lt;param name="..." value="..."/&gt; <br />&lt;auth method="..." role="..."/&gt; <br />&lt;exclude method="..."/&gt; <br />&lt;include method="..."/&gt; <br />&lt;/create&gt; <br />... <br />&lt;/allow&gt; <br />为了更少的暴露业务方法，最好配置include属性。 <br />dwr支持new ,script,struts....几种集成方法，也支持static方法的调用，我觉得最好的是spring,其他感觉是处理遗留问题处理。 <br />8、engine_js 作为dwr框架客户端核心，主要完成xmlHttp或iframe的构造，我们没必要关心它如何实现。有几点创新的我们可以学习下。 <br />Call Batching 我们可以把几个客户端请求一起放送到服务器端，减少了网络交互，但要注意依存关系和他们处理的顺序。 <br />Call Ordering 同步异步调整。一般用默认的就好了。注意依存关系。 <br />Remoting Hooks 钩子，"small AOP" <br />依存关系解释。 如果 request1() request2()两个业务逻辑方法，request2方法需要用到request1方法从服务器端返回的结果。如果调用request2时，request1还没处理或还没请求。 下拉框连动可能有这个问题。 <br />9、util.js propotype.js有些重复，这让我很难受。只能改代码了，可别坏了开元协议。 <br />10、如果你的回调方法想加其他参数 <br />var dataFromBrowser = ...; <br />var callbackProxy = function(dataFromServer) { <br />callbackFunc(dataFromServer, dataFromBrowser); <br />}; <br />var callMetaData = { callback:callbackProxy }; <br />Remote.method(params, callMetaData); <br />11、dwr1.1 <br />1.1只能算一个bug消除版本，没有什么大的功能调整。源代码结构做了些调整。2.0有新的特征加入。 <br /><br />It
has a far broader scope; the major new features are accessibility
enhancements, and what now appears to be called 'Comet'.
在文档中提到了“Comet”，估计与DWR2.0作者想法类似。 <br /><br /><a href="http://forum.javaeye.com/viewtopic.php?t=19089" target="_blank">http://forum.javaeye.com/viewtopic.php?t=19089</a><br /><br />楼主叫server push。 <br /><br /><a href="http://alex.dojotoolkit.org/?p=545" target="_blank">http://alex.dojotoolkit.org/?p=545</a> 给正名了，叫 Comet</span>
<img src ="http://www.blogjava.net/Vencent/aggbug/37104.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-23 22:40 <a href="http://www.blogjava.net/Vencent/articles/37104.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dwr学习1</title><link>http://www.blogjava.net/Vencent/articles/37103.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Thu, 23 Mar 2006 14:39:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/37103.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/37103.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/37103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/37103.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/37103.html</trackback:ping><description><![CDATA[这段时间较闲,研究了一番dwr.发现dwr实现的AJAX有些地方确实很是先进.比如动态生成javascript代码;隐藏的http协议;javascript于java代码交互的是javascript对象(或字符串)等. <br />以下是我临时译的一些东西.本来想全译,发现dwr实在是简单,就随便写了.英文居差,现一把. <br /><br />1、DWR: Easy AJAX for JAVA <br /><br />作为一个java open source library,DWR可以帮助开发人员完成应用AJAX技术的web程序。它可以让浏览器上的javascript方法调用运行在web服务器上java方法。 <br /><br />DWR主要由两部门组成。javascript与web服务器通信并更新web页；运行在web服务器的Servlet处理请求并把响应发回浏览器。 <br /><br />DWR
采用新颖的方法实现了AJAX(本来也没有确切的定义)，在java代码基础上动态的生成javascript代码。web开发者可以直接调用这些
javascript代码，然而真正的代码是运行在web服务器上的java code。出与安全考虑，开发者必须配置哪些java
class暴露给DWR.(dwr.xml) <br /><br />这种从(java到javascript)调用机制给用户一种感觉，好象常规的RPC机制，或RMI or SOAP.但是它运行在web上，不需要任何浏览器插件。 <br /><br />DWR
不认为浏览器和web服务器之间协议重要，把系统界面放在首位。最大挑战是java method
call的同步特征与ajax异步特性之间的矛盾。在异步模型里，结果只有在方法结束后才有效。DWR解决了这个问题，把回调函数当成参数传给方法，处理
完成后，自动调用回调方法。 <br /><br />这个图表显示了，通过javascript事件，DWR能改变select的内容，当然这些内容由
java代码返回。 javascript函数Data.getOptions(populateList)由DWR动态生成，这个函数会调用java
class
Data类的方法。DWR处理如何远程调用，包括转换所有的参数和返回的结果（javascript\java）。java方法执行完后，执行回调方法
populateList。在整个过程中我们就想在用本地的方法一样。 <br /><br />2、Getting Started <br /><br />废话少说，试试就ok了。 <br />web.xml <br /><br />&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt; <br />&lt;!DOCTYPE
web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd"&gt; <br /><br />&lt;web-app id="dwr"&gt; <br />&lt;servlet&gt; <br />&lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />&lt;servlet-class&gt;uk.ltd.getahead.dwr.DWRServlet&lt;/servlet-class&gt; <br />&lt;/servlet&gt; <br />&lt;servlet-mapping&gt; <br />&lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />&lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt; <br />&lt;/servlet-mapping&gt; <br />&lt;/web-app&gt; <br /><br />dwr.xml 与web.xml同目录 <br />&lt;?xml version="1.0" encoding="UTF-8"?&gt; <br />&lt;!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"&gt; <br />&lt;dwr&gt; <br />&lt;allow&gt; <br />&lt;create creator="new" javascript="JDate"&gt; <br />&lt;param name="class" value="java.util.Date"/&gt; <br />&lt;/create&gt; <br />&lt;/allow&gt; <br />&lt;/dwr&gt; <br /><br />index.html <br />&lt;html&gt; <br />&lt;head&gt; <br />&lt;title&gt;DWR - Test Home&lt;/title&gt; <br />&lt;script type='text/javascript' src='dwr/interface/JDate.js'&gt;&lt;/script&gt; <br />&lt;script type='text/javascript' src='dwr/engine.js'&gt;&lt;/script&gt; <br />&lt;script&gt; <br />function init(){ <br />JDate.getYear(load); <br />} <br />function load(data){ <br />alert(data+1900+'年') <br />} <br />&lt;/script&gt; <br />&lt;/head&gt; <br />&lt;body onload="init()"&gt; <br />&lt;/body&gt; <br />&lt;/html&gt; <br /><br />dwr.jar 下载放lib下 <br /><br />完了，什么，够了，就这些。访问ok! <br />3、Examples <br /><a href="http://www.aboutmyhealth.org/" target="_blank">http://www.aboutmyhealth.org/</a> 这不是Google Suggest吗!ok. <br />4、源码浅析 <br />dwr的设计很象webwork2的设计,隐藏http协议,扩展性，兼容性及强。 <br /><br />通过研究uk.ltd.getahead.dwr.DWRServlet这个servlet来研究下dwr到底是如何工作滴。 <br /><br /><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br />web.<span style="color: rgb(0, 0, 0);">xml</span>配置 <br />&lt;servlet&gt; <br />    &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />    &lt;servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt;uk.<span style="color: rgb(0, 0, 0);">ltd</span>.<span style="color: rgb(0, 0, 0);">getahead</span>.<span style="color: rgb(0, 0, 0);">dwr</span>.<span style="color: rgb(0, 0, 0);">DWRServlet</span>&lt;/servlet-<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">class</span>&gt; <br />  &lt;/servlet&gt; <br />  &lt;servlet-mapping&gt; <br />    &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt; <br />    &lt;url-pattern&gt;/dwr<span style="color: rgb(102, 102, 255);">/*&lt;/url-pattern&gt; <br />&lt;/servlet-mapping&gt;</span></div><br /></td></tr></tbody></table><span class="postbody"><br />这样所有的/dwr/*所有请求都由这个servlet来处理，它到底处理了些什么能。我们还以上面最简单的例子来看。 <br />1、 web服务器启动，DWRServlet init()方法调用，init主要做了以下工作。 <br />设置日志级别、实例化DWR用到的单例类（这些类在jvm中只有一个实例对象）、读去配置文件（包括dwr.jar包中的dwr.xml,WEB-INF/dwr.xml. config*.xml）。 <br />2、请求处理 <br />DWRServlet.doGet, doPost方法都调用processor.handle(req, resp)方法处理。Processor对象在init()方法中已经初始化了。 <br /></span><table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><span class="genmed"><b>java代码: </b></span></td></tr><tr><td class="code"><div style="font-family: 'Courier New',Courier,monospace;"><br /><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">public</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">void</span> handle<span style="color: rgb(0, 0, 0);">(</span>HttpServletRequest req, HttpServletResponse resp<span style="color: rgb(0, 0, 0);">)</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">throws</span><span style="color: rgb(170, 170, 221);" ?="">IOException</span><br />    <span style="color: rgb(0, 0, 0);">{</span><br />        <span style="color: rgb(170, 170, 221);" ?="">String</span> pathinfo = req.<span style="color: rgb(0, 0, 0);">getPathInfo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo == <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> || pathinfo.<span style="color: rgb(0, 0, 0);">length</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span> == <span style="color: rgb(0, 0, 0);" ?="">0</span> || pathinfo.<span style="color: rgb(0, 0, 0);">equals</span><span style="color: rgb(0, 0, 0);">(</span>"/"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            resp.<span style="color: rgb(0, 0, 0);">sendRedirect</span><span style="color: rgb(0, 0, 0);">(</span>req.<span style="color: rgb(0, 0, 0);">getContextPath</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span> + req.<span style="color: rgb(0, 0, 0);">getServletPath</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span> + <span style="color: rgb(0, 0, 255);">'/'</span> + "index.<span style="color: rgb(0, 0, 0);">html</span>"<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">equalsIgnoreCase</span><span style="color: rgb(0, 0, 0);">(</span>"/index.<span style="color: rgb(0, 0, 0);">html</span>"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doIndex<span style="color: rgb(0, 0, 0);">(</span>req, resp<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">startsWith</span><span style="color: rgb(0, 0, 0);">(</span>"/test/"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doTest<span style="color: rgb(0, 0, 0);">(</span>req, resp<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">equalsIgnoreCase</span><span style="color: rgb(0, 0, 0);">(</span>"/engine.<span style="color: rgb(0, 0, 0);">js</span>"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doFile<span style="color: rgb(0, 0, 0);">(</span>resp, "engine.<span style="color: rgb(0, 0, 0);">js</span>", "text/javascript"<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">equalsIgnoreCase</span><span style="color: rgb(0, 0, 0);">(</span>"/util.<span style="color: rgb(0, 0, 0);">js</span>"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doFile<span style="color: rgb(0, 0, 0);">(</span>resp, "util.<span style="color: rgb(0, 0, 0);">js</span>", "text/javascript"<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">equalsIgnoreCase</span><span style="color: rgb(0, 0, 0);">(</span>"/deprecated.<span style="color: rgb(0, 0, 0);">js</span>"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doFile<span style="color: rgb(0, 0, 0);">(</span>resp, "deprecated.<span style="color: rgb(0, 0, 0);">js</span>", "text/javascript"<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">startsWith</span><span style="color: rgb(0, 0, 0);">(</span>"/<span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">interface</span>/"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doInterface<span style="color: rgb(0, 0, 0);">(</span>req, resp<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">if</span><span style="color: rgb(0, 0, 0);">(</span>pathinfo != <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">null</span> &amp;&amp; pathinfo.<span style="color: rgb(0, 0, 0);">startsWith</span><span style="color: rgb(0, 0, 0);">(</span>"/exec"<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">)</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            doExec<span style="color: rgb(0, 0, 0);">(</span>req, resp<span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">else</span><br />        <span style="color: rgb(0, 0, 0);">{</span><br />            log.<span style="color: rgb(0, 0, 0);">warn</span><span style="color: rgb(0, 0, 0);">(</span>"Page not found. <span style="color: rgb(0, 0, 0);">In</span> debug/test mode <span style="font-weight: bold; color: rgb(153, 0, 102);" ?="">try</span> viewing /<span style="color: rgb(0, 0, 0);">[</span>WEB-APP<span style="color: rgb(0, 0, 0);">]</span>/dwr/"<span style="color: rgb(0, 0, 0);">)</span>; <br />            resp.<span style="color: rgb(0, 0, 0);">sendError</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);" ?="">404</span><span style="color: rgb(0, 0, 0);">)</span>; <br />        <span style="color: rgb(0, 0, 0);">}</span><br />    <span style="color: rgb(0, 0, 0);">}</span></div><br /></td></tr></tbody></table><span class="postbody"><br />哦。这些恍然大悟。dwr/*处理的请求也就这几种。 <br />（1）dwr/index.html，dwr/test/这种只能在debug模式下使用，调试用。 <br />dwr/engine.js，dwr/util.js，dwr/deprecated.js当这个请求到达，从dwr.jar包中读取文件流，响应回去。（重复请求有缓存） <br />（2）
当dwr/interface/这种请求到来，（例如我们在index.html中的 &lt;script
type='text/javascript'
src='dwr/interface/JDate.js'&gt;&lt;/script&gt;）DWR做一件伟大的事。把我们在WEB-
INF/dwr.xml中的 <br />&lt;create creator="new" javascript="JDate"&gt; <br />&lt;param name="class" value="java.util.Date"/&gt; <br />&lt;/create&gt; <br />java.util.Date转化为javascript函数。 <br /><a href="http://localhost/simpledwr/dwr/interface/JDate.js%E7%9C%8B%E7%9C%8B%E5%90%A7%E3%80%82" target="_blank">http://localhost:port/simpledwr/dwr/interface/JDate.js看看吧。</a><br />细节也比较简单，通过java反射，把方法都写成javascript特定的方法。（我觉得这些转换可以放到缓存里，下次调用没必要再生成一遍，不知道作者为什么没这样做）。 <br />（3）dwr/exec <br />javascript调用方法时发送这种请求，可能是XMLHttpRequest或IFrame发送。 <br />当
然，javascript调用的方法签名与java代码一致，包括参数，还有javascript的回调方法也传到了服务器端，在服务器端很容易实现。回
调方法的java的执行结果 返回类似
&lt;script&gt;callMethod(结果)&lt;script&gt;的javascript字符串,在浏览器执行。哈，一切就这么简
单，巧妙。 <br /><br />dwr的设计构思很是巧妙。 <br />第一、把java类转化为javascript类由dwr自动完成，只需简单的配置。 <br />第二、应用起来极其简单。开发者不要该服务器代码就可以集成。 <br />第三、容易测试。和webwork一样，隐藏的http协议。 <br />第四、及强扩展性。例如与spring集成，只需修改一点代码。 <br />第五、性能。就我与jason,等简单比较，dwr性能可能是最好的。 <br />第六、自动把java对象转化为javascript对象，并且及易扩展。[/code]</span><img src ="http://www.blogjava.net/Vencent/aggbug/37103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-23 22:39 <a href="http://www.blogjava.net/Vencent/articles/37103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发保留标准浏览器功能的AJAX应用程序</title><link>http://www.blogjava.net/Vencent/articles/36447.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 20 Mar 2006 13:54:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36447.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36447.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36447.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36447.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36447.html</trackback:ping><description><![CDATA[
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td height="64">时间：2006-03-14<br />
作者：<a href="http://dev2dev.bea.com.cn/author/404.html">Mark Schiefelbein</a><br />
浏览次数：
<script language="JavaScript" type="text/JavaScript" src="http://203.81.25.103/cgi-bin/beadevcount.cgi?d_id=748"></script><br />
本文关键字：<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Ajax">Ajax</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=RIA">RIA</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Rich%20Internet%20Application">Rich Internet Application</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Dev%20Toolbox">Dev Toolbox</a></td>
								<td>
										<table class="box_content" border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td>
																		<span class="h2b">文章工具</span>
																		<br />
																		<img src="http://dev2dev.bea.com.cn/images/letter001.gif" alt="推荐给朋友" align="absmiddle" height="10" width="19" /> <a href="javascript:sendmail()">推荐给朋友</a><br /><img src="http://dev2dev.bea.com.cn/images/print001.gif" alt="打印文章" align="absmiddle" height="18" width="19" /> <a href="javascript:window.print()">打印文章</a></td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<!-- 提取技术文章 -->
		<div class="beas">
				<img src="http://dev2dev.bea.com.cn/images/dot6B6B6B.gif" alt="" height="1" width="100%" />
		</div>
		<h3>摘要</h3>
		<p>Ajax应用程序由于其丰富的功能、交互性以及快速的响应能力而得到人们的普遍赞许。它可以使用XMLHttpRequest对象动态地加载数据，
而不是加载新的页面。在它大肆进行宣传以及许多人兴奋的同时，有评论指出，Ajax应用程序丢失了浏览器的一些重要功能，包括对<b>后退前进</b>按钮的支持。</p>
		<p>本文将首先阐明为什么在Ajax应用程序中除非显式地构建后退/前进按钮以及其它浏览器功能，否则它们将无法运行的原因。然后，我们将简要介绍开发
人员如何解决这些问题。最后，我们将看到有关Backbase Ajax引擎如何支持后退/前进按钮以及其它标准浏览器功能的详细情况。</p>
		<h3>Ajax应用程序是否需要后退按钮？</h3>
		<p>Ajax承诺，可以让开发人员完全基于标准的Web浏览器技术（通常是指DHTML）创建在视觉上吸引人的、高度交互式的Web应用程序。</p>
		<p>以前开发人员不得不在<b>功能丰富</b>（具有高度交互性的、吸引人的用户界面）和<b>易于到达</b>（不需要进行客户端安装就可以工作在所有Web浏览器下的前端）二者之中作出选择。而Ajax应用程序应该能够产生既“功能丰富”又“易于到达”的前端。</p>
		<p>但是一个界面怎样才算是“功能丰富”的，而一个应用程序又怎样才是“易于到达”的呢？</p>
		<p>很难精确地定义“功能丰富”的含义，但是却很容易直觉地认识到：当您看到一个界面时，您就会知道它是不是功能丰富的。象Microsoft
Office之类的桌面应用程序就是功能丰富的。功能丰富的界面使用诸如选项卡和上下文菜单这样的高级UI控件。这样的界面提供一些高级交互方法。例如，
拖放、对关注的UI元素进行高亮显示等。传统的浏览器应用程序是功能不丰富的。它们仅限于诸如表单之类的简单控件，交互主要是由到新页面的单击链接组成。
我们只要看看微软的电子邮件客户端就可以看出功能丰富和功能不丰富的区别：Outlook是功能丰富的，而Hotmail就是功能不丰富的。</p>
		<p>Ajax应用程序已经由于功能丰富而得到人们的普遍赞许。Google的Gmail就是其中最具代表性的例子。Google所开发的其它Ajax应
用程序（Google Suggest、 Google Map）、微软即将推出的名为“Kahuna”的Web邮件客户端以及<a href="http://www.backbase.com/demos/RSS">Backbase RSS Reader</a>都包含了一些高级控件和交互模块。可查看Dan Grossman的<a href="http://www.aventureforth.com/2005/09/06/top-10-ajax-applications/">Top 10  Ajax Applications</a>列表，其中给出了一个让人印象深刻的功能丰富界面的列表。</p>
		<p>通过前面的讨论，可以说Ajax应用程序很明显满足“功能丰富”的标准。那么它是不是“易于到达”的呢？</p>
		<p>首先，最基本的是，只有界面在Web浏览器中运行的应用程序才是“易于到达”的。Ajax应用程序是基于浏览器标准的，因此可以通过Web浏览器来访问。</p>
		<p>但是，仅仅可以通过Web浏览器访问还不够。Jakob Nielson在他2000年的文章<a href="http://www.useit.com/alertbox/20001029.html">Flash: 99% Bad</a>中指出，Flash“打破了Web的基本交互方式”。终端用户希望在使用Web应用程序时所面对的是特定的交互方式。应用程序需要遵从传统的Web交互方式，并提供以下的可用功能：</p>
		<ul>
				<li>后退和前进按钮可以正常工作，以便终端用户可以导航到历史记录页面。</li>
				<li>用户应该可以创建书签。</li>
				<li>支持深链接，以保证终端用户可以将这个页面通过电子邮件发送给朋友和同事。</li>
				<li>刷新按钮可以正常工作，以便刷新当前的状态而不是重新初始化应用程序。</li>
				<li>开发人员可以使用“查看源文件”看到源代码。</li>
				<li>终端用户可以使用“查找”对页面进行搜索。</li>
				<li>搜索引擎可以为页面做索引并创建到搜索项的深链接。</li>
		</ul>
		<p>再看一下<a href="http://www.aventureforth.com/2005/09/06/top-10-ajax-applications/">Top 10  Ajax Applications</a>列表，我们可以看出，之前讨论的大多数Ajax应用程序的确打破了标准的Web交互方式。在下一节中，我们将讨论为什么许多Ajax应用程序会这么做。</p>
		<h3>为什么Ajax应用程序常常会使后退按钮无法正常工作？</h3>
		<p>我们所说的Web基于以下三个原则：</p>
		<ul>
				<li>使用 (D)HTML来定义界面</li>
				<li>使用HTTP实现客户端与服务器间的通讯</li>
				<li>使用URI进行寻址</li>
		</ul>
		<p>Ajax编程突破了由以上原则所带来的种种限制，使得界面功能更加丰富。正如我在以前的文章<a href="http://dev2dev.bea.com.cn/techdoc/2005110301.html">A Backbase Ajax  Front-end for J2EE Applications</a>(中
文版)中所介绍的那样，Ajax广泛使用了JavaScript（“J”）以创建功能丰富的UI组件和交互性。Ajax还引入了异步的XML通信（“A”
和“X”），也就是使用XMLHttpRequest对象导入新的数据和表示逻辑而不必刷新页面。然而，目前的Ajax模型并没有解决如何处理URI的问
题。</p>
		<p>Ajax应用程序对(D)HTML和HTTP的使用方式做了改变，而这种改变带来的直接结果就是后退按钮和Web的基本交互方式的其它元素无法正常
工作了。在本节的其余部分，我将说明如何通过以Ajax的方式处理URI来解决上述问题。首先我们来看看在传统的Web应用程序中URI是如何与用户交互
相关联的。</p>
		<p>从技术方面来说，用户交互是指用户界面状态的一次更改。状态改变由终端用户发起。浏览器客户端通过向服务器发出页面请求来处理状态更改（REST法则）。服务器将发送新的页面和新的URI到客户端以生成新的界面状态。<br />
  简单地说，每个用户交互都是通过会导致如下结果的服务器往返来处理的：</p>
		<ul>
				<li>生成新的页面</li>
				<li>生成新的URI</li>
		</ul>
		<p>这些Web功能之所以能够被使用，是因为浏览器在它的历史记录堆栈中记录了连续的URI，并在地址栏中向终端用户显示当前URI，用户可以通过地址
栏复制URI，并将其发送给朋友。当用户单击后退按钮或者向浏览器的地址栏中粘贴一个来自于电子邮件的URI时，就会触发一次到服务器的往返。因为服务器
负责状态管理，所以它就可以生成相应的页面。</p>
		<p>Ajax应用程序与传统的Web应用程序之间的主要区别在，Ajax应用程序可以处理用户的交互而无需页面重新加载。例如，通过XMLHttpRequest对象从服务器载入数据，或者使用JavaScript来处理拖放客户端。</p>
		<p>在上面的两个例子中，状态改变了，但是却没有生成新的URI。因此，单击后退按钮或刷新按钮会产生意外的结果，在地址栏中也不会有深链接的URI。</p>
		<p>为了提供传统的Web可用功能，Ajax应用程序需要以类似于服务器处理传统的Web应用程序的方式来处理URI客户端。Ajax应用程序需要实现以下功能：</p>
		<ul>
				<li>当客户端状态发生改变时，生成一个URI，并将其发送到浏览器</li>
				<li>当浏览器请求新的URI时可以重新创建状态。</li>
		</ul>
		<p>实现以上功能后，浏览器的历史记录就可以正常工作，浏览器的地址栏就可以显示URI，当然，您也就可以将它发送给朋友了。<br />
这里还有另外一个难点，那就是如何确定Ajax引擎什么时候需要实现以上功能（例如，哪一次状态改变需要创建新的URI）。在传统的模式中，每一次页面刷
新都对应着一次URI更新。而在Ajax模式中，每一个客户端事件都将新的URI添加到浏览器堆栈中。交互设计者和开发人员将不得不做出决定：哪一次状态
改变是有意义的。只对有意义的状态改变才需要生成URI。</p>
		<p>下面我们对提供Web可用功能的Ajax应用程序在客户端需要实现的功能做一下总结：</p>
		<ul>
				<li>创建历史记录
  <ul><li>保存有意义的状态</li><li>生成相应的URI</li><li>将这个URI添加到浏览器的堆栈中</li></ul></li>
				<li>恢复历史记录
  <ul><li>检测URI的改变</li><li>通过URI重新创建状态</li></ul></li>
		</ul>
		<h3>在Ajax中支持后退按钮的基本设计思想</h3>
		<p>在这一节中，我们将讨论在Ajax应用程序中支持后退按钮所需的基本步骤，并给出说明所需步骤的简单示例代码。有关如何以跨浏览器兼容的方式实现后退按钮支持的更完整讨论可以参见<a href="http://www.contentwithstyle.co.uk/Articles/38/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps" target="_blank">Mike  Stenhouse</a>在Content with  Style以及<a href="http://www.onjava.com/pub/a/onjava/2005/10/26/ajax-handling-bookmarks-and-back-button.html" target="_blank">Brad  Neuberg</a>在OnJava发表的文章。这两篇文章也是我比较喜欢的。</p>
		<p>简单示例程序如图１所示，在界面中将有一个选择框，它有两个值：“Year 1”和“Year 2”。对于这个程序，我们将在选择框值发生改变时跟踪历史记录。这意味着用户可以首先选择“Year 2”然后单击后退按钮后退到先前的选择。</p>
		<p align="center">
				<img src="http://dev2dev.bea.com.cn/images/image060313001.jpg" alt="带有选择框的简单示例程序" border="0" height="165" width="460" />
				<br />
  图1.带有选择框的简单示例程序</p>
		<p>示例程序最初是一个带有JavaScript getter和setter（用于选择框值）的简单HTML表单：</p>
		<pre class="code">&lt;html&gt;<br /><br />&lt;head&gt;<br />&lt;script language="JavaScript" type="text/JavaScript"&gt;<br />function reportOptionValue()<br />{<br />  var myForm = document.make_history;<br />  var mySelect = myForm.change_year;<br />  return mySelect.options[mySelect.selectedIndex].value;<br />}<br /><br />function setOptionValue(value)<br />{<br />  var myForm = document.make_history;<br />  var mySelect = myForm.change_year;<br />  mySelect.options[value-1].selected = true;<br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br /><br />&lt;body&gt;<br />&lt;form name=make_history&gt;<br />  &lt;select name=change_year&gt;<br />    &lt;option value="year_1"&gt;Year 1&lt;/option&gt;<br />    &lt;option value="year_2"&gt;Year 2&lt;/option&gt;<br />  &lt;/select&gt;<br />&lt;/form&gt;<br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /></pre>
		<p>我们将首先实现第一个要求：创建状态的历史记录。正如我们前面所提到的，这个要求包含以下三个步骤：</p>
		<ul>
				<li>创建历史记录
  <ul><li>保存有意义的状态</li><li>生成相应的URI</li><li>将这个URI添加到浏览器的堆栈中</li></ul></li>
		</ul>
		<p>我们希望能够保存选择框的每一次更改。因此我们将创建新的包含选择框状态信息的URI。</p>
		<p>为了遵循Internet标准，我们将使用URI的碎片标识符部分。按照<a href="http://www.ietf.org/rfc/rfc3986.txt" target="_blank">IETF RFC 3986</a>的规定，“……作为客户端间接引用的主要形式，碎片标识符在信息检索系统中起着特殊的作用，〈……〉碎片标识符在解除引用之前与URI的其余部分是分离的，因此，碎片本身中的标识信息只被用户代理所废弃，而不考虑URI方案……”。</p>
		<p>使用碎片标识符，我们可以创建一个“Ajax-URI”，其中的客户端部分和服务器端部分使用“#”隔开。</p>
		<p>JavaScript提供了window.location()函数，以便通过URI更新浏览器的历史记录和地址。此外，我们可以使用window.location.hash()直接访问碎片标识符。</p>
		<p>在下面的代码片断中，您可以看到如何通过对选择框使用onchange事件处理程序来扩展我们的代码，该处理程序使用一个“Ajax-URI”来更新浏览器历史记录及地址栏。</p>
		<pre class="code">&lt;html&gt;<br /><br />&lt;head&gt;<br />&lt;script language="JavaScript" type="text/JavaScript"&gt;<br />function makeHistory(newHash)<br />{<br />  window.location.hash = newHash;<br />}<br /><br />function reportOptionValue()<br />{<br />  var myForm = document.make_history;<br />  var mySelect = myForm.change_year;<br />  return mySelect.options[mySelect.selectedIndex].value;<br />}<br /><br />function setOptionValue(value)<br />{<br />  var myForm = document.make_history;<br />  var mySelect = myForm.change_year;<br />  mySelect.options[value-1].selected = true;<br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br /><br />&lt;body&gt;<br />&lt;form name=make_history&gt;<br />  &lt;select name=change_year <br />    onchange=<br />      "return makeHistory(reportOptionValue())"&gt;<br />    &lt;option value="year_1"&gt;Year 1&lt;/option&gt;<br />    &lt;option value="year_2"&gt;Year 2&lt;/option&gt;<br />  &lt;/select&gt;<br />&lt;/form&gt;<br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></pre>
		<p>正如我们在图２中所看到的，选择框的每一次变动都将导致浏览器地址的更新。请注意，在需要使用隐藏帧以获取正确的行为的Internet  Explorer (IE)中会存在一些问题，详细情况还是请参见Mike Stenhouse和Brad Neuberg的文章。</p>
		<p align="center">
				<img src="http://dev2dev.bea.com.cn/images/image060313002.jpg" alt="状态变化时历史记录堆栈被更新" border="0" height="136" width="460" />
				<br />
  图2.状态变化时历史记录堆栈被更新</p>
		<p>我们现在有了一个在选择框的值发生变化时创建新URI的事件处理程序。新URI使用碎片标识符存储重新创建先前状态所需的信息。现在我们可以着手实现下一个功能了。</p>
		<ul>
				<li>恢复历史记录</li>
				<ul>
						<li>检测URI的更改</li>
						<li>通过URI重新创建状态</li>
				</ul>
		</ul>
		<p>在第一步中，我们通过window.location.hash()函数更新了客户端的URI。这个调用并不会产生服务器的往返，也不会导致页面刷新。因此，我们需要使用Ajax的方法（在客户端）处理URI的改变。</p>
		<p>首先需要增加一个轮询函数，以定时检查浏览器历史记录中的URI。我将在页面的onload事件中使用pollHash()函数，每隔1000毫秒它将重新执行一次。</p>
		<p>这个轮询函数将调用handleHistory()函数，后者检查在上一次检查之后URI是否改变了。我们将借助一个名为expectedHash的全局变量来实现。</p>
		<p>最后一部分是确定URI是否发生了改变，这种改变由选择框中的事件处理程序引起，或者是因为终端用户单击了后退按钮而造成。我们通过在选择框的事件处理程序中设置expectedHash来达到此目的。</p>
		<pre class="code">&lt;html&gt;<br /><br />&lt;head&gt;<br />&lt;script language="JavaScript" type="text/JavaScript"&gt;<br />var expectedHash = "";<br /><br />function makeHistory(newHash)<br />{<br />  window.location.hash = newHash;<br />  expectedHash = window.location.hash;<br />  return true;<br />}<br /><br />function reportOptionValue()<br />{<br />  var myForm = document.make_history;<br />  var mySelect = myForm.change_year;<br />  return mySelect.options[mySelect.selectedIndex].value;<br />}<br /><br />function setOptionValue(value)<br />{<br />  var myForm = document.make_history;<br />  var mySelect = myForm.change_year;<br />  mySelect.options[value-1].selected = true;<br />  return true;<br />}<br /><br />function handleHistory()<br />{<br />  if ( window.location.hash != expectedHash )<br />  {<br />    expectedHash = window.location.hash;<br />    var newoption = expectedHash.substring(6);<br />    setOptionValue( newoption );<br />  }<br />  return true;<br />}<br /><br />function pollHash() {<br />  handleHistory();<br />  window.setInterval("handleHistory()", 1000);<br />  return true;<br />}<br />&lt;/script&gt;<br /><br />&lt;/head&gt;<br /><br />&lt;body language="JavaScript"<br />      onload="return pollHash()"&gt;<br />&lt;form name=make_history&gt;<br />  &lt;select name=change_year <br />    onchange="return makeHistory(reportOptionValue())"&gt;<br />    &lt;option value="year_1"&gt;Year 1&lt;/option&gt;<br />    &lt;option value="year_2"&gt;Year 2&lt;/option&gt;<br />  &lt;/select&gt;<br />&lt;/form&gt;<br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></pre>
		<p>到此，我们的示例程序就完成了。在这个程序中，我们演示了如何在URI中记录状态，如何将URI添加到浏览器的历史记录堆栈中，如何从后退按钮检测地址变动，以及最终如何重新创建所需的状态。</p>
		<p>这个示例程序还缺少以下功能：</p>
		<ul>
				<li>对使用隐藏帧的IE的支持</li>
				<li>更多的固定URI（这个示例程序只用于选择框选项少于10的情况）</li>
				<li>在构造时注册初始状态</li>
		</ul>
		<p>以一种兼容所有浏览器的健壮方式实现对所有传统的Web可用功能的处理不是一件容易的事。一种替代方法是使用对这些功能提供了内置支持的Ajax工具包。</p>
		<p>在下一节中，我们将描述Backbase Ajax引擎如何提供这些功能。我参考<a href="http://www.backbase.com/#forum/forum.html%3Fid=1">了Ajax  forum on the Backbase DevNet</a>上的实现。</p>
		<h3>案例分析：包含后退按钮和深链接的Ajax论坛</h3>
		<p>Backbase Ajax引擎是一个成熟的、功能丰富的Ajax软件包。对所有传统Web可用功能的支持是Backbase的优点之一。</p>
		<p>Backbase DevNet包含了为开发人员提供的、与Backbase和Ajax有关的信息。而开发人员论坛是DevNet的一部分。</p>
		<p>Backbase Web应用程序（包括DevNet及其讨论论坛）是使用Backbase构建的。为了演示该论坛功能丰富和易于到达的特点，我们将逐步遍历论坛的典型用例：</p>
		<ul>
				<li>开发人员浏览论坛，阅读不同的主题。</li>
				<li>开发人员复制这个主题的URI，将其粘贴到电子邮件中并发送给朋友。这个朋友从电子邮件中复制这个URI到一个浏览器中并打开同一论坛主题。</li>
				<li>开发人员单击后退按钮以阅读以前的主题。</li>
		</ul>
		<h3>进行几次用户交互后的论坛界面状态</h3>
		<p>我们来看看开发人员来到“BXML”论坛并选中名为“Issue with vertical and  horizontal menus”的贴子之后，论坛界面的状态以及地址栏中的对应URI是什么样的情况。</p>
		<p>论坛和贴子被选中，并被高亮显示。讨论的主题被显示出来以供阅读。在URI的碎片标识符中包含了所有的相关信息。在#后面，我们看到了为书签和深链
接而记录的完整状态：“forum”表示开发人员在浏览这个Web站点的论坛部分；“forum=2”表示当前选中的是BXML论坛，“thread=
211”记录了当前所选择的主题。最后，方括号中的“[5]”表示与书签结合的对多个后退和前进步骤的处理。</p>
		<p align="center">
				<a href="http://dev2dev.bea.com/images/2006/01/3_forum-initial-state.jpg" target="_blank">
						<img src="http://dev2dev.bea.com.cn/images/image060313003.gif" alt="具有Ajax URI的论坛初始状态" border="0" height="101" vspace="4" width="220" />
				</a>
				<br />
  图3.具有Ajax URI的论坛初始状态
  （单击图片查看大图） </p>
		<p>访问Backbase论坛，您就可以看到URI如何随着每次状态改变而更新，即使更新是在客户端进行处理的，或者牵涉到通过XMLHttpRequest对象进行部分页面更新。</p>
		<h3>在新的浏览器窗口内重新创建论坛界面的状态</h3>
		<p>现在让我们看看当开发人员将当前URI发送给朋友时会发生什么情况。这个朋友在浏览器窗口中打开了这个URI，期望能看到相同的界面状态。需要在新的浏览器中重新创建该状态。对于本文，我是从一个Firefox窗口中复制URI到一个新打开的IE窗口中。</p>
		<p>在地址栏中输入URI首先会产生一个服务器端的请求。使用“#”前的部分，会加载Backbase.com，在这一过程中，Backbase
Ajax引擎也就实现了初始化。活动的Backbase引擎会阅读URI中“#”后的部分。通过这些信息，Backbase引擎会转到“论坛
（forum）”部分，并选定BXML论坛（id=2）中的第211个主题，从而创建相应的状态。不需要页面的刷新，只需从服务器中加载附加的内容并在客
户端部分地更新界面，就可以实现了。</p>
		<p>在后续的浏览器功能的处理中，新的URI被添加到浏览器历史记录中，这个新的URI既可以在地址栏中使用，也可以用来做深链接。“[0]”表示没有可返回（使用后退按钮）的先前状态。</p>
		<p align="center">
				<a href="http://dev2dev.bea.com/images/2006/01/4_forum-state-new-browser.jpg" target="_blank">
						<img src="http://dev2dev.bea.com.cn/images/image060313004.gif" alt="在新的浏览器窗口中重新创建论坛状态" border="0" height="96" vspace="4" width="220" />
				</a>
				<br />
  图4.在新的浏览器窗口中重新创建论坛状态（单击图片查看大图）</p>
		<h3>用户单击后退按钮后的论坛界面状态</h3>
		<p>第一步我们研究了URI如何随着由用户交互所触发的界面状态更改而更新。下面我们将看到相反的情况：用户请求新的URI，相应的状态被重新创建。</p>
		<p>通过单击后退按钮，用户要求返回先前阅读的页面。浏览器通过从历史记录堆栈中找回先前的URI来响应后退按钮。Backbase
Ajax引擎将监测这一变化，从历史记录中读取新的URI，并来到“论坛”部分选定BXML论坛（id=2）中的第192个主题，从而重新构建相应的状
态。新的URI将按照上述语义显示在地址栏中。</p>
		<p>到这里，我们的案例分析也就结束了。</p>
		<p align="center">
				<a href="http://dev2dev.bea.com/images/2006/01/5_forum-state-after-back.jpg" target="_blank">
						<img src="http://dev2dev.bea.com.cn/images/image060313005.gif" alt="单击后退按钮后的论坛状态" border="0" height="101" vspace="4" width="220" />
				</a>
				<br />
图5.单击后退按钮后的论坛状态（单击图片查看大图）</p>
		<h3>Ajax程序确实需要后退按钮！</h3>
		<p>在过去的几年中，Web开发人员因为市场要求“易于到达”并愿意接受“功能丰富”方面的牺牲，所以选择构建Web界面。然而，当前Ajax受到的普
遍关注清楚地显示出这种情况实际上只是暂时的。市场现在强烈要求Web程序也能像桌面应用程序那样具有丰富的功能、交互性以及敏捷的响应能力。</p>
		<p>但是，终端用户已经习惯了Web交互方式。使用常见模式与任何Web界面进行交互可以提高生产力。终端用户期望后退/前进按钮和刷新按钮能正常工作，可以创建书签和深链接，可以查看源文件，使用“查找”对页面进行搜索，而且搜索引擎可以对Ajax应用程序建立索引。</p>
		<p>Ajax社区必须知道：正如本文所述，在Ajax应用程序中提供对后退/前进按钮以及其它传统浏览器功能的支持的技术是存在的。虽然实现起来并不容
易，而且会增加成本，但是Ajax社区的成功需要将传统的浏览器功能构建到Ajax应用程序中。因此，我强烈呼吁Ajax开发人员构建支持这些功能的
Ajax应用程序！</p>
		<h3>结束语</h3>
		<p>在本文中，我着重阐明了Ajax应用程序为什么需要遵从传统的Web交互方式并提供传统的Web可用功能。我确定可以通过创建在碎片标识符中包含客户端状态信息的“Ajax URI” ，从而将这些功能编程到Ajax应用程序中。</p>
		<p>阅读相关代码，您会发现，由于状态处理代码通常非常重要，再加上不同浏览器之间常常不兼容，实现完整的通用解决方案是相当困难的。而Backbase Ajax引擎通过开箱即用地提供所需功能，为该问题提供了一种解决方案。</p>
		<h3>参考资料</h3>
		<ul>
				<li>
						<a href="http://dev2dev.bea.com.cn/techdoc/2005110103.html">An Introduction to  Ajax（中文版）</a>，作者David Teare（dev2dev、2005年11月）</li>
				<li>
						<a href="http://www.backbase.com/demos/RSS" target="_blank">Backbase  RSS Reader</a>
				</li>
				<li>
						<a href="http://www.aventureforth.com/2005/09/06/top-10-ajax-applications/" target="_blank">Top 10  Ajax Applications</a> ，作者Dan Grossman （A Venture Forth、2005年9月）</li>
				<li>
						<a href="http://www.useit.com/alertbox/20001029.html" target="_blank">Flash: 99% Bad</a>，作者Jakob Nielsen（Jakob Nielsen的Alertbox、2005年10月）</li>
				<li>
						<a href="http://dev2dev.bea.com.cn/techdoc/2005110301.html">A Backbase Ajax  Front-end for J2EE Applications（中文版）</a> ，作者Mark  Schiefelbein（dev2dev、2005年8月）</li>
				<li>
						<a href="http://www.contentwithstyle.co.uk/Articles/38/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps" target="_blank">Fixing  the Back Button and Enabling Bookmarking for AJAX Apps</a>，作者Mike Stenhouse （Content with Style、2005年6月）</li>
				<li>
						<a href="http://www.onjava.com/pub/a/onjava/2005/10/26/ajax-handling-bookmarks-and-back-button.html" target="_blank">AJAX:  How to Handle Bookmarks and Back Buttons</a> ，作者Brad Neuberg （OnJava、2005年10月）</li>
				<li>
						<a href="http://www.ietf.org/rfc/rfc3986.txt" target="_blank">Uniform  Resource Identifier (URI): Generic Syntax</a>（IETF RFC 3986、2005年1月）</li>
				<li>
						<a href="http://www.backbase.com/#forum/forum.html?id=1" target="_blank">Ajax forum on the  Backbase DevNet</a>
				</li>
				<li>
						<a href="http://dev2dev.bea.com.cn/techdoc/2005110103.html">Ajax简介</a>，作者David Teare（dev2dev、2005年11月）</li>
				<li>
						<a href="http://dev2dev.bea.com.cn/techdoc/2005110301.html">一个用于J2EE应用程序的Backbase  Ajax前端</a>，作者Mark Schiefelbein（dev2dev、2005年8月） </li>
		</ul>
		<p>原文出处:<a href="http://dev2dev.bea.com/pub/a/2006/01/ajax-back-button.html" target="_blank">http://dev2dev.bea.com/pub/a/2006/01/ajax-back-button.html</a></p>
		<!--文章其他信息-->
		<div class="dot001">
				<img src="http://dev2dev.bea.com.cn/images/_.gif" alt="" height="1" width="100%" />
		</div>
		<table border="0" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="bottom">
								<td colspan="2" height="20"> <span class="h2b">作者简介</span></td>
						</tr>
						<tr>
								<td align="center" valign="top" width="0">
										<br />
								</td>
								<td>
										<a href="http://dev2dev.bea.com/pub/au/324" target="_blank">Mark Schiefelbein</a>自2005年2月以来一直担任Backbase的产品管理主管。Mark极大地推动了Backbase Rich Internet Application的全球推广。</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/36447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-20 21:54 <a href="http://www.blogjava.net/Vencent/articles/36447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个用于J2EE应用程序的Backbase Ajax前端</title><link>http://www.blogjava.net/Vencent/articles/36446.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 20 Mar 2006 13:53:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36446.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36446.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36446.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36446.html</trackback:ping><description><![CDATA[
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td height="64">时间：2005-11-03<br />
作者：<a href="http://dev2dev.bea.com.cn/author/404.html">Mark Schiefelbein</a><br />
浏览次数：
<script language="JavaScript" type="text/JavaScript" src="http://203.81.25.103/cgi-bin/beadevcount.cgi?d_id=682"></script><br />
本文关键字：<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Ajax">Ajax</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=RIA">RIA</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Rich%20Internet%20Application">Rich Internet Application</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=backbase">backbase</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=Dev%20Toolbox">Dev Toolbox</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=%20Eclipse"> Eclipse</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=%20WebLogic"> WebLogic</a></td>
								<td>
										<table class="box_content" border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td>
																		<span class="h2b">文章工具</span>
																		<br />
																		<img src="http://dev2dev.bea.com.cn/images/letter001.gif" alt="推荐给朋友" align="absmiddle" height="10" width="19" /> <a href="javascript:sendmail()">推荐给朋友</a><br /><img src="http://dev2dev.bea.com.cn/images/print001.gif" alt="打印文章" align="absmiddle" height="18" width="19" /> <a href="javascript:window.print()">打印文章</a></td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<!-- 提取技术文章 -->
		<div class="beas">
				<img src="http://dev2dev.bea.com.cn/images/dot6B6B6B.gif" alt="" height="1" width="100%" />
		</div>
		<p>　　动态HTML技术已经出现了多年。最近，Google的最新Web应用程序GMail、Google Suggests和Google
Maps，在前端页面中重新引入了基于标准的DHTML开发模型。Google证明了，DHTML开发模型能够让开发人员创建具有可视化吸引力和高度交互
式的Rich Internet Application（丰富网络应用程序，RIA）。</p>
		<p>　　Adaptive Path公司的Jesse James Garrett为这个基于标准的RIA开发模型创造了术语<a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" target="_blank">Ajax (Asynchronous JavaScript + XML)</a>。与传统的基于页面的Web应用程序模型相比，Ajax有3点不同之处：</p>
		<ul>
				<li>有一个客户端引擎担任用户界面（UI）和服务器之间的中介。</li>
				<li>用户行为由客户端引擎处理，而不是生成发往服务器的页面请求。</li>
				<li>XML数据在客户端引擎和服务器之间传输。</li>
		</ul>
		<p>　　换言之，Ajax解决方案包括一个客户端引擎，它用于呈现用户界面，并使用XML格式与服务器通信。这个引擎由很多JavaScript函数组成，位于Web浏览器中，它不需要插件，也不需要用户安装。</p>
		<p>　　基于Ajax的RIA正在迅速成为Web应用程序前端的基准，因为它可以同时提供二者的优点：丰富性和可达性。Ajax应用程序和桌面应用程序
一样丰富，响应高度灵敏，并且可以在一个页面上提供所有数据，无需刷新页面。它们还拥有基于标准的浏览器应用程序的可达性特点，这类应用程序可以在不具备
浏览器插件或客户端applet的情况下进行部署。</p>
		<p>　　Backbase所提供的Ajax软件具有以下特点：基于标准、功能全面且易于使用。Backbase Presentation
Client (BPC)基于Ajax技术，它使用称为Backbase XML (BXML)的附加标签扩展了DHTML。Backbase XML
Server Edition for J2EE
(BXS)包含了一些服务器端的组件，利用这些组件，J2EE开发人员可以快速开发J2EE应用程序的Ajax前端。</p>
		<p>　　在本文中，我使用Backbase为Java Pet Store开发了一个基于Ajax的前端。该案例分析说明了如何使用Backbase技术作为J2EE应用程序的Ajax表示层。您可以查看文中所描述的应用程序的在线演示，网址是<a href="http://www.backbase.com/xmlserver" target="_blank">http://www.backbase.com/xmlserver</a>。</p>
		<p>
				<strong>Backbase Ajax表示层</strong>
		</p>
		<p>　　Web开发人员应该能够轻松创建具有以下特点的Rich Internet Application
(RIA)：完全基于HTML标准（W3C），不需要最终用户安装插件，速度超快，能够在所有浏览器上进行操作，并与J2EE运行时和开发环境完全集成。
RIA利用客户端（Web浏览器）资源创建和管理用户界面，从而为最终用户提供一个响应灵敏而且具有应用程序风格的用户界面。</p>
		<p>　　这种方法最近被称为Ajax。Ajax这个术语的灵感来源于Gmail、Google Maps和Google
Suggests这类应用程序，它把现有的浏览器技术提高到了一个新的水平上。RIA从根本上改进了在线应用程序的可用性和有效性。Ajax
RIA只使用标准的浏览器技术（如JavaScript、XHTML和XMLHttpRequest对象）就做到了这一点。通过使用
XMLHttpRequest，在将数据异步加载到界面中时就无需刷新页面。</p>
		<p>　　Backbase在J2EE架构中提供一个Ajax表示层，它结合了目前的J2EE服务器和先进的富客户端技术的优点。Backbase表示层
控制了富用户界面的每个方面：与最终用户的交互模型，与后端系统的集成，以及整个客户端-服务器通信。Backbase直接提供了用于聚合来自任意位置的
XML的下一个范型，将数据绑定到先进的富用户界面控件，并在一个统一的富用户界面中交付组合应用程序。</p>
		<p>　　Backbase表示层由一个客户机和一个服务器组成。Backbase Presentation Client
(BPC)是一个基于Ajax的GUI引擎，它允许开发人员以声明性的方式快速构建RIA。Backbase
XML(BXML)是对XHTML的扩展。它为开发人员提供了交付富前端功能的附加标签(B tag)。Backbase XML Server
(BXS)提供一种XML流水线架构，利用它可以从Web服务、数据库或Java对象获取数据，可以聚合和转换这些数据，并将其绑定到BPC中的UI元
素。BPC和BXS相结合，可以在Web浏览器和应用服务器之间搭建一座功能强大的桥梁，并提供一个分布在客户端和服务器上的完整的富Internet表
示层。</p>
		<p>　　图1说明了在逻辑和物理应用程序架构中，Backbase所处的位置。应用程序由一个J2EE后端和一个基于Ajax的RIA前端组成。从逻辑
上说，Backbase提供了表示层，而J2EE提供了业务逻辑和数据层。从物理上说，表示层分布在客户端和服务器上。在客户端上，Backbase使用
BPC扩展了浏览器。在服务器上，Backbase使用BXS扩展了应用服务器。</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020101.jpg" height="235" width="301" />
		</p>
		<p>图1. Backbase富Internet表示层</p>
		<p>
				<strong>Pet Store案例分析</strong>
		</p>
		<p>　　我们将使用Java Pet Store作为案例来分析如何为J2EE应用程序添加Backbase RIA前端。Java Pet
Store Demo是Sun Microsystems提供的一个示例应用程序，其目的是为了演示如何使用Java 2 Platform,
Enterprise Edition(J2EE)构建Web应用程序（详情请参见<a href="http://java.sun.com/developer/releases/petstore" target="_blank">http://java.sun.com/developer/releases/petstore</a>）。</p>
		<p>　　Java Pet Store是业内一个著名的参考应用程序（pet store还有.NET和Flash版本）。由于以下两个原因，它成为为J2EE应用程序添加基于Ajax的RIA前端的完美案例：</p>
		<ul>
				<li>Java Pet Store是一个完整的Web应用程序。</li>
				<p>Sun设计Pet Store的目的是演示所有常见的Web应用程序功能。通过使用Pet Store作为案例，我可以说明为J2EE应用程序添加RIA层的所有方面。</p>
				<p>作为一个典型的在线商店，它包含以下功能：</p>
				<ul>
						<li>浏览产品类别。</li>
						<li>在购物车中添加和删除物品。</li>
						<li>填写订单表单。</li>
						<li>提交订单。</li>
				</ul>
				<li>Java Pet Store有一个传统的HTML前端。</li>
				<p>使用RIA前端的目的是提供更简单和响应更灵敏的GUI，以及通常更为丰富的Web用户体验。我将说明，如何通过Backbase RIA技术极大地改进应用程序的前端，同时无需对后端和总体系统需求做任何修改。</p>
				<p>Pet Store的RIA前端将通过以下方式改善可用性：</p>
				<li>把前端变为一个单页面的界面（SPI）。</li>
				<li>提供更先进的UI控件（如模态弹出式菜单）。</li>
				<li>使用可视化效果（例如，把宠物放入购物车）。</li>
				<li>更加有效地利用电脑屏幕的操作区域。</li>
		</ul>
		<p>
				<strong>RIA Pet Store前端</strong>
		</p>
		<p>　　在这一节中，我将讨论经过改进的新Pet Store RIA前端。</p>
		<p>　　下面的两个屏幕快照演示了前端的改进。要获得对Backbase RIA前端更直观的感受，请访问<a href="http://www.backbase.com/xmlserver" target="_blank">http://www.backbase.com/xmlserver</a>上的在线演示，或者到<a href="http://www.backbase.com/download" target="_blank">http://www.backbase.com/download</a>下载Backbase社区版本。</p>
		<p>下面两个图对两个前端进行了可视化的比较。图2显示的是原来静态的多页面HTML前端。图3显示的是新的Backbase SPI前端：
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020102.jpg" height="186" width="325" />
		</p>
		<p> 图2. 原始HTML前端 </p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020103.jpg" height="232" width="325" />
		</p>
		<p>图3. 新Backbase前端</p>
		<p>　　Backbase为创建丰富的单页面Web界面提供了许多可能性。下面列出了一些Pet Store所使用的例子。</p>
		<ul>
				<li>选项卡式的单页面浏览</li>
				<p>在Web界面上，不同的动物种类（狗、猫等等）被表示为不同的选项卡。点击一个选项卡就会打开相应的类别，显示可供出售的宠物。</p>
				<p>在Backbase SPI中，无需刷新页面就可以打开选项卡。BPC只从服务器请求所需的数据，然后更新客户端的视图。SPI机制可以极大地缩短响应时间，让客户随心所欲地在类别之间来回穿梭。</p>
				<li>活动的多功能界面</li>
				<p>界面有三个主要功能——类别浏览、购物车和页面引导历史记录，它们在界面上都是一直可见的。因此，购物者总是能够查看购物车的当前内容或最近看过的宠物的记录。</p>
				<p>这些功能是高度同步的：浏览一个宠物时，历史记录将自动更新为在记录中显示该宠物。定购一个宠物时，它将被添加到购物车中。上述一切都发生在客户端的一个页面上（例如，无需重新加载页面就可以更新界面的各个部分）。</p>
				<li>界面变化的流畅可视化效果</li>
				<p>进行浏览时，客户将会看到不断变化的界面视图。例如，他可以按照价格和名称对宠物进行排序。界面需要根据新的排列顺序显示更新以后的宠物清单。</p>
				<p>在Backbase RIA前端中，以前的视图被使用可视化效果的新视图所代替，新视图向最终用户显示什么正在改变。图4说明了如何通过流畅的定位效果，把按名称排列的顺序转变为按价格排列的顺序：
</p>
				<p>
						<img src="http://dev2dev.bea.com.cn/images/051102/0511020104.jpg" height="56" width="313" />
				</p>
				<p>图4.类别视图的排列顺序转换</p>
				<li>用于提高转换速度的信息栏验证</li>
		</ul>
		<p>　　为了执行购买，购买者必须在一份表单中填入个人详细信息。Backbase极大地简化了这个购买过程，通过客户端的信息栏验证提供即时的反馈，并在提供所有数据的过程中提供逐步的指南和概述。</p>
		<p>　　图5显示了在填写表单的第一个步骤中，对于e-mail地址信息栏的验证。当购买者填写下一栏时，就会提供即时的反馈。
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020105.jpg" height="135" width="325" />
		</p>
		<p>图5. 信息栏验证—e-mail栏</p>
		<p>
				<strong>Backbase RIA Pet Store的架构</strong>
		</p>
		<p>　　增强Pet Store（或其他任何Web应用程序）的前端时，我们将继续依赖于以下两条架构基本原则：</p>
		<ul>
				<li>最终用户仍然使用标准的Web浏览器访问Pet Store，无需添加任何插件。</li>
				<li>由J2EE业务逻辑和数据组成的整个后端保持不变。</li>
		</ul>
		<p>　　现有的后端在开发期间是完全孤立的，而且不会改变，这个事实对于架构师和IT管理人员十分有利。通过一个规整的、模块化的架构，他们将能够控制风险和成本，同时显著提高Web应用程序的用户友好性。</p>
		<p>　　Backbase的富表示层技术由两个模块组成，它们将被加入到架构中。在客户端，BPC管理着SPI，并通过异步响应事件来处理与最终用户之
间的交互。在服务器端，Backbase XML
Server这个灵活的XML管道可以连接到任意服务器端的数据源，包括Web服务、文件、数据库或本地Java对象。图6说明了BPC和BXS如何共同
为RIA提供一个声明式的、基于XML的端到端表示层。
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020106.jpg" height="149" width="299" />
		</p>
		<p>图6. 声明式的端到端表示层</p>
		<p>
				<strong>Backbase表示客户端</strong>
		</p>
		<p>　　BPC是一个基于Ajax的GUI引擎，它运行在标准的Web浏览器中。运行时，BPC被加载到浏览器中，然后它会接收BXML代码，构造对应的B树，并不断地把这种表示转换为浏览器所呈现的DOM树。图7说明了运行时转换过程。
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020107.jpg" height="212" width="296" />
		</p>
		<p>图7. BPC运行时</p>
		<p>
				<strong>Backbase XML</strong>
		</p>
		<p>　　Backbase XML (BXML)是XHTML的扩展。开发人员通过创建BXML应用程序来开发富前端，包括BXML标签、标准的XHTML和CSS。BXML是一种声明性语言，它包含了XHTML中所没有的标签（B标签）</p>
		<p>　　BXML包含用于下列用途的标签：</p>
		<ul>
				<li>定义屏幕分区(&lt;b:panel&gt;) </li>
				<li>交互式客户端控制(&lt;b:menu&gt;) </li>
				<li>处理标准的用户交互事件(onClick) </li>
				<li>处理高级的用户交互事件(拖放和调整大小) </li>
				<li>管理客户端状态</li>
				<li>处理可视化效果(使修改任意CSS属性的过程动画化) </li>
				<li>数据绑定</li>
				<li>使用XSLT的一个子集进行客户端转换</li>
		</ul>
		<p>
				<strong>用于J2EE的Backbase XML Server</strong>
		</p>
		<p>　　Backbase XML Server (BXS)是一个服务器端的引擎，用于把BPC链接到任意J2EE后端。和BPC一样，BXS是完全基于XML的，其编程是声明性的。它使用一种XML管道架构，提供功能强大的服务器端转换和聚合。</p>
		<p>　　BXS附带一些用于访问最常用的数据源（包括Web服务、数据库、文件系统和本地Java对象）的开箱即用任务。我们使用Backbase标签对从这些源获得的数据进行聚合，然后使用XSLT进行转换。结果以无格式XML数据或BXML表示代码的形式返回给BPC。</p>
		<p>　　BXS还提供一些应用服务，包括身份验证、授权、日志记录和用户跟踪。图8显示了BXS的总体架构。</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020108.jpg" height="217" width="302" />
		</p>
		<p>图8. BXS架构</p>
		<p>
				<strong>Eclipse开发工具</strong>
		</p>
		<p>　　为了让J2EE开发人员可以只使用一种开发工具就能创建完整的Web应用程序，包括富前端，Backbase提供了一个Eclipse插件。如图9所示，该插件提供了在Eclipse中突出显示语法和Backbase标签代码自动完成的功能。
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020109.jpg" height="235" width="317" />
		</p>
		<p>图9. Backbase Eclipse插件</p>
		<p>　　注意：Eclipse的可视化拖放开发插件还处在开发阶段。</p>
		<p>
				<strong>部署到BEA WebLogic</strong>
		</p>
		<p>　　BXS是一个与标准兼容的J2EE应用程序，可以将其部署到任何J2EE应用服务器上。图10显示了如何使用WebLogic控制台把BXS部署到<a href="http://dev2dev.bea.com/wlserver/" target="_blank">BEA WebLogic Server</a>。
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020111.jpg" height="251" width="325" />
		</p>
		<p>图10. 把BXS部署到BEA WebLogic</p>
		<p>
				<strong>实现Backbase RIA Pet Store</strong>
		</p>
		<p>　　下面的顺序图包括更多详细信息，可以帮助您更好地理解如何实现Backbase pet store。该顺序图显示了在应用程序的初始化加载期间BPC与BXS之间的交互，如图11所示，它包括以下4个步骤：</p>
		<ul>
				<li>初始化：用户在浏览器中输入宠物商店的URL；对BPC进行初始化。</li>
				<li>应用程序布局：触发正在构造的事件；BPC构建整体应用程序布局；宠物类别被加载并显示在选项卡中。</li>
				<li>默认数据：默认情况下加载狗的类别；最初显示8张狗的图片，并带有向前/向后和排序功能。</li>
		</ul>
		<p>　　用户交互：用户点击Next按钮便可显示编号从9到16的狗图片。
</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051102/0511020110.jpg" height="365" width="329" />
		</p>
		<p>图11.顺序图：富商店前端</p>
		<ul>
				<li>初始化</li>
				<p>从用户在浏览器中输入宠物商店的URL开始，这将导致从Web服务器请求一个索引页面。</p>
				<p>索引页面包含用于实例化BPC的代码。索引页面是XHTML和BXML标签的结合，包含负责启动富前端的初始化事件处理程序。</p>
				<p>BPC初始化代码：</p>
				<pre class="code">&lt;...&gt;&lt;body onload="bpc.boot('/Backbase/')"&gt;<br /><br />&lt;...&gt;<br /><br />  &lt;xmp b:backbase="true"<br /><br />          style="display:none;height:100%;"&gt;<br /><br />    &lt;s:loading&gt;<br /><br />      &lt;div style="position:absolute;width:20%;<br /><br />                     top: 50px;left: 35%;"&gt;<br /><br />        &lt;center&gt;Please wait while loading...<br /><br />        &lt;/center&gt;<br /><br />      &lt;/div&gt;<br /><br />    &lt;/s:loading&gt;<br /><br />    &lt;...&gt;<br /><br />    &lt;!-- Include petshop specific behaviors --&gt;<br /><br />    &lt;s:include b:url="petshop.xml"/&gt;<br /></pre>
				<li>应用程序布局</li>
				<p>加载页面之后，BPC就会处理正在构造的事件，以便开始构建总体的应用程序布局。</p>
				<p>应用程序布局由几个面板组成，它们将屏幕划分为几个部分。顶行有一个固定高度的宠物商店徽标，接下来的主行是实际的商店，大小可以调整。主行分为两列，左边一列是产品类别，右边一列是购物车和历史记录。</p>
产品类别使用选项卡式的导航，每个宠物类别一个选项卡。这些选项卡是动态构造的，具体过程是通过BXS从一个XML文件加载类别，然后通过一个客户端模板把这些类别转换为选项卡，该转换模板的BPC代码如下：
<pre class="code">&lt;s:task b:action="transform"<br /><br />    b:stylesheet="b:xml('categories')"<br /><br />    b:xmldatasource="b:url('categories.xml')"<br /><br />    b:destination="id('main-content')" <br /><br />    b:mode="aslastchild" /&gt;<br /><br /></pre><p>下面是用于从文件系统把类别加载为XML的BXS代码：</p><pre class="code">&lt;bsd:pipeline equals="categories.xml"<br /><br />                                 access="public"&gt;<br /><br />    &lt;bsd:readxml input="file:/categories.xml"/&gt;<br /><br />&lt;/bsd:pipeline&gt;<br /></pre><p>下面是用于创建选项卡式导航的BPC客户端模板：</p><pre class="code">&lt;b:tabrow&gt;<br /><br />  &lt;s:for-each b:select="categories/category"&gt;<br /><br />    &lt;b:tab&gt;<br /><br />      &lt;s:attribute b:name="b:followstate"&gt;<br /><br />        id('&lt;s:value-of b:select="name"/&gt;')<br /><br />      &lt;/s:attribute&gt;<br /><br />      &lt;s:value-of b:select="name"/&gt;<br /><br />    &lt;/b:tab&gt;<br /><br />  &lt;/s:for-each&gt;<br /><br />&lt;/b:tabrow&gt;<br /></pre><p>所有BPC代码（用蓝色表示）都在客户端执行，而所有BXS代码（用红色表示）都在服务器端执行。注意，在本例中，我选择了在客户端进行转换，因为
数据集很小。下面我会给出一个在服务器端转换的例子。两种转换都要用到XSLT语法。Backbase的一个强大功能就是，前端开发人员可以根据情况选择
在客户端还是服务器端处理表示逻辑。语法似乎允许轻松地把代码从客户端移到服务器端，或者反之。</p><p>以上的代码示例应该可以使您了解到，借助于Backbase，Ajax编程变得多么轻松。结合了DHTML的声明性方法则更容易上手。使用附加的B
标签不仅可以使界面更加丰富，而且可以使开发人员的效率更高。诸如&lt;b:tab&gt;之类的单个标签可以代替多行HTML和JavaScript
代码，而且保证可以用于各种浏览器。</p><li>默认数据</li><p>显示商店前端时，默认情况下显示的是狗的类别。对于本案例，BXS负责此项操作。BXS从一个Web服务获得数据，将其放入缓存，然后生成BXML
表示代码，再把这些表示代码发回给BPC。服务器还通过一项配置设置确定一个页面上可以显示的动物数量，并根据需要加入了Next和Previous按
钮。最后，服务器还提供了按照名称或价格进行排序的功能。</p><p>下面的代码片断演示了服务器功能。外部管道products-overview.xml首先调用catalog.xml子管道。该子管道要么返回缓
存中的宠物信息，要么调用另一个子管道catalog.ws。在缓存没有命中的情况下，内部管道catalog.ws会从Web服务获取宠物信息。</p><p>外部管道获得宠物信息，然后进行XSLT转换，从而以4x2表格显示这些信息，并带有Next和Previouse按钮，然后把BXML格式的代码发回给BPC。BPC呈现它接收到的BXML。</p><p>有3个嵌套的BXS管道分别用于从Web服务获取数据、将其放入缓存，以及通过XSLT转换创建BXML输出：
</p><pre class="code">&lt;bsd:pipeline equals="products-overview.xml"<br /><br />                              access="public"/&gt;<br /><br />  &lt;bsd:callpipe pipe="catalog.xml"/&gt;<br /></pre><pre class="code">&lt;bsd:pipeline equals="catalog.xml" access="private"&gt;<br /><br />  &lt;bsd:exist field="{global:petstore-catalog}"&gt;<br /><br />    &lt;bsd:readxml&gt;{global:petstore-catalog}<br /><br />    &lt;/bsd:readxml&gt;<br /><br />    &lt;bsd:otherwise&gt;<br /><br />      &lt;bsd:callpipe pipe="catalog.ws"/&gt;<br /></pre><pre class="code">&lt;bsd:pipeline equals="catalog.ws"<br /><br />                               access="private"&gt;<br /><br />  &lt;bsd:try&gt;<br /><br />    &lt;bsd:callws wsdl="PetstoreCatalog.wsdl"<br /><br />                               method="getAll"/&gt;<br /><br />    &lt;bsd:callpipe pipe="strip-root-ns"/&gt;<br /><br />    &lt;bsd:catch&gt;<br /><br />      &lt;bsd:xslt xslt="error.xslt"&gt;<br /><br />        &lt;bsd:param name="errormsg"&gt;{error:message}<br /><br />        &lt;/bsd:param&gt;<br /><br />        &lt;bsd:param name="errorsrc"&gt;{error:source}<br /><br />        &lt;/bsd:param&gt;<br /><br />      &lt;/bsd:xslt&gt;<br /><br />    &lt;/bsd:catch&gt;<br /><br />  &lt;/bsd:try&gt;<br /><br />&lt;/bsd:pipeline&gt;<br />      &lt;bsd:writexml&gt;{global:petstore-catalog}<br /><br />      &lt;/bsd:writexml&gt;<br /><br />    &lt;/bsd:otherwise&gt;<br /><br />  &lt;/bsd:exist&gt;<br /><br />&lt;/bsd:pipeline&gt;<br />&lt;bsd:extractfilter xpath=<br /><br />  "category[name/text()='{requestparam:category}']"/&gt; <br /><br />  &lt;bsd:xslt xslt="products/products-overview.xslt"&gt;<br /><br />    &lt;bsd:param name="category"&gt;<br /><br />      {requestparam:category}<br /><br />    &lt;/bsd:param&gt;<br /><br />    &lt;bsd:param name="stepsize"&gt;<br /><br />      {global:stepsize}<br /><br />    &lt;/bsd:param&gt;<br /><br />    &lt;bsd:param name="sortorder"&gt;<br /><br />      {requestparam:sortorder}<br /><br />    &lt;/bsd:param&gt;<br /><br />    &lt;bsd:param name="sortfield"&gt;<br /><br />      {requestparam:sortfield}<br /><br />    &lt;/bsd:param&gt;<br /><br />  &lt;/bsd:xslt&gt;<br /><br />&lt;/bsd:pipeline&gt;<br /></pre><p>代码示例再次清楚地说明了，借助于Backbase，以声明性的方式创建Ajax前端是多么容易的事情。例如，只要使用带有一个WSDL引用作为属性的&lt;bsd:callws&gt;标签，就可以调用一个Web服务。</p><li>用户交互</li><p>现在，最终用户可以与宠物商店类别进行交互。可以使用Next或Previous按钮或者排序功能在动物类别中进行浏览。或者，只要点击一下相应的选项卡，就可以转到另一个类别中。</p><p>BPC和BXS对这种交互进行了无缝处理。显示已经在客户端上的数据时，无需与服务器进行任何通信。例如，购物者已经从狗类别转到了猫类别，然后再
回到狗类别。客户端仍然拥有狗类别的数据，所以可以马上显示出来，这使得购物体验变得更完美。其他的类别需要从BXS获取。BXS要么立即从其缓存返回它
们，要们访问Web服务来获得新数据。</p></ul>
		<p>　　为了详细说明Backbase Ajax宠物商店的实现，我把重点放在了初始化的步骤上。完整的宠物商店（可以从<a href="http://www.backbase.com/xmlserver" target="_blank">http://www.backbase.com/xmlserver</a>下载）还包括以下功能：</p>
		<ul>
				<ul>
						<li>商店前端</li>
						<ul>
								<li>初始化。</li>
								<li>使用从文件加载的宠物类别创建选项卡。</li>
								<li>默认情况下从Web服务加载Dog选项卡。</li>
								<li>通过缓存浏览Dog并对其进行排序。</li>
						</ul>
						<li>宠物详细情况</li>
						<ul>
								<li>使用跟踪聚合来自缓存和数据库的宠物详细情况。</li>
								<li>创建可视化历史记录。</li>
						</ul>
						<li>购物车</li>
						<ul>
								<li>使用跟踪添加到购物车。</li>
						</ul>
						<li>登录</li>
						<ul>
								<li>登录和身份验证。</li>
						</ul>
						<li>退出</li>
						<ul>
								<li>退出和授权。</li>
								<li>确认。</li>
						</ul>
				</ul>
		</ul>
		<p>
				<strong>结束语</strong>
		</p>
		<p>　　最近有很多人都在研究Ajax。Ajax的优点已经在实践中得到了证明。定制Ajax的缺点在于它的复杂性和不兼容性。大量客户端
JavaScript的出现意味着开发人员很可能陷入到浏览器实现差别的泥潭中去。另外，JavaScript这种语言不适用于复杂的应用程序。</p>
		<p>　　为了开发易于管理的、可伸缩的和适应未来变化的Ajax解决方案，开发人员所需使用的工具应该具有比定制部件开发更多的功能。Backbase
Ajax软件提供了一个功能全面的客户端GUI管理引擎(Backbase Presentation
Client)、一个灵活的服务器端XML管道(Backbase XML
Server)和一种声明性的基于标签的UI语言，BXML(Backbase eXtensible Markup
Language)。该方法具有几个优点。</p>
		<p>　　首先，Backbae易于使用。它的声明性语言水平地扩展了DHTML；它完全对开发人员隐藏了浏览器兼容性的问题；而且它带有一套开发和调试工具。</p>
		<p>　　其次，Backbase是一个功能全面的Ajax
GUI管理系统。Backbase的先进性大大超过了其他Ajax框架，它完全把重点放在提供一个部件库或客户端－服务器通信（如DWR）上。在控件和客
户端－服务器通信的基础上，Backbase提供了用于如下用途的标签：提供电影效果，随需应变的数据加载，数据绑定和客户端的数据转换，对于Back和
Forward按钮的支持，完善的GUI状态管理，等等。所有这些功能对于目前的Ajax Web应用程序来说都是必需的。</p>
		<p>　　最后，Backbase是以兼容的方式提供所有客户端和服务器端的功能。用户可以使用富Ajax前端扩展现有的应用程序，同时无需修改后端。对于整个表示层来说，它的架构是时新的、模块化的，而且它基于XML。</p>
		<p>
				<strong>参考资料</strong>
		</p>
		<ul>
				<li>
						<a href="http://java.sun.com/developer/releases/petstore/" target="_blank">Java Pet Store Demo</a>。</li>
				<li>
						<a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" target="_blank">Ajax: A New Approach to Web Applications</a>，作者Jesse James Garrett（Adaptive Path，2005年2月）。</li>
		</ul>
		<p>
				<strong>原文出处</strong>
		</p>
		<p>A Backbase Ajax Front-end for J2EE Applications</p>
		<p>
				<a href="http://dev2dev.bea.com/pub/a/2005/08/backbase_ajax.html" target="_blank">http://dev2dev.bea.com/pub/a/2005/08/backbase_ajax.html</a>
		</p>
		<!--文章其他信息-->
		<div class="dot001">
				<img src="http://dev2dev.bea.com.cn/images/_.gif" alt="" height="1" width="100%" />
		</div>
		<table border="0" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="bottom">
								<td colspan="2" height="20"> <span class="h2b">作者简介</span></td>
						</tr>
						<tr>
								<td align="center" valign="top" width="0">
										<br />
								</td>
								<td>
										<a href="http://dev2dev.bea.com/pub/au/324" target="_blank">Mark Schiefelbein</a>自2005年2月以来一直担任Backbase的产品管理主管。Mark极大地推动了Backbase Rich Internet Application的全球推广。</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/36446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-20 21:53 <a href="http://www.blogjava.net/Vencent/articles/36446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax简介</title><link>http://www.blogjava.net/Vencent/articles/36445.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 20 Mar 2006 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36445.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36445.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36445.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36445.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36445.html</trackback:ping><description><![CDATA[
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td height="64">时间：2005-11-01<br />
作者：<a href="http://dev2dev.bea.com.cn/author/353.html">David Teare</a><br />
浏览次数：
<script language="JavaScript" type="text/JavaScript" src="http://203.81.25.103/cgi-bin/beadevcount.cgi?d_id=681"></script><br />
本文关键字：<a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=ajax">ajax</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=dhtml">dhtml</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=dwr">dwr</a>, <a href="http://dev2dev.bea.com.cn/products/search.jsp?searchtype=keywords&amp;keywords=%20javascript"> javascript</a></td>
								<td>
										<table class="box_content" border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td>
																		<span class="h2b">文章工具</span>
																		<br />
																		<img src="http://dev2dev.bea.com.cn/images/letter001.gif" alt="推荐给朋友" align="absmiddle" height="10" width="19" /> <a href="javascript:sendmail()">推荐给朋友</a><br /><img src="http://dev2dev.bea.com.cn/images/print001.gif" alt="打印文章" align="absmiddle" height="18" width="19" /> <a href="javascript:window.print()">打印文章</a></td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<!-- 提取技术文章 -->
		<div class="beas">
				<img src="http://dev2dev.bea.com.cn/images/dot6B6B6B.gif" alt="" height="1" width="100%" />
		</div>
		<p>　　作为J2EE开发人员，我们似乎经常关注“后端机制（backend
mechanics）”。我们通常会忘记，J2EE的主要成功之处在Web应用程序方面；许多原因使得人们喜欢利用Web开发应用程序，但主要还是因为其
易于部署的特点允许站点以尽可能低的成本拥有上百万的用户。遗憾的是，在过去几年中，我们在后端投入了太多的时间，而在使我们的Web用户界面对用户自然
和响应灵敏方面却投入不足。</p>
		<p>　　本文介绍一种方法，Ajax，使用它可以构建更为动态和响应更灵敏的Web应用程序。该方法的关键在于对浏览器端的JavaScript、
DHTML和与服务器异步通信的组合。本文也演示了启用这种方法是多么简单：利用一个Ajax框架（指DWR）构造一个应用程序，它直接从浏览器与后端服
务进行通信。如果使用得当，这种强大的力量可以使应用程序更加自然和响应灵敏，从而提升用户的浏览体验。</p>
		<p>　　该应用程序中所使用的示例代码已打包为单独的WAR文件，可供下载。</p>
		<p>
				<strong>简介</strong>
		</p>
		<p>　　术语Ajax用来描述一组技术，它使浏览器可以为用户提供更为自然的浏览体验。在Ajax之前，Web站点强制用户进入提交/等待/重新显示范
例，用户的动作总是与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力，从而使用户从请求/响应的循环中解脱出来。借助于Ajax，可以在
用户单击按钮时，使用JavaScript和DHTML立即更新UI，并向服务器发出异步请求，以执行更新或查询数据库。当请求返回时，就可以使用
JavaScript和CSS来相应地更新UI，而不是刷新整个页面。最重要的是，用户甚至不知道浏览器正在与服务器通信：Web站点看起来是即时响应
的。</p>
		<p>　　虽然Ajax所需的基础架构已经出现了一段时间，但直到最近异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点确实激动人
心，因为它最终允许开发人员和设计人员使用标准的HTML/CSS/JavaScript堆栈创建“桌面风格的（desktop-like）”可用性。</p>
		<p>　　通常，在J2EE中，开发人员过于关注服务和持久性层的开发，以至于用户界面的可用性已经落后。在一个典型的J2EE开发周期中，常常会听到这样的话，“我们没有可投入UI的时间”或“不能用HTML实现”。但是，以下Web站点证明，这些理由再也站不住脚了：</p>
		<ul>
				<li>
						<a href="http://backpackit.com/" target="_blank">BackPack</a>
				</li>
				<li>
						<a href="http://www.google.com/webhp?complete=1&amp;hl=en" target="_blank">Google Suggest</a>
				</li>
				<li>
						<a href="http://maps.google.com/" target="_blank">Google Maps</a>
				</li>
				<li>
						<a href="http://www.palmsphere.com/" target="_blank">PalmSphere</a>
				</li>
		</ul>
		<p>　　所有这些Web站点都告诉我们，Web应用程序不必完全依赖于从服务器重新载入页面来向用户呈现更改。一切似乎就在瞬间发生。简而言之，在涉及到用户界面的响应灵敏度时，基准设得更高了。</p>
		<p>
				<strong>定义Ajax</strong>
		</p>
		<p>　　Adaptive Path公司的Jesse James Garrett这样<a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" target="_blank">定义Ajax</a>：</p>
		<p>　　Ajax不是一种技术。实际上，它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含：</p>
		<ul>
				<li>基于<a href="http://www.w3.org/TR/xhtml1/" target="_blank">XHTML</a>和<a href="http://www.w3.org/Style/CSS/" target="_blank">CSS</a>标准的表示；</li>
				<li>使用<a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/introduction.html" target="_blank">Document Object Model</a>进行动态显示和交互；</li>
				<li>使用XMLHttpRequest与服务器进行异步通信；</li>
				<li>使用JavaScript绑定一切。</li>
		</ul>
		<p>　　这非常好，但为什么要以Ajax命名呢？其实术语Ajax是由Jesse James Garrett创造的，他说它是“Asynchronous JavaScript + XML的简写”。</p>
		<p>
				<strong>Ajax的工作原理</strong>
		</p>
		<p>　　Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer
5中首次引入，它是一种支持异步请求的技术。简而言之，XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应，而不
阻塞用户。</p>
		<p>　　在创建Web站点时，在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用Ajax可以完成的功能：</p>
		<ul>
				<li>动态更新购物车的物品总数，无需用户单击Update并等待服务器重新发送整个页面。</li>
				<li>提升站点的性
能，这是通过减少从服务器下载的数据量而实现的。例如，在Amazon的购物车页面，当更新篮子中的一项物品的数量时，会重新载入整个页面，这必须下载
32K的数据。如果使用Ajax计算新的总量，服务器只会返回新的总量值，因此所需的带宽仅为原来的百分之一。</li>
				<li>消除了每次用户输入时的页面刷新。例如，在Ajax中，如果用户在分页列表上单击Next，则服务器数据只刷新列表而不是整个页面。</li>
				<li>直接编辑表格数据，而不是要求用户导航到新的页面来编辑数据。对于Ajax，当用户单击Edit时，可以将静态表格刷新为内容可编辑的表格。用户单击Done之后，就可以发出一个Ajax请求来更新服务器，并刷新表格，使其包含静态、只读的数据。</li>
		</ul>
		<p>　　一切皆有可能！但愿它能够激发您开始开发自己的基于Ajax的站点。然而，在开始之前，让我们介绍一个现有的Web站点，它遵循传统的提交/等待/重新显示的范例，我们还将讨论Ajax如何提升用户体验。</p>
		<p>
				<strong>Ajax可用于那些场景？——一个例子：MSN Money页面</strong>
		</p>
		<p>　　前几天，在浏览MSN Money页面的时候，有一篇<a href="http://moneycentral.msn.com/content/Investing/Realestate/P63633.asp" target="_blank">关于房地产投资的文章</a>引起了我的好奇心。我决定使用站点的“Rate this article”（评价本文）功能，鼓励其他的用户花一点时间来阅读这篇文章。在我单击vote按钮并等待了一会儿之后，整个页面被刷新，在原来投票问题所在的地方出现了一个漂亮的感谢画面。</p>
		<p>
				<img src="http://dev2dev.bea.com.cn/images/051101/0511010101.jpg" height="63" width="303" />
		</p>
		<p>　　而Ajax能够使用户的体验更加愉快，它可以提供响应更加灵敏的UI，并消除页面刷新所带来的闪烁。目前，由于要刷新整个页面，需要传送大量的
数据，因为必须重新发送整个页面。如果使用Ajax，服务器可以返回一个包含了感谢信息的500字节的消息，而不是发送26,813字节的消息来刷新整个
页面。即使使用的是高速Internet，传送26K和1/2K的差别也非常大。同样重要的是，只需要刷新与投票相关的一小节，而不是刷新整个屏幕。</p>
		<p>　　让我们利用Ajax实现自己的基本投票系统。</p>
		<p>
				<strong>原始的Ajax：直接使用XmlHttpRequest</strong>
		</p>
		<p>　　如上所述，Ajax的核心是JavaScript对象XmlHttpRequest。下面的示例文章评价系统将带您熟悉Ajax的底层基本知识：<a href="http://tearesolutions.com/ajax-demo/raw-ajax.html" target="_blank">http://tearesolutions.com/ajax-demo/raw-ajax.html</a>。注：如果您已经在本地WebLogic容器中安装了<a href="http://dev2dev.bea.com/2005/08/ajax-demo.war">ajax-demo.war</a>，可以导航到<a href="http://localhost:7001/ajax-demo/raw-ajax.html" target="_blank">http://localhost:7001/ajax-demo/raw-ajax.html</a>，</p>
		<p>　　浏览应用程序，参与投票，并亲眼看它如何运转。熟悉了该应用程序之后，继续阅读，进一步了解其工作原理细节。</p>
　　首先，您拥有一些简单的定位点标记，它连接到一个JavaScriptcastVote(rank)函数。
<pre class="code">function castVote(rank) {<br />  var url = "/ajax-demo/static-article-ranking.html";<br />  var callback = processAjaxResponse;<br />  executeXhr(callback, url);<br />}<br /></pre><p>　　该函数为您想要与之通信的服务器资源创建一个URL并调用内部函数executeXhr，提供一个回调JavaScript函数，一旦服务器响
应可用，该函数就被执行。由于我希望它运行在一个简单的Apache环境中，“cast vote
URL”只是一个简单的HTML页面。在实际情况中，被调用的URL将记录票数并动态地呈现包含投票总数的响应。</p>
　　下一步是发出一个XmlHttpRequest请求：
<pre class="code">function executeXhr(callback, url) {<br />  // branch for native XMLHttpRequest object<br />  if (window.XMLHttpRequest) {<br />    req = new XMLHttpRequest();<br />    req.onreadystatechange = callback;<br />    req.open("GET", url, true);<br />    req.send(null);<br />  } // branch for IE/Windows ActiveX version<br />  else if (window.ActiveXObject) {<br />    req = new ActiveXObject("Microsoft.XMLHTTP");<br />    if (req) {<br />      req.onreadystatechange = callback;<br />      req.open("GET", url, true);<br />      req.send();<br />    }<br />  }<br />}<br /><br /></pre><p>　　如您所见，执行一个XmlHttpRequest并不简单，但非常直观。和平常一样，在JavaScript领域，大部分的工作量都花在确保浏
览器兼容方面。在这种情况下，首先要确定XmlHttpRequest是否可用。如果不能用，很可能要使用Internet
Explorer，这样就要使用所提供的ActiveX实现。</p><p>executeXhr()方法中最关键的部分是这两行：
</p><pre class="code">req.onreadystatechange = callback;<br />req.open("GET", url, true);<br /></pre><p>　　第一行定义了JavaScript回调函数，您希望一旦响应就绪它就自动执行，而req.open()方法中所指定的“true”标志说明您想要异步执行该请求。</p>
　　一旦服务器处理完XmlHttpRequest并返回给浏览器，使用req.onreadystatechange指派所设置的回调方法将被自动调用。
<pre class="code">function processAjaxResponse() {<br />  // only if req shows "loaded"<br />  if (req.readyState == 4) {<br />    // only if "OK"<br />    if (req.status == 200) {<br />      502 502'votes').innerHTML = req.responseText;<br />    } else {<br />      alert("There was a problem retrieving the XML data:<br />" +<br />      req.statusText);<br />    }<br />  }<br />} <br /></pre><p>　　该代码相当简洁，并且使用了几个幻数，这使得难以一下子看出发生了什么。为了弄清楚这一点，下面的表格（引用自<a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html" target="_blank">http://developer.apple.com/internet/webcontent/xmlhttpreq.html</a>）列举了常用的XmlHttpRequest对象属性。</p><table bgcolor="#cccccc" border="0" cellpadding="0" cellspacing="1" width="80%"><tbody><tr bgcolor="#ffffff"><td height="22"><p><strong>属性</strong></p></td><td><p><strong>描述</strong></p></td></tr><tr bgcolor="#ffffff"><td height="22" valign="top"><p>onreadystatechange</p></td><td valign="top"><p>每次状态改变所触发事件的事件处理程序</p></td></tr><tr bgcolor="#ffffff"><td height="22" valign="top"><p>readyState</p></td><td valign="top"><p>对象状态值：
        </p><ul><li>0 = 未初始化（uninitialized）</li><li>1 = 正在加载（loading）</li><li>2 = 加载完毕（loaded）</li><li>3 = 交互（interactive）</li><li>4 = 完成（complete）</li></ul></td></tr><tr bgcolor="#ffffff"><td height="22" valign="top"><p>responseText</p></td><td valign="top"><p>从服务器进程返回的数据的字符串形式</p></td></tr><tr bgcolor="#ffffff"><td height="22" valign="top"><p>responseXML</p></td><td valign="top"><p>从服务器进程返回的DOM兼容的文档数据对象</p></td></tr><tr bgcolor="#ffffff"><td height="22" valign="top"><p>status</p></td><td valign="top"><p>从服务器返回的数字代码，比如404（未找到）或200（就绪）</p></td></tr><tr bgcolor="#ffffff"><td height="22" valign="top"><p>statusText</p></td><td valign="top"><p>伴随状态码的字符串信息</p></td></tr></tbody></table><p>　　现在processVoteResponse()函数开始显示出其意义了。它首先检查XmlHttpRequest的整体状态以保证它已经完成
（readyStatus == 4），然后根据服务器的设定询问请求状态。如果一切正常（status ==
200）,就使用innerHTML属性重写DOM的“votes”节点的内容。</p><p>　　既然您亲眼看到了XmlHttpRequest对象是如何工作的，就让我们利用一个旨在简化JavaScript与Java应用程序之间的异步通信的框架来对具体的细节进行抽象。</p><p><strong>Ajax: DWR方式</strong></p><p>　　按照与文章评价系统相同的流程，我们将使用Direct Web Remoting（DWR）框架实现同样的功能。</p><p>　　假定文章和投票结果存储在一个数据库中，使用某种对象/关系映射技术来完成抽取工作。为了部署起来尽可能地简单，我们不会使用数据库进行持久性
存储。此外，为使应用程序尽可能通用，也不使用Web框架。相反，应用程序将从一个静态HTML文件开始，可以认为它由服务器动态地呈现。除了这些简化措
施，应用程序还应该使用Spring Framework关联一切，以便轻松看出如何在一个“真实的”应用程序中使用DWR。</p><p>　　现在应该下载示例应用程序并熟悉它。该应用程序被压缩为标准的WAR文件，因此您可以把它放置到任何一个Web容器中——无需进行配置。部署完毕之后，就可以导航到<a href="http://localhost:7001/ajax-demo/dwr-ajax.html" target="_blank">http://localhost:7001/ajax_demo/dwr-ajax.html</a>来运行程序。</p><p>　　可以查看<a href="http://dev2dev.bea.com/2005/08/source.html" target="_blank">HTML 源代码</a>，了解它如何工作。给人印象最深的是，代码如此简单——所有与服务器的交互都隐藏在JavaScript对象ajaxSampleSvc的后面。更加令人惊讶的是，ajaxSampleSvc服务不是由手工编写而是完全自动生成的！让我们继续，看看这是如何做到的。</p><p><strong>引入DWR</strong></p><p>　　如同在“原始的Ajax”一节所演示的那样，直接使用XmlHttpRequest创建异步请求非常麻烦。不仅JavaScript代码冗长，而且必须考虑服务器端为定位Ajax请求到适当的服务所需做的工作，并将结果封送到浏览器。</p><p>　　设计DWR的目的是要处理将Web页面安装到后端服务上所需的所有信息管道。它是一个Java框架，可以很轻松地将它插入到Web应用程序中，
以便JavaScript代码可以调用服务器上的服务。它甚至直接与Spring
Framework集成，从而允许用户直接向Web客户机公开bean。</p><p>　　DWR真正的巧妙之处是，在用户配置了要向客户机公开的服务之后，它使用反射来生成JavaScript对象，以便Web页面能够使用这些对象
来访问该服务。然后Web页面只需接合到生成的JavaScript对象，就像它们是直接使用服务一样；DWR无缝地处理所有有关Ajax和请求定位的琐
碎细节。</p><p>　　让我们仔细分析一下示例代码，弄清它是如何工作的。</p><p><strong>应用程序细节：DWR分析</strong></p><p>　　关于应用程序，首先要注意的是，它是一个标准的Java应用程序，使用分层架构（Layered Architecture）设计模式。使用DWR通过JavaScript公开一些服务并不影响您的设计。
</p><p><img src="http://dev2dev.bea.com.cn/images/051101/0511010102.jpg" height="344" width="209" /></p><p>　　下面是一个简单的Java服务，我们将使用DWR框架直接将其向JavaScript代码公开：</p><pre class="code">package com.tearesolutions.service;<br /><br />public interface AjaxSampleSvc { <br />  Article castVote(int rank);<br />}<br /></pre><p>　　这是一个被简化到几乎不可能的程度的例子，其中只有一篇文章可以投票。该服务由Spring管理，它使用的bean名是ajaxSampleSvc，它的持久性需求则依赖于ArticleDao。详情请参见applicationContext.xml。</p><p>　　为了把该服务公开为JavaScript对象，需要配置DWR，添加dwr.xml文件到WEB-INF目录下：
</p><pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE dwr PUBLIC<br /> "-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN"<br /> "http://www.getahead.ltd.uk/dwr/dwr.dtd"&gt;<br /><br />&lt;dwr&gt;<br /> &lt;allow&gt;<br />  &lt;create creator="spring" javascript="ajaxSampleSvc"&gt;<br />   &lt;param name="beanName" value="ajaxSampleSvc" /&gt;<br />  &lt;/create&gt;<br />  &lt;convert converter="bean" match="com.tearesolutions.model.Article"/&gt;<br />  &lt;exclude method="toString"/&gt;<br />  &lt;exclude method="setArticleDao"/&gt;<br /> &lt;/allow&gt;<br />&lt;/dwr&gt;<br /></pre><p>　　dwr.xml文件告诉DWR哪些服务是要直接向JavaScript代码公开的。注意，已经要求公开Spring bean
ajaxSampleSvc。DWR将自动找到由应用程序设置的SpringApplicationContext。为此，必须使用标准的servlet
过滤器ContextLoaderListener来初始化Spring ApplicationContext。</p>
　　DWR被设置为一个servlet，所以把它的定义添加到web.xml：
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD <br /> Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;<br /><br />&lt;web-app&gt;<br /> &lt;display-name&gt;Ajax Examples&lt;/display-name&gt;<br /><br /> &lt;listener&gt;<br />  &lt;listener-class&gt;<br />      org.springframework.web.context.ContextLoaderListener<br />  &lt;/listener-class&gt;<br /> &lt;/listener&gt;<br /><br /> &lt;servlet&gt;<br />  &lt;servlet-name&gt;ajax_sample&lt;/servlet-name&gt;<br />  &lt;servlet-class&gt;com.tearesolutions.web.AjaxSampleServlet&lt;/servlet-class&gt;<br />  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br /> &lt;/servlet&gt;<br /><br /> &lt;servlet&gt;<br />  &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;<br />  &lt;display-name&gt;DWR Servlet&lt;/display-name&gt;<br />  &lt;description&gt;Direct Web Remoter Servlet&lt;/description&gt;<br />  &lt;servlet-class&gt;uk.ltd.getahead.dwr.DWRServlet&lt;/servlet-class&gt;<br />  &lt;init-param&gt;<br />   &lt;param-name&gt;debug&lt;/param-name&gt;<br />   &lt;param-value&gt;true&lt;/param-value&gt;<br />  &lt;/init-param&gt;<br /> &lt;/servlet&gt;<br /><br /> &lt;servlet-mapping&gt;<br />  &lt;servlet-name&gt;ajax_sample&lt;/servlet-name&gt;<br />  &lt;url-pattern&gt;/ajax_sample&lt;/url-pattern&gt;<br /> &lt;/servlet-mapping&gt;<br /><br /> &lt;servlet-mapping&gt;<br />  &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;<br />  &lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;<br /> &lt;/servlet-mapping&gt;<br />&lt;/web-app&gt;<br /></pre><p> 　　做完这些之后，可以加载<a href="http://localhost:7001/ajax-demo/dwr" target="_blank">http://localhost:7001/ajax-demo/dwr</a>，看看哪些服务可用。结果如下：</p><p><img src="http://dev2dev.bea.com.cn/images/051101/0511010103.jpg" height="102" width="305" /></p><p>图3. 可用的服务</p>
　　单击ajaxSampleSvc链接，查看有关如何在HTML页面内直接使用服务的示例实现。其中包含的两个JavaScript文件完成了大部分的功能：
<pre class="code">&lt;script type='text/javascript' <br />   src='/ajax-demo/dwr/interface/ajaxSampleSvc.js'&gt;&lt;/script&gt;<br />&lt;script type='text/javascript' <br />   src='/ajax-demo/dwr/engine.js'&gt;&lt;/script&gt;<br /></pre><p>ajaxSampleSvc.js是动态生成的：</p><pre class="code">function ajaxSampleSvc() { }<br /><br />ajaxSampleSvc.castVote = function(callback, p0)<br />{ <br />  DWREngine._execute(callback, '/ajax-demo/dwr', <br /> 'ajaxSampleSvc', 'castVote', p0);<br />}<br /></pre><p>　　现在可以使用JavaScript对象ajaxSampleSvc替换所有的XmlHttpRequest代码，从而重构raw-ajax.html文件。可以在dwr-ajax.html文件中看到改动的结果；下面是新的JavaScript函数：</p><pre class="code">function castVote(rank) {<br />  ajaxSampleSvc.castVote(processResponse, rank);<br />}<br />function processResponse(data) {<br /> var voteText = "<p><strong>Thanks for Voting!</strong></p>"<br />    + "<p>Current ranking: " + data.voteAverage <br />    + " out of 5</p>" <br />    + "<p>Number of votes placed: " <br />    + data.numberOfVotes + "</p>";<br /> 502 502'votes').innerHTML = voteText;       <br />}<br /></pre><p>　　惊人地简单，不是吗？由ajaxSampleSvc对象返回的Article域对象序列化为一个JavaScript对象，允许在它上面调用诸
如numberOfVotes()和voteAverage()之类的方法。在动态生成并插入到DIV元素“votes”中的HTML代码内使用这些数
据。</p><p><strong>下一步工作</strong></p><p>　　　在后续文章中，我将继续有关Ajax的话题，涉及下面这些方面：</p><ul><li>Ajax最佳实践</li></ul><p>　　像许多技术一样，Ajax是一把双刃剑。对于一些用例，其应用程序其实没有必要使用Ajax，使用了反而有损可用性。我将介绍一些不适合使用的模式，突出说明Ajax的一些消极方面，并展示一些有助于缓和这些消极方面的机制。例如，对<a href="http://www.netflix.com/BrowseSelection">Netflix电影浏览器</a>来说，Ajax是合适的解决方案吗？或者，如何提示用户确实出了一些问题，而再次单击按钮也无济于事？</p><ul><li>管理跨请求的状态</li></ul><p>　　在使用Ajax时，最初的文档DOM会发生一些变化，并且有大量的页面状态信息存储在客户端变量中。当用户跟踪一个链接到应用程序中的另一个页面时，状态就丢失了。当用户按照惯例单击Back按钮时，呈现给他们的是缓存中的初始页面。这会使用户感到非常迷惑！</p><ul><li>调试技巧</li></ul><p>　　使用JavaScript在客户端执行更多的工作时，如果事情不按预期方式进行，就需要一些调试工具来帮助弄清出现了什么问题。</p><p><strong>结束语</strong></p><p>　　本文介绍了Ajax方法，并展示了如何使用它来创建一个动态且响应灵敏的Web应用程序。通过使用DWR框架，可以轻松地把Ajax融合到站点中，而无需担心所有必须执行的实际管道工作。</p><p>　　特别感谢Getahead IT咨询公司的Joe Walker和他的团队开发出DWR这样神奇的工具。感谢你们与世界共享它！</p><p><strong>下载</strong></p><p>　　本文中演示的应用程序源代码可供下载：<a href="http://dev2dev.bea.com/2005/08/ajax-demo.war" target="_blank">ajax-demo.war</a>（1.52 MB）。</p><p><strong>参考资料</strong></p><ul><li><a href="http://www.getahead.ltd.uk/dwr" target="_blank">http://www.getahead.ltd.uk/dwr</a>——Getahead IT咨询公司。</li><li>Jesse James Garrett所撰写的“<a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" target="_blank">Ajax: A New Approach to Web Applications</a>”（Adaptive Path，2005年二月）。</li><li>“<a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html" target="_blank">Dynamic HTML and XML: The XMLHttpRequest Object</a>”（Apple Developer Connection）。</li></ul><p><strong>原文出处</strong></p><p>An Introduction To Ajax</p><p><a href="http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html" target="_blank">http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html</a></p><img src ="http://www.blogjava.net/Vencent/aggbug/36445.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-20 21:51 <a href="http://www.blogjava.net/Vencent/articles/36445.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>prototype.js开发笔记</title><link>http://www.blogjava.net/Vencent/articles/36443.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 20 Mar 2006 13:47:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36443.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36443.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36443.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36443.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1. Prototype是什么?		或许你还没有用过它， prototype.js 是一个由Sam    Stephenson写的JavaScript包。这个构思奇妙编写良好的一段兼容标准的一段代码将承担创造胖客户端， 高交互性WEB应用程序的重担。轻松加入Web    2.0特性。		如果你最近体验了这个程序包，你很可能会发现文档并不是它的强项之一。像所有在我之前的开发者一样，我...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/36443.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/36443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-20 21:47 <a href="http://www.blogjava.net/Vencent/articles/36443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>prototype.js 源码解读v1.3.1版本</title><link>http://www.blogjava.net/Vencent/articles/36442.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Mon, 20 Mar 2006 13:45:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36442.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36442.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36442.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36442.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: prototype 1.3.1 版本和之前的 1.2.0 版本有了不少改进,并增加了新的功能：1.  增加了事件注册管理2.  增加了空间定位的常用函数3.  改善了 xmlhttp 的封装4.  移除了 Effect.js，交给 Rico 或者 script.aculo.us 这些扩展库类实现。5.  bug 修复												...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/36442.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/36442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-20 21:45 <a href="http://www.blogjava.net/Vencent/articles/36442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向 Java 开发人员的 Ajax: 结合 Direct Web Remoting 使用 Ajax::数据序列化不可能比这更简单了！</title><link>http://www.blogjava.net/Vencent/articles/36075.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sun, 19 Mar 2006 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36075.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36075.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36075.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36075.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36075.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#author">Philip McCarthy</a>, 软件开发顾问, Independent Consultant<br /></p>
		<p>2005 年  12 月  27 日</p>
		<blockquote>虽然令人兴奋，但是把 Ajax 功能添加到应用程序可能意味着大量的艰苦工作。在<i>面向 Java® 开发人员的 Ajax </i> 系列的第 3 篇文章中，Philip McCarthy 介绍了如何使用Direct Web Remoting（DWR）直接把 JavaBean 的方法公开给 JavaScript 代码并自动进行 Ajax 的繁重工作。 </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>理解 <a href="http://www.ibm.com/developerworks/cn/java/j-ajax1/">Ajax 编程的基本知识</a> 是重要的，但是如果正在构建复杂的用户界面，那么能够在更高层次的抽象上工作也很重要。在<i>面向 Java 开发人员的 Ajax </i> 系列的第 3 篇文章中，我在上个月的
<a href="http://www.ibm.com/developerworks/cn/java//j-ajax2/">Ajax 的数据序列化技术</a> 基础之上，介绍一种可以避免繁琐的 Java 对象序列化细节的技术。</p>
		<p>在 <a href="http://www.ibm.com/developerworks/cn/java//j-ajax2/">上一篇文章</a> 中，我介绍了如何用 JavaScript 对象标注（JSON）以一种在客户机上容易转化成 JavaScript 对象的格式对数据进行序列化。有了这个设置，就可以用
 JavaScript 代码调用远程服务，并在响应中接收 JavaScript 对象图，但是又不像远程过程调用。这一次，将学习如何更进一步，使用一个框架，把从 JavaScript 客户代码对服务器端 Java 对象进行远程调用的能力正式化。</p>
		<p>DWR 是一个开放源码的使用 Apache 许可协议的解决方案，它包含服务器端 Java 库、一个 DWR servlet 以及
JavaScript 库。虽然 DWR 不是 Java 平台上唯一可用的 Ajax-RPC
工具包，但是它是最成熟的，而且提供了许多有用的功能。请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#resources">参考资料</a>，在继续学习之前下载 DWR。</p>
		<p>
				<a name="N10083">
						<span class="atitle">DWR 是什么？</span>
				</a>
		</p>
		<p>从最简单的角度来说，DWR 是一个引擎，可以把服务器端 Java 对象的方法公开给 JavaScript 代码。使用 DWR 可以有效地从应用程序代码中把 Ajax 的全部请求-响应循环消除掉。这意味着客户端代码再也不需要直接处理 <code>XMLHttpRequest</code> 对象或者服务器的响应。不再需要编写对象的序列化代码或者使用第三方工具才能把对象变成 XML。甚至不再需要编写 servlet 代码把 Ajax 请求调整成对 Java 域对象的调用。</p>
		<p>DWR 是作为 Web 应用程序中的 servlet 部署的。把它看作一个黑盒子，这个 servlet
有两个主要作用：首先，对于公开的每个类，DWR 动态地生成包含在 Web 页面中的 JavaScript。生成的 JavaScript
包含存根函数，代表 Java 类上的对应方法并在幕后执行 <code>XMLHttpRequest</code>。这些请求被发送给
DWR，这时它的第二个作用就是把请求翻译成服务器端 Java 对象上的方法调用并把方法的返回值放在 servlet 响应中发送回客户端，编码成
JavaScript。DWR 还提供了帮助执行常见的用户界面任务的 JavaScript 工具函数。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10097">
						<span class="atitle">关于示例</span>
				</a>
		</p>
		<p>在更详细地解释 DWR 之前，我要介绍一个简单的示例场景。像在前一篇文章中一样，我将采用一个基于在线商店的最小模型，这次包含一个基本的产品表示、一个可以包含产品商品的用户购物车以及一个从数据存储查询产品的数据访问对象（DAO）。<code>Item</code> 类与前一篇文章中使用的一样，但是不再实现任何手工序列化方法。图 1 说明了这个简单的设置：</p>
		<br />
		<a name="figure1">
				<b>图 1. 说明 Cart、CatalogDAO 和 Item 类的类图</b>
		</a>
		<br />
		<img alt="" src="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/dwr-fig1.gif" height="280" width="450" />
		<br />
		<p>在这个场景中，我将演示两个非常简单的用例。第一，用户可以在目录中执行文本搜索并查看匹配的商品。第二，用户可以添加商品到购物车中并查看购物车中商品的总价。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100B6">
						<span class="atitle">实现目录</span>
				</a>
		</p>
		<p>DWR 应用程序的起点是编写服务器端对象模型。在这个示例中，我从编写 DAO 开始，用它提供对产品目录数据存储的搜索功能。<code>CatalogDAO.java</code> 是一个简单的无状态的类，有一个无参数的构造函数。清单 1 显示了我想要公开给 Ajax 客户的 Java 方法的签名：</p>
		<br />
		<a name="listing1">
				<b>清单 1. 通过 DWR 公开的 CatalogDAO 方法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />/**<br /> * Returns a list of items in the catalog that have <br /> *  names or descriptions matching the search expression<br /> * @param expression Text to search for in item names <br /> *  and descriptions <br /> * @return list of all matching items<br /> */<br />public List&lt;Item&gt; findItems(String expression);<br /><br />/**<br /> * Returns the Item corresponding to a given Item ID<br /> * @param id The ID code of the item<br /> * @return the matching Item<br /> */<br />public Item getItem(String id);<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>接下来，我需要配置 DWR，告诉它 Ajax 客户应当能够构建 <code>CatalogDAO</code> 并调用这些方法。我在清单 2 所示的 dwr.xml 配置文件中做这些事：</p>
		<br />
		<a name="listing2">
				<b>清单 2. 公开 CatalogDAO 方法的配置</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;!DOCTYPE dwr PUBLIC<br />  "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"<br />  "http://www.getahead.ltd.uk/dwr/dwr10.dtd"&gt;<br />&lt;dwr&gt;<br />  &lt;allow&gt;<br />    &lt;create creator="new" javascript="catalog"&gt;<br />      &lt;param name="class" <br />        value="developerworks.ajax.store.CatalogDAO"/&gt;<br />      &lt;include method="getItem"/&gt; <br />      &lt;include method="findItems"/&gt; <br />    &lt;/create&gt; <br />    &lt;convert converter="bean" <br />      match="developerworks.ajax.store.Item"&gt;<br />      &lt;param name="include" <br />        value="id,name,description,formattedPrice"/&gt;<br />    &lt;/convert&gt;<br />  &lt;/allow&gt;<br />&lt;/dwr&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>dwr.xml 文档的根元素是 <code>dwr</code>。在这个元素内是 <code>allow</code> 元素，它指定 DWR 进行远程的类。<code>allow</code> 的两个子元素是 <code>create</code> 和 <code>convert</code>。</p>
		<p>
				<a name="N100F3">
						<span class="smalltitle">create 元素</span>
				</a>
		</p>
		<p>
				<code>create</code> 元素告诉 DWR 应当公开给 Ajax 请求的服务器端类，并定义 DWR 应当如何获得要进行远程的类的实例。这里的 <code>creator</code> 属性被设置为值 <code>new</code>，
这意味着 DWR 应当调用类的默认构造函数来获得实例。其他的可能有：通过代码段用 Bean 脚本框架（Bean Scripting
Framework，BSF）创建实例，或者通过与 IOC 容器 Spring 进行集成来获得实例。默认情况下，到 DWR 的 Ajax
请求会调用 <code>creator</code>，实例化的对象处于页面范围内，因此请求完成之后就不再可用。在无状态的 <code>CatalogDAO</code> 情况下，这样很好。</p>
		<p>
				<code>create</code> 的 <code>javascript</code> 属性指定从 JavaScript 代码访问对象时使用的名称。嵌套在 <code>create</code> 元素内的 <code>param</code> 元素指定 <code>creator</code> 要创建的 Java 类。最后，<code>include</code> 元素指定应当公开的方法的名称。显式地说明要公开的方法是避免偶然间允许访问有害功能的良好实践 —— 如果漏了这个元素，类的所有方法都会公开给远程调用。反过来，可以用 <code>exclude</code> 元素指定那些想防止被访问的方法。</p>
		<p>
				<a name="N1012D">
						<span class="smalltitle">convert 元素</span>
				</a>
		</p>
		<p>
				<code>creator</code> 负责公开用于 Web 远程的类和类的方法，<code>convertor</code> 则负责这些方法的参数和返回类型。<code>convert</code> 元素的作用是告诉 DWR 在服务器端 Java 对象表示和序列化的 JavaScript 之间如何转换数据类型。</p>
		<p>DWR 自动地在 Java 和 JavaScript 表示之间调整简单数据类型。这些类型包括 Java 原生类型和它们各自的类表示，还有
String、Date、数组和集合类型。DWR 也能把 JavaBean 转换成 JavaScript
表示，但是出于安全性的原因，做这件事要求显式的配置。</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#listing2">清单 2</a> 中的 <code>convert</code> 元素告诉 DWR 用自己基于反射的 bean 转换器处理 <code>CatalogDAO</code> 的公开方法返回的 <code>Item</code>，并指定序列化中应当包含 <code>Item</code> 的哪个成员。成员的指定采用 JavaBean 命名规范，所以 DWR 会调用对应的 <code>get</code> 方法。在这个示例中，我去掉了数字的 <code>price</code> 字段，而是包含了 <code>formattedPrice</code> 字段，它采用货币格式进行显示。</p>
		<p>现在，我准备把 dwr.xml 部署到 Web 应用程序的 <code>WEB-INF</code> 目录，在那里 DWR servlet 会读取它。但是，在继续之前，确保每件事都按照希望的那样运行是个好主意。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1016D">
						<span class="atitle">测试部署</span>
				</a>
		</p>
		<p>如果 <code>DWRServlet</code> 的 <code>web.xml</code> 定义把 <code>init-param</code><code> debug</code> 设置为 <code>true</code>，那么就启用了 DWR 非常有帮助的测试模式。导航到 <code>/{your-web-app}/dwr/</code> 会把 DWR 配置的要进行远程的类列表显示出来。在其中点击，会进入指定类的状态屏幕。<code>CatalogDAO</code> 的 DWR 测试页如图 2 所示。除了提供粘贴到 Web 页面的 <code>script</code> 标记（指向 DWR 为类生成的 JavaScript）之外，这个屏幕还提供了类的方法列表。这个列表包括从类的超类继承的方法，但是只有在 <code>dwr.xml</code> 中显式地指定为远程的才标记为可访问。</p>
		<br />
		<a name="figure2">
				<b>图 2.  CatalogDAO 的 DWR 测试页</b>
		</a>
		<br />
		<img alt="DWR 为 CatalogDAO 生成的诊断和测试页" src="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/dwr-fig2.jpg" height="415" width="460" />
		<br />
		<p>可以在可访问的方法旁边的文本框中输入参数值并点击 <b>Execute</b> 按钮调用方法。服务器的响应将在警告框中用 JSON 标注显示出来，如果是简单值，就会内联在方法旁边直接显示。这个测试页非常有用。它们不仅允许检查公开了哪个类和方法用于远程，还可以测试每个方法是否像预期的那样工作。</p>
		<p>如果对远程方法的工作感到满意，就可以用 DWR 生成的 JavaScript 存根从客户端代码调用服务器端对象。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101B2">
						<span class="atitle">调用远程对象</span>
				</a>
		</p>
		<p>远程 Java 对象方法和对应的 JavaScript 存根函数之间的映射很简单。通用的形式是 <code>JavaScriptName.methodName(methodParams ..., callBack)</code>，其中 <code>JavaScriptName</code> 是 <code>creator</code> 的 <code>javascript</code> 属性指定的名称，<code>methodParams</code> 代表 Java 方法的 <i>n</i> 个参数，<code>callback</code> 是要用 Java 方法的返回值调用的 JavaScript 函数。如果熟悉 Ajax，可以看出这个回调机制是 <code>XMLHttpRequest</code> 异步性的常用方式。</p>
		<p>在示例场景中，我用清单 3 中的 JavaScript 函数执行搜索，并用搜索结果更新用户界面。这个清单还使用来自 DWR 的 <code>util.js</code> 的便捷函数。要特别说明的是名为 <code>$()</code> 的 JavaScript 函数，可以把它当作 <code>document.getElementById()</code> 的加速版。录入它当然更容易。如果您使用过 JavaScript 原型库，应当熟悉这个函数。</p>
		<br />
		<a name="listing3">
				<b>清单 3. 从客户机调用远程的 findItems()</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />/*<br /> * Handles submission of the search form<br /> */<br />function searchFormSubmitHandler() {<br /><br />  // Obtain the search expression from the search field<br />  var searchexp = $("searchbox").value;<br /><br />  // Call remoted DAO method, and specify callback function<br />  catalog.findItems(searchexp, displayItems);<br /><br />  // Return false to suppress form submission<br />  return false;<br />}<br /><br />/*<br /> * Displays a list of catalog items<br /> */<br />function displayItems(items) {<br /><br />  // Remove the currently displayed search results<br />  DWRUtil.removeAllRows("items");<br /><br />  if (items.length == 0) {<br />    alert("No matching products found");<br />    $("catalog").style.visibility = "hidden";<br />  } else {<br /><br />    DWRUtil.addRows("items",items,cellFunctions);<br />    $("catalog").style.visibility = "visible";<br />  }<br />}</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在上面的 <code>searchFormSubmitHandler()</code> 函数中，我们感兴趣的代码当然是 <code>catalog.findItems(searchexp, displayItems);</code>。这一行代码就是通过网络向 DWR servlet 发送 <code>XMLHttpRequest</code> 并用远程对象的响应调用 <code>displayItems()</code> 函数所需要的全部内容。</p>
		<p>
				<code>displayItems()</code> 回调本身是由一个 <code>Item</code> 数组表示调用的。这个数组传递给 <code>DWRUtil.addRows()</code> 便捷函数，同时还有要填充的表的 ID 和一个函数数组。表中每行有多少单元格，这个数组中就有多少个函数。按照顺序使用来自数组的 <code>Item</code> 逐个调用每个函数，并用返回的内容填充对应的单元格。</p>
		<p>在这个示例中，我想让商品表中的每一行都显示商品的名称、说明和价格，并在最后一列显示商品的 <b>Add to Cart</b> 按钮。清单 4 显示了实现这一功能的单元格函数数组：</p>
		<br />
		<a name="listing4">
				<b>清单 4. 填充商品表的单元格函数数组</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />/*<br /> * Array of functions to populate a row of the items table<br /> * using DWRUtil's addRows function<br /> */<br />var cellFunctions = [<br />  function(item) { return item.name; },<br />  function(item) { return item.description; },<br />  function(item) { return item.formattedPrice; },<br />  function(item) {<br />    var btn = document.createElement("button");<br />    btn.innerHTML = "Add to cart";<br />    btn.itemId = item.id;<br />    btn.onclick = addToCartButtonHandler;<br />    return btn;<br />  }<br />];<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>前三个函数只是返回 dwr.xml 中 <code>Item</code> 的 <code>convertor</code> 包含的字段内容。最后一个函数创建一个按钮，把 <code>Item</code> 的 ID 赋给它，并指定在点击按钮时应当调用名为 <code>addToCartButtonHandler</code> 的函数。这个函数是第二个用例的入口点：向购物车中添加 <code>Item</code>。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1023D">
						<span class="atitle">实现购物车</span>
				</a>
		</p>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N10247">
																				<b>DWR 的安全性</b>
																		</a>
																		<br />
																		<p>DWR 设计时就考虑了安全性。使用 dwr.xml 明确地列出那些想做远程处理的类和方法，可以避免意外地把那些可能被恶意利用的功能公开出去。除此之外，使用调试测试模式，可以容易地审计所有公开到 Web 上的类和方法。</p>
																		<p>DWR 也支持基于角色的安全性。通过 bean 的 <code>creator</code> 配置，可以指定用户访问特定 bean 所必须属于的 J2EE 角色。通过部署多个 URL 受保护的 <code>DWRServlet</code> 实例，每个实例都有自己的 dwr.xml 配置文件，也可以提供拥有不同远程功能的用户集。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>用户购物车的 Java 表示基于 <code>Map</code>。当 <code>Item</code> 添加到购物车中时，<code>Item</code> 本身作为键被插入 <code>Map</code>。 <code>Map</code> 中对应的值是一个 <code>Integer</code>，代表购物车中指定 <code>Item</code> 的数量。所以 <code>Cart.java</code> 有一个字段 <code>contents</code>，声明为 <code>Map&lt;Item,Integer&gt;</code>。</p>
		<p>使用复杂类型作为哈希键给 DWR 带来一个问题 —— 在 JavaScript 中，数组的键必须是标量的。所以，DWR 无法转换 <code>contents</code><code> Map</code>。但是，对于购物车用户界面来说，用户需要查看的只是每个商品的名称和数量。所以我向 <code>Cart</code> 添加了一个名为 <code>getSimpleContents()</code> 的方法，它接受 <code>contents</code><code> Map</code> 并根据它构建一个简化的 <code>Map&lt;String,Integer&gt;</code>，只代表每个 <code>Item</code> 的名称和数量。这个用字符串作为键的 map 表示可以由 DWR 的转换器转换成 JavaScript。</p>
		<p>客户对 <code>Cart</code> 感兴趣的其他字段是 <code>totalPrice</code>，它代表购物车中所有商品的金额汇总。使用 <code>Item</code>，我还提供了一个合成的成员叫作 <code>formattedTotalPrice</code>，它是金额汇总的格式化好的 <code>String</code> 表示。</p>
		<p>
				<a name="N102C0">
						<span class="smalltitle">转换购物车</span>
				</a>
		</p>
		<p>为了不让客户代码对 <code>Cart</code> 做两个调用（一个获得内容，一个获得总价），我想把这些数据一次全都发给客户。为了做到这一点，我添加了一个看起来有点儿怪的方法，如清单 5 所示：</p>
		<br />
		<a name="listing5">
				<b>清单 5. Cart.getCart() 方法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />/**<br /> * Returns the cart itself - for DWR<br /> * @return the cart<br /> */ <br />public Cart getCart() {<br />  return this;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>虽然这个方法在普通的 Java 代码中可能完全是多余的（因为在调用这个方法时，已经有对 <code>Cart</code> 的引用），但它允许 DWR 客户让 <code>Cart</code> 把自己序列化成 JavaScript。</p>
		<p>除了 <code>getCart()</code>，需要远程化的另一个方法是 <code>addItemToCart()</code>。这个方法接受目录 Item 的 ID 的 <code>String</code> 表示，把这个商品添加到 <code>Cart</code> 中并更新总价。方法还返回 <code>Cart</code>，这样客户代码在一个操作中就能更新 <code>Cart</code> 的内容并接收购物车的新状态。</p>
		<p>清单 6 是扩展的 dwr.xml 配置文件，包含 <code>Cart</code> 类进行远程所需要的额外配置：</p>
		<br />
		<a name="listing6">
				<b>清单 6. 修改过的 dwr.xml 包含了 Cart 类</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;!DOCTYPE dwr PUBLIC<br />    "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"<br />    "http://www.getahead.ltd.uk/dwr/dwr10.dtd"&gt;<br />&lt;dwr&gt;<br />  &lt;/allow&gt;<br />    &lt;/create creator="new" javascript="catalog"&gt;<br />      &lt;/param name="class" <br />        value="developerworks.ajax.store.CatalogDAO"/&gt;<br />      &lt;/include method="getItem"/&gt;<br />      &lt;/include method="findItems"/&gt;<br />    &lt;//create&gt;<br />    &lt;/convert converter="bean" <br />      match="developerworks.ajax.store.Item"&gt;<br />      &lt;/param name="include" <br />        value="id,name,description,formattedPrice"/&gt;<br />    &lt;//convert&gt;<span class="boldcode"><br />    &lt;/create creator="new" scope="session" javascript="Cart"&gt;<br />      &lt;/param name="class" <br />        value="developerworks.ajax.store.Cart"/&gt;<br />      &lt;/include method="addItemToCart"/&gt;<br />      &lt;/include method="getCart"/&gt;<br />    &lt;//create&gt;<br />    &lt;/convert converter="bean" <br />      match="developerworks.ajax.store.Cart"&gt;<br />      &lt;/param name="include" <br />        value="simpleContents,formattedTotalPrice"/&gt;<br />    &lt;//convert&gt;</span><br />  &lt;//allow&gt;<br />&lt;/dwr&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在这个版本的 <code>dwr.xml</code> 中，我添加了 <code>Cart</code> 的 <code>creator</code> 和 <code>convertor</code>。<code>create</code> 元素指定应当把 <code>addItemToCart()</code> 和 <code>getCart()</code> 方法远程化，而且重要的是，生成的 <code>Cart</code> 实例应当放在用户的会话中。所以，购物车的内容在用户的请求之间会保留。</p>
		<p>
				<code>Cart</code> 的 <code>convert</code> 元素是必需的，因为远程的 <code>Cart</code> 方法返回的是 <code>Cart</code> 本身。在这里我指定在  <code>Cart</code> 的序列化 JavaScript 形式中应当存在的成员是 <code>simpleContents</code> 这个图和 <code>formattedTotalPrice</code> 这个字符串。</p>
		<p>如果对这觉得有点儿不明白，那么只要记住 <code>create</code> 元素指定的是 DWR 客户可以调用的 <code>Cart</code> 服务器端方法，而 <code>convert</code> 元素指定在 <code>Cart</code> 的 JavaScript 序列化形式中包含的成员。</p>
		<p>现在可以实现调用 <code>Cart</code> 的远程方法的客户端代码了。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1036A">
						<span class="atitle">调用远程的 Cart 方法</span>
				</a>
		</p>
		<p>首先，当商店的 Web 页首次装入时，我想检查保存在会话中的 <code>Cart</code> 的状态，看是否已经有一个购物车了。这是必需的，因为用户可能已经向 <code>Cart</code> 中添加了商品，然后刷新了页面或者导航到其他地方之后又返回来。在这些情况下，重新载入的页面需要用会话中的 <code>Cart</code> 数据对自己进行同步。我可以在页面的 onload 函数中用一个调用做到这一点，就像这样：<code>Cart.getCart(displayCart)</code>。请注意 <code>displayCart()</code> 是一个回调函数，由服务器返回的 <code>Cart</code> 响应数据调用。</p>
		<p>如果 <code>Cart</code> 已经在会话中，那么<code>creator</code> 会检索它并调用它的 <code>getCart()</code> 方法。如果会话中没有 <code>Cart</code>，那么 <code>creator</code> 会实例化一个新的，把它放在会话中，并调用 <code>getCart()</code> 方法。</p>
		<p>清单 7 显示了 <code>addToCartButtonHandler()</code> 函数的实现，当点击商品的 <b>Add to Cart</b> 按钮时会调用这个函数：</p>
		<br />
		<a name="listing7">
				<b>清单 7. addToCartButtonHandler() 实现</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />/*<br /> * Handles a click on an Item's "Add to Cart" button<br /> */<br />function addToCartButtonHandler() {<br /><br />  // 'this' is the button that was clicked.<br />  // Obtain the item ID that was set on it, and<br />  // add to the cart.<br />  Cart.addItemToCart(this.itemId,displayCart);<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>由 DWR 负责所有通信，所以客户上的添加到购物车行为就是一个函数。清单 8 显示了这个示例的最后一部分 —— <code>displayCart()</code> 回调的实现，它用 <code>Cart</code> 的状态更新用户界面：</p>
		<br />
		<a name="listing8">
				<b>清单 8. displayCart() 实现</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />/*<br /> * Displays the contents of the user's shopping cart<br /> */<br />function displayCart(cart) {<br /><br />  // Clear existing content of cart UI<br />  var contentsUL = $("contents");<br />  contentsUL.innerHTML="";<br /><br />  // Loop over cart items<br />  for (var item in cart.simpleContents) {<br /><br />    // Add a list element with the name and quantity of item<br />    var li = document.createElement("li");<br />    li.appendChild(document.createTextNode(<br />                    cart.simpleContents[item] + " x " + item<br />                  ));<br />    contentsUL.appendChild(li);<br />  }<br /><br />  // Update cart total<br />  var totalSpan = $("totalprice");<br />  totalSpan.innerHTML = cart.formattedTotalPrice;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在这里重要的是要记住，<code>simpleContents</code> 是一个把 <code>String</code> 映射到数字的 JavaScript 数组。每个字符串都是一个商品的名称，关联数组中的对应数字就是购物车中该商品的数量。所以表达式 <code>cart.simpleContents[item] + " x " + item</code> 可能就会计算出 “<code>2 x Oolong 128MB CF Card</code>” 这样的结果。</p>
		<p>
				<a name="N103E0">
						<span class="smalltitle">DWR 商店应用程序</span>
				</a>
		</p>
		<p>图 3 显示了这个基于 DWR 的 Ajax 应用程序的使用情况：显示了通过搜索检索到的商品，并在右侧显示用户的购物车：</p>
		<br />
		<a name="figure3">
				<b>图 3. 基于 DWR 的 Ajax 商店应用程序的使用情况</b>
		</a>
		<br />
		<img alt="示例场景的截屏，带有搜索结果和购物车" src="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/dwr-fig3.jpg" height="241" width="572" />
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N103F8">
						<span class="atitle">DWR 的利弊</span>
				</a>
		</p>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="call-batching">
																				<b>调用批处理</b>
																		</a>
																		<br />
																		<p>在 DWR 中，可以在一个 HTTP 请求中向服务器发送多个远程调用。调用 <code>DWREngine.beginBatch()</code> 告诉 DWR 不要直接分派后续的远程调用，而是把它们组合到一个批请求中。<code>DWREngine.endBatch()</code> 调用则把批请求发送到服务器。远程调用在服务器端顺序执行，然后调用每个 JavaScript 回调。</p>
																		<p>批处理在两方面有助于降低延迟：第一，避免了为每个调用创建 <code>XMLHttpRequest</code> 对象并建立相关的 HTTP 连接的开销。第二，在生产环境中，Web 服务器不必处理过多的并发 HTTP 请求，改进了响应时间。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>现在可以看出用 DWR 实现由 Java 支持的 Ajax
应用程序有多么容易了。虽然示例场景很简单，我实现用例的手段也尽可能少，但是不应因此而低估 DWR 引擎相对于自己设计 Ajax
应用程序可以节约的工作量。在前一篇文章中，我介绍了手工设计 Ajax 请求和响应、把 Java 对象图转化成 JSON
表示的全部步骤，在这篇文章中，DWR 替我做了所有这些工作。我只编写了不到 50 行 JavaScript
就实现了客户机，而在服务器端，我需要做的所有工作就是给常规的 JavaBean 加上一些额外方法。</p>
		<p>当然，每种技术都有它的不足。同任何 RPC 机制一样，在 DWR
中，可能很容易忘记对于远程对象进行的每个调用都要比本地函数调用昂贵得多。DWR 在隐藏 Ajax
的机械性方面做得很好，但是重要的是要记住网络并不是透明的 —— 进行 DWR
调用会有延迟，所以应用程序的架构应当让远程方法的粒度比较粗。正是为了这个目的，<code>addItemToCart()</code> 才返回 <code>Cart</code> 本身。虽然让 <code>addItemToCart()</code> 作为一个 void 方法可能更自然，但是这样的话对它的每个 DWR 调用后面都必须跟着一个 <code>getCart()</code> 调用以检索修改后的 <code>Cart</code> 状态。</p>
		<p>对于延迟，DWR 在调用的批处理中有自己的解决方案（请参阅侧栏的 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#call-batching">调用批处理</a>）。如果不能为应用程序提供适当粗粒度的 Ajax 接口，那么只要有可能把多个远程调用组合到一个 HTTP 请求中，就请使用调用批处理。</p>
		<p>
				<a name="N1043B">
						<span class="smalltitle">分离的问题</span>
				</a>
		</p>
		<p>从实质上看，DWR 在客户端和服务器端代码间形成了紧密的耦合，这有许多含义：首先，远程方法 API 的变化需要在 DWR 存根调用的
JavaScript 上反映出来。第二（也是最明显的），这种耦合会造成对客户端的考虑会渗入服务器端代码。例如，因为不是所有 Java
类型都能转化成 JavaScript，所以有时有必要给 Java 对象添加额外方法，好让它能够更容易地远程化。在示例场景中，我通过把 <code>getSimpleContents()</code> 方法添加到 <code>Cart</code> 来解决这个问题。我还添加了 <code>getCart()</code> 方法，它在 DWR 场景中是有用的，但在其他场景中则完全是多余的。由于远程对象粗粒度 API 的需要以及把某些 Java 类型转化成 JavaScript 的问题，所以可以看到远程 JavaBean 会被那些只对 Ajax 客户有用的方法“污染”。</p>
		<p>为了克服这个问题，可以使用包装器类把额外的特定于 DWR 的方法添加到普通 JavaBean。这意味着 JavaBean 类的 Java 客户可能看不到与远程相关联的额外的毛病，而且也允许给远程方法提供更友好的名称 —— 例如用 <code>getPrice()</code> 代替 <code>getFormattedPrice()</code>。图 4 显示的 <code>RemoteCart</code> 类对 <code>Cart</code> 进行了包装，添加了额外的 DWR 功能：</p>
		<br />
		<a name="figure4">
				<b>图 4. RemoteCart 为远程功能对 Cart 做了包装</b>
		</a>
		<br />
		<img alt="RemoteCart 包装器类的类图" src="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/dwr-fig4.gif" height="174" width="550" />
		<br />
		<p>最后，需要记住：DWR Ajax 调用是异步的，所以不要期望它们会按照分派的顺序返回。在示例代码中我忽略了这个小问题，但是在这个系列的第一篇文章中，我演示了如何为响应加时间戳，以此作为保证数据到达顺序的一种简单手段。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10475">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>正如所看到的，DWR 提供了许多东西 —— 它允许迅速而简单地创建到服务器端域对象的 Ajax 接口，而不需要编写任何 servlet 代码、对象序列化代码或客户端 <code>XMLHttpRequest</code> 代码。使用 DWR 部署到 Web 应用程序极为简单，而且 DWR 的安全性特性可以与 J2EE 基于角色的验证系统集成。但是 DWR 并不是对于任何一种应用程序架构都适合，所以在设计域对象的 API 时需要做些考虑。</p>
		<p>如果想学习用 DWR 进行 Ajax 的利弊的更多内容，最好的方式就是下载并开始实践。DWR 有许多我没有介绍的特性， <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#download">文章源代码</a> 是把 DWR 投入使用的一个良好起点。请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#resources">参考资料</a>，学习关于 Ajax、DWR 和相关技术的更多内容。</p>
		<p>这个系列中要指出的最重要的一点是：对于 Ajax 应用程序，没有包治百病的解决方案。Ajax
是一个快速发展的领域，不断有新技术涌现。在这个系列的三篇文章中，我的重点在于带您开始在 Ajax 应用程序的 Web 层中利用 Java 技术
—— 不管是选择基于 <code>XMLHttpRequest</code> 的带有对象序列化框架的技术，还是选择 DWR 这样的更高级抽象。请在后续几个月中留意面向 Java 开发人员介绍 Ajax 的文章。</p>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<span class="atitle">
						<a name="download">下载</a>
				</span>
		</p>
		<table class="data-table-1" border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<th>描述</th>
								<th>名字</th>
								<th style="text-align: right;">大小</th>
								<th>下载方法</th>
						</tr>
						<tr>
								<td class="tb-row">DWR source code</td>
								<td nowrap="nowrap">j-ajax3dwr.zip</td>
								<td style="text-align: right;" nowrap="nowrap">301 KB</td>
								<td nowrap="nowrap">
                               <a class="fbox" href="ftp://www6.software.ibm.com/software/developer/library/j-ajax3dwr.zip"><b>FTP</b></a></td>
						</tr>
				</tbody>
		</table>
		<table border="0" cellpadding="0" cellspacing="0">
				<tbody>
						<tr valign="top">
								<td colspan="5">
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="12" width="12" />
								</td>
						</tr>
						<tr>
								<td>
										<img alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" height="16" width="16" />
								</td>
								<td>
										<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/whichmethod.html">关于下载方法的信息</a>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="50" />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/v14/icons/sout.gif" height="16" width="16" />
								</td>
								<td>
										<a class="fbox" href="http://www.adobe.com/products/acrobat/readstep2.html">Get Adobe® Reader®</a>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www-128.ibm.com/developerworks/java/library/j-ajax3/" target="_blank">英文原文</a>。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/webservices/library/ws-wsajax/">Call SOAP Web services with AJAX, Part 1: Build the Web services client</a>” （James Snell，developerWorks，2005 年 10 月）：用 Ajax 实现 SOAP Web 服务客户机。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/cn/java/j-ajax2/">面向 Java 开发人员的 Ajax: Ajax 的 Java 对象序列化
</a>” （Philip McCarthy，developerWorks，2005 年 10 月）：学习在 Ajax 应用程序中进行数据序列化的技术。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/cn/java/j-ajax1/">面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序</a>” （Philip McCarthy，developerWorks，2005 年 9 月）：使用 Ajax 的第一步。<br /><br /></li>
				<li>
						<a href="http://getahead.ltd.uk/dwr/documentation">DWR Handbook</a> ：对 Ajax 和 DWR 的介绍。<br /><br /></li>
				<li>“<a href="http://today.java.net/pub/a/today/2005/08/25/dwr.html">Developing
AJAX Applications the Easy Way</a>” （Java.net，2005 年 8 月）：DWR 的创造者 Joe Walker 介绍如何编写简单的 Ajax 聊天服务器。<br /><br /></li>
				<li>请参阅教程 <a href="http://www.ibm.com/developerworks/edu/os-dw-os-phpajax-i.html">An alternative to generating Ajax code with Java is using the Simple Ajax Toolkit (Sajax)</a>，学习如何从 Sajax 起步。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/">Java 技术专区</a> ：数百篇关于 Java 编程各方面的文章。</li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
						<a href="http://getahead.ltd.uk/dwr/download">下载 DWR</a> ：得到最新的 DWR jar 发行包。<br /><br /></li>
				<li>
						<a href="http://oss.metaparadigm.com/jsonrpc/">JSON-RPC-Java</a> ：用于 Java 的另一个 Ajax-RPC 引擎。<br /><br /></li>
		</ul>
		<br />
		<b>讨论</b>
		<br />
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/community/">参与论坛讨论</a>。<br /><br /></li>
				<li>
						<a href="https://dwr.dev.java.net/">DWR's Java.net pages</a> ：订阅 DWR 的邮件列表。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/blogs/">developerWorks
blogs</a> ：加入 developerWorks 社区。<br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Philip
McCarthy 是一位软件开发顾问，专攻 Java 和 Web 技术。他目前在位于 Bristol 的 HP 试验室从事 Hewlett
Packard 数字媒体平台的工作 。在最近几年中，Phil 开发了多个采用异步服务器通信和 DOM 脚本的富 Web
客户端。他很高兴我们现在有了一个针对它们的名称。可以通过 Phil 的电子邮件 <a href="mailto:philmccarthy@gmail.com">philmccarthy@gmail.com</a> 与他联系。
		</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/36075.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-19 16:04 <a href="http://www.blogjava.net/Vencent/articles/36075.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面向 Java 开发人员的 Ajax: Ajax 的 Java 对象序列化::在 Ajax 应用程序中序列化数据的五种途径</title><link>http://www.blogjava.net/Vencent/articles/36074.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sun, 19 Mar 2006 08:03:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36074.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36074.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36074.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36074.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#author">Philip McCarthy</a>, 软件开发顾问, 独立顾问<br /></p>
		<p>2005 年  10 月  24 日</p>
		<blockquote>如果您正在使用异步 JavaScript 和 XML（Ajax）进行 Java™ Web 开发，那么您最关心的问题可能就是把数据从服务器传递给客户机。在 <i>面向 Java 开发人员的 Ajax</i> 系列的第二篇文章中，Philip McCarthy 介绍了 Java 对象序列化的五种方式，并提供了选择最适合应用程序的数据格式和技术所需要的全部信息。</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>在这个系列的 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/">第一篇文章</a> 中，我介绍了 Ajax 的构造块：</p>
		<ul>
				<li>如何用 JavaScript <code>XMLHttpRequest</code> 对象从 Web 页面向服务器发送异步请求。</li>
				<li>如何用 Java servlet 处理和响应请求（向客户机返回 XML 文档）。</li>
				<li>如何在客户端用响应文档更新页面视图。</li>
		</ul>
		<p>这一次，我将继续讨论 Ajax 开发的基础知识，但是将侧重于许多 Java Web 开发人员最关心的问题：为客户机生成数据。</p>
		<p>多
数 Java 开发人员已经把模型-视图-控制器（MVC）模式应用在他们的 Web 应用程序上。在传统的 Web 应用程序中，视图组件由 JSP
或者其他表示技术（例如 Velocity 模板）构成。这些表示组件动态地生成全新的 HTML
页面，替代用户以前正在查看的页面，从而更新用户界面。但是，在 Java Web 应用程序使用 Ajax UI 的情况下，基于从 <code>XMLHttpRequest</code> 的响应接收到的数据，JavaScript 客户端代码对于更新用户看到的内容负有最终责任。从服务器的角度来看，视图成为它响应客户机请求而发送的数据表示。</p>
		<p>这
篇文章侧重于可以用来生成 Java 对象以数据为中心的视图的技术。我将演示可以把 JavaBeans 变成 XML
文档的各种方法，并且讨论每种方法的优劣。您将看到为什么 XML 并不总是最好的途径：对于简单的 Ajax
请求来说，传输纯文本更好。最后，我将介绍 JavaScript 对象标注（JSON）。JSON 允许数据以序列化的 JavaScript
对象图的形式传输，在客户端代码中处理序列化的 JavaScript 对象图极为容易。</p>
		<p>
				<a name="N10078">
						<span class="smalltitle">关于示例</span>
				</a>
		</p>
		<p>我将使用一个示例应用程序和几个用例来演示这里讨论的技术特性和技术。图 1 显示的极为简单的数据模型可以表示示例用例。这个模型代表在线商店中的顾客帐户。顾客拥有以前订单的集合，每个订单包含几个商品。</p>
		<br />
		<a name="figure1">
				<b>图 1. 简单的对象模型</b>
		</a>
		<br />
		<img alt="代表顾客帐户的对象模型" src="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/ajaxobjects.jpg" height="133" width="541" />
		<br />
		<p>虽然 <code>XMLHttpRequest</code> 对于发送数据使用的格式没有做任何限制，但是对于多数目的来说，只发送传统的表单数据是适合的，所以我的讨论集中在服务器的响应上。响应也可以有基于文本的格式，但是正如它的名字表示的，<code>XMLHttpRequest</code> 具有内置的处理 XML 响应数据的能力。这使 XML 成为 Ajax 响应的默认选择，所以我们从 XML 格式开始讨论。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1009B">
						<span class="atitle">从 Java 类产生 XML</span>
				</a>
		</p>
		<p>把
Ajax 响应作为 XML 来传递有许多原因：每个支持 Ajax 的浏览器都有导航 XML 文档的方法，也有许多服务器端技术可以处理 XML
数据。通过制定一个方案，描述要交换的文档类型，在 Ajax
客户端和服务器端之间很容易定义合约，而且如果服务器端架构采用面向服务的方式，那么使用 XML 也可以允许非 Ajax 客户机使用您提供的数据。</p>
		<p>我将考虑从 Java 对象产生 XML 数据的三种方法，并讨论每种方法的优劣。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100A7">
						<span class="atitle">自行进行序列化</span>
				</a>
		</p>
		<p>首先，可以从对象图以编程的方式生成 XML。这种方式可以简单到只是在每个 JavaBean 类中实现 <code>toXml()</code>
方法即可。然后就可以选择合适的 XML API，让每个 bean
提供表示自己状态的元素，并递归地对自己的成员调用对象图。显然，这种方式无法扩展到大量的类，因为每个类都需要专门编写自己的 XML
生成代码。从好的方面来看，这是一个实现起来简单的方式，没有额外的配置支出或者更复杂的构建过程支出，任何 JavaBean
图都可以只用几个调用就变成 XML 文档。</p>
		<p>在本系列 <a href="http://www.ibm.com/developerworks/cn/java/j-ajax1/">前一篇文章</a> 的示例代码中，我把 XML 标记字符串连接在一起，实现了 <code>toXml()</code> 方法。上次我就提到过，这是个糟糕的方法，因为它把确保标记配对、实体编码等工作的负担放在每个 <code>toXml()</code> 方法的代码中。在 Java 平台上有几个 XML API 可以替您做这些工作，这样您就可以把精力集中在 XML 的内容上。清单 1 用 JDOM API 实现了在线商店示例中表示订单的类中的 <code>toXml()</code>（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#figure1">图 1</a>）。</p>
		<br />
		<a name="code1">
				<b>清单 1. Order 类的 toXml() 的 JDOM 实现</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />public Element toXml() {<br /><br />  Element elOrder = new Element("order");<br />  elOrder.setAttribute("id",id);<br /><br />  elOrder.setAttribute("cost",getFormattedCost());<br /><br />  Element elDate = new Element("date").addContent(date);<br />  elOrder.addContent(elDate);<br /><br />  Element elItems = new Element("items");<br />  for (Iterator&lt;Item&gt; iter = <br />   items.iterator() ; iter.hasNext() ; ) {<br />    elItems.addContent(iter.next().toXml());<br />  }<br />  elOrder.addContent(elItems);<br /><br />  return elOrder;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在这里可以看到用 JDOM 创建元素、使用属性和添加元素内容有多么简单。递归地调用复合 JavaBean 的 <code>toXml()</code> 方法是为了取得它们子图的 <code>Element</code> 表示。例如，<code>items</code> 元素的内容是通过调用 <code>Order</code> 聚合的每个 <code>Item</code> 对象上的 <code>toXml()</code> 得到的。</p>
		<p>一旦所有的 JavaBean 都实现了 <code>toXml()</code> 方法，那么把任意对象图序列化成 XML 文档并返回给 Ajax 客户机就简单了，如清单 2 所示。</p>
		<br />
		<a name="code2">
				<b>清单 2. 从 JDOM 元素生成 XML 响应</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />public void doGet(HttpServletRequest req, HttpServletResponse res)<br />  throws java.io.IOException, ServletException {<br /><br />    String custId = req.getParameter("username");<br />    Customer customer = getCustomer(custId);<br /><br />    Element responseElem = customer.toXml();<br />    Document responseDoc = new Document(responseElem);<br /><br />    res.setContentType("application/xml");<br />    new XMLOutputter().output(responseDoc,res.getWriter());<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>JDOM 再次把工作变得非常简单。只需要在对象图返回的 XML 元素外面包装一个 <code>Document</code>，然后用 <code>XMLOutputter</code> 把文档写入 servlet 响应即可。清单 3 显示了用这种方式生成的 XML 示例，用 JDOM <code>Format.getPrettyFormat()</code> 对 <code>XMLOutputter</code> 进行初始化，格式化得非常好。在这个示例中，顾客只做了一个订单，包含两个商品。</p>
		<br />
		<a name="code3">
				<b>清单 3. 代表顾客的 XML 文档</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;customer username="jimmy66"&gt;<br />  &lt;realname&gt;James Hyrax&lt;/realname&gt;<br />  &lt;orders&gt;<br />    &lt;order id="o-11123" cost="$349.98"&gt;<br />      &lt;date&gt;08-26-2005&lt;/date&gt;<br />      &lt;items&gt;<br />        &lt;item id="i-55768"&gt;<br />          &lt;name&gt;Oolong 512MB CF Card&lt;/name&gt;<br />          &lt;description&gt;512 Megabyte Type 1 CompactFlash card. <br />          Manufactured by Oolong Industries&lt;/description&gt;<br />          &lt;price&gt;$49.99&lt;/price&gt;<br />        &lt;/item&gt;<br />        &lt;item id="i-74491"&gt;<br />          &lt;name&gt;Fujak Superpix72 Camera&lt;/name&gt;<br />          &lt;description&gt;7.2 Megapixel digital camera featuring six <br />          shooting modes and 3x optical zoom. Silver.&lt;/description&gt;<br />          &lt;price&gt;$299.99&lt;/price&gt;<br />        &lt;/item&gt;<br />      &lt;/items&gt;<br />    &lt;/order&gt;<br />  &lt;/orders&gt;<br />&lt;/customer&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="N1011B">
						<span class="smalltitle">自行序列化的不足</span>
				</a>
		</p>
		<p>有趣的是，清单 3 中的代码展示了让 JavaBean 把自己序列化为 XML 的一个主要不足。假设要用这个文档表示顾客的订单历史视图。在这种情况下，不太可能要显示每个历史订单中每个商品的完整说明，或者告诉顾客他或她自己的姓名。但是如果应用程序有一个 <code>ProductSearch</code> 类，它就是以 <code>Item</code> bean 列表的形式返回搜索结果，那么在 <code>Item</code> 的 XML 表示中包含说明可能会有帮助。而且，<code>Item</code> 类上代表当前库存水平的额外字段，在产品搜索视图中可能就是需要显示的有用信息。但是，不管当前的库存水平是否与当前情况相关（比如对顾客的订单历史来说），这个字段都会从包含 <code>Item</code> 的任何对象图中序列化出来。</p>
		<p>从
设计的角度来看，这是数据模型与视图生成耦合的经典问题。每个 bean 只能用一种途径序列化自己，一成不变的方式意味着 Ajax
交互最终要交换它们不需要交换的数据，因此造成客户端代码要从文档中找到需要的信息更加困难，而且也会增加带宽消耗和客户端的 XML
解析时间。这种耦合的另一个后果就是 XML 的语法不能脱离 Java 类独立变化。例如，对顾客文档的方案做修改，可能会影响多个 Java
类，造成它们也不得不做修改和重新编译。</p>
		<p>我稍后会解决这些问题，但是首先来看一个对自行序列化方式的可伸缩性问题的解决方案：XML 绑定框架。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1013E">
						<span class="atitle">XML 绑定框架</span>
				</a>
		</p>
		<p>近
些年来，已经开发了多个 Java API 来简化 XML 文档到 Java 对象图的绑定过程。多数都提供了 XML
编排和拆解；也就是说，它们可以在 Java 对象图和 XML 之间执行双向会话。这些框架封装了 XML
处理的全部工作，这意味着应用程序代码只需要处理普通的 Java
类。它们还希望提供有用的辅助功能，例如文档验证。笼统来说，这些框架采用了两种不同的方式：代码生成和对象到 XML 映射。我将分别解释这两种方式。</p>
		<p>
				<a name="N10147">
						<span class="smalltitle">代码生成方式</span>
				</a>
		</p>
		<p>使
用代码生成的框架包括 XMLBeans、JAXB、Zeus 和 JBind。Castor 也能使用这项技术。这类框架的起点是描述文档数据类型的
XML 方案。使用框架提供的工具，就可以生成代表这些方案定义类型的 Java
类。最后，用这些生成的类编写应用程序，表示自己的模型数据，并通过框架提供的一些辅助机制把数据序列化成 XML。</p>
		<p>如果应用程
序要使用大型 XML 语法，那么代码生成方式是个很好的方法。在数十个类上编写定制 XML
序列化代码的可伸缩性问题由此消除。另一方面，也不再需要定义自己的 JavaBean。框架生成的 Java 类通常非常符合 XML
的结构，所以对它们进行编码很难。而且，生成的类变成哑数据容器，因为一般不能向它们添加行为。一般来说，在应用程序代码中要做些妥协，才能很好地处理方
案生成的类型。另一个缺陷是如果修改方案，会造成生成的类也要修改，所以也就会对围绕它们编写的代码带来相应的影响。</p>
		<p>这种类型的 XML 绑定框架在数据拆解时最有用（例如，使用 XML 文档并把它们转化成 Java 对象）。除非拥有大型数据模型而且有可能从生成的类中获益，否则基于代码生成的框架对于 Ajax 应用程序来说可能有很大的杀伤力。</p>
		<p>
				<a name="N10156">
						<span class="smalltitle">映射方式</span>
				</a>
		</p>
		<p>采
用映射方式的框架包括 Castor 和 Apache Commons
Betwixt。映射通常是比代码生成更灵活和更轻量的解决方案。首先，可以像通常一样编写
JavaBean，包括任何行为以及任何自己喜欢的方便的方法。然后，在运行时，调用框架中基于内省的编排器，并根据对象成员的类型、名称和值生成
XML 文档。通过定义类的映射文件，可以覆盖默认的绑定策略，并就类在 XML 中的表示方式对编排器提出建议。</p>
		<p>这种方法是在
可伸缩性与灵活性之间的良好折中。可以按照自己喜欢的方式编写 Java 类，编排器负责处理
XML。虽然映射定义文件编写起来简单，可伸缩性也足够好，但是映射规则最多只能改变标准的绑定行为，而且在对象结构和它们的 XML
表示之间总要残留一些耦合。最终，可能不得不在 Java 表示或 XML 格式之间任选一个做些折中，才能让映射方法起作用。</p>
		<p>
				<a name="N10162">
						<span class="smalltitle">数据绑定总结</span>
				</a>
		</p>
		<p>Dennis Sosnoski 就 XML 数据绑定 API 的主题，在代码生成和代码映射两个方面写了深入的文章。如果想进一步研究这个领域，我推荐他在 Castor 和代码生成框架方面的精彩文章（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#resources">参考资料</a> 中的链接）。</p>
		<p>总之，代码生成方式损失了过多的灵活性和方便性，对于典型的 Ajax 应用程序用处不大。另一方面，基于映射的框架可能工作得很好，但是要恰到好处地调整它们的映射策略，以便从对象生成需要的 XML。</p>
		<p>所
有的 XML 绑定 API 都具有手工序列化技术的一个主要不足：模型和视图的耦合。被限制为一个类型一个 XML
表示，就意味着在网络上总要有冗余数据传输。更严重的问题是，在情况要求客户端代码使用专门视图时，客户端代码却无法得到它，所以可能要费力地处理给定对
象图的一成不变的视图。</p>
		<p>在传统的 Web 应用程序开发中，采用页面模板系统把视图生成与控制器逻辑和模型数据干净地分离。这种方法在 Ajax 场景中也会有帮助。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10178">
						<span class="atitle">页面模板系统</span>
				</a>
		</p>
		<p>任何通用目的的页面模板技术都可以用来生成 XML，从而使 Ajax 应用程序根据自己的数据模型生成任何 XML 响应文档。额外收获是：模板可以用简单的、表现力强的标记语言编写，而不是用一行行的 Java 代码编写。清单 5 是一个 JSP 页面，采用了 <code>Customer</code> bean 并表示出定制的 XML 视图，适合客户端代码生成订单历史组件。</p>
		<br />
		<a name="code4">
				<b>清单 4. 生成订单历史文档的 JSP</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;?xml version="1.0"?&gt;<br />&lt;%@ page contentType="application/xml" %&gt;<br />&lt;%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %&gt;<br />&lt;c:set var="cust" value="${requestScope.customer}"/&gt;<br /><br />&lt;orderhistory username="${cust.username}"&gt;<br />&lt;c:forEach var="order" items="${cust.orders}"&gt;<br />  &lt;order id="${order.id}" cost="${order.formattedCost}"&gt;<br />    &lt;date&gt;${order.date}&lt;/date&gt;<br />    &lt;items&gt;<br />    &lt;c:forEach var="item" items="${order.items}"&gt;<br />      &lt;item id="${item.id}"&gt;<br />        &lt;name&gt;&lt;c:out value="${item.name}" escapeXml="true"/&gt;&lt;/name&gt;<br />        &lt;price&gt;${item.formattedPrice}&lt;/price&gt;<br />      &lt;/item&gt;<br />    &lt;/c:forEach&gt;<br />    &lt;/items&gt;<br />  &lt;/order&gt;<br />&lt;/c:forEach&gt;<br />&lt;/orderhistory&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这个简洁的模板只输出订单历史视图需要的数据，不输出不相关的资料（例如商品说明）。创建产品搜索视图的定制 XML 应当同样简单，这个视图包含每个商品的完整说明和库存水平。</p>
		<p>
				<a name="N10191">
						<span class="smalltitle">模板的问题</span>
				</a>
		</p>
		<p>另
一方面，现在我需要为每个不同视图创建一个新
JSP，而不能仅仅把需要的对象图组织起来并序列化它。从设计的角度来说，许多人可能会有争议，认为这无论如何是件好事，因为这意味着正式地考虑服务器要
生成的文档类型。而且，因为我现在要处理通用的模板环境，而不是特定于 XML 的 API，所以确保标记匹配、元素和属性的顺序正确以及 XML
实体（例如 <code>&lt;</code> 或 <code>&amp;</code>）正确转义就成了我的责任。JSP 的核心 <code>out</code> 标记使后面这项工作变得很容易，但是不是所有的模板技术都提供了这样的机制。最后，没有方便的途径可以在服务器端根据方案检验生成的 XML 文档的正确性，但这毕竟不是要在生产环境中做的事，可以方便地在开发期间处理它。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101A6">
						<span class="atitle">不用 XML 的响应数据</span>
				</a>
		</p>
		<p>迄
今为止，我介绍的所有技术都用 XML 文档的形式生成服务器响应。但是，XML 有一些问题。其中一个就是延迟。浏览器不能立即解析 XML
文档并生成 DOM 模型，所以这会降低某些 Ajax
组件需要的“迅捷”感，特别是在较慢的机器上解析大型文档的时候更是如此。“现场搜索”就是一个示例，在这种搜索中，当用户输入搜索术语时，就会从服务器
提取搜索结果并显示给用户。对于现场搜索组件来说，迅速地响应输入是非常重要的，但是同时它还需要迅速而持续地解析服务器的响应。</p>
		<p>延迟是一个重要的考虑因素，但是避免使用 XML 的最大原因是差劲的客户端 DOM API。清单 5 显示了使用跨浏览器兼容的方式通过 DOM 得到某个值的时候，通常不得不面对的困难。</p>
		<br />
		<a name="code5">
				<b>清单 5. 在 JavaScript 中导航 XML 响应文档</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />// Find name of first item in customer's last order<br />var orderHistoryDoc = req.responseXML;<br /><br />var orders = orderHistoryDoc.getElementsByTagName("order");<br />var lastOrder = orders[orders.length - 1];<br /><br />var firstItem = lastOrder.getElementsByTagName("item")[0];<br />var itemNameElement = firstItem.firstChild;<br /><br />var itemNameText = itemNameElement.firstChild.data;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当元素中间存在空白时，情况就变得更加复杂，因为每个元素的 <code>firstChild</code> 经常是个空白文本节点。现在有 JavaScript 库可以缓解处理 XML 文档的麻烦。这些库包括 Sarissa （请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#resources">参考资料</a>）和 Google-ajaXSLT，这两个库都把 XPath 功能添加到了大多数浏览器中。</p>
		<p>但是，想想替代方案还是值得的。除了 <code>responseXML</code> 之外，<code>XMLHttpRequest</code> 对象还提供了名为 <code>responseText</code> 的属性，这个属性只是以字符串的方式提供服务器的响应体。</p>
		<p>
				<a name="N101D5">
						<span class="smalltitle">responseText 属性</span>
				</a>
		</p>
		<p>当服务器需要向客户机发送非常简单的值时，<code>responseText</code>
特别方便，它可以避免 XML 导致的带宽支出和处理支出。例如，简单的 true/false
响应可以由服务器以纯文本方式返回，可以是逗号分隔的简单的名称或数字列表。但是，一般来说，最好不要在同一个应用程序中把 XML
响应和纯文本响应混合使用；保持单一数据格式可以让代码抽象和重用更加简单。</p>
		<p>
				<code>responseText</code>
与 XML 响应数据结合时也会有用。在只需要从响应文档中提取单一值的场景中，“欺骗性”地把 XML
当作文本字符串，而不把它当作结构化的文档对待，会更方便。例如，清单 6
显示了如何用正则表达式从顾客的订单历史中提取第一笔订单的日期。不过，这实际是种花招，一般不应当依赖 XML 文档的词汇表达。</p>
		<br />
		<a name="code6">
				<b>清单 6. 用正则表达式处理 XMLHttpRequest 的 responseText 对象</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var orderHistoryText = req.responseText;<br />var matches = orderHistoryText.match(/&lt;date&gt;(.*?)&lt;\/date&gt;/);<br /><br />var date = matches[1];<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在某些情况下，采用即时方式使用 <code>responseText</code> 会比较方便。但是，理想情况下，应当有种途径，可以用一种能够让 JavaScript 轻松导航、却没有 XML 处理支出的格式表示复杂的结构化数据。幸运的是，确实存在这样一种格式。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101F9">
						<span class="atitle">JavaScript 对象标注</span>
				</a>
		</p>
		<p>实
际上，JavaScript 对象的大部分都由联合数组、数字索引数组、字符串、数字或者这些类型的嵌套组合而成。因为所有类型都可以用
JavaScript 直接声明，所以可以在一条语句中静态地定义对象图。清单 7 使用 JSON
语法声明了一个对象，并演示了如何访问这个对象。大括号表示联合数组（即对象），它的键 -值组合由逗号分隔。方括号表示数字索引数组。</p>
		<br />
		<a name="code7">
				<b>清单 7. 用 JSON 在 JavaScript 中直接声明一个简单对象</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var band = {<br />  name: "The Beatles",<br />  members: [<br />    {<br />      name: "John",<br />      instruments: ["Vocals","Guitar","Piano"]<br />    },<br />    {<br />      name: "Paul",<br />      instruments: ["Vocals","Bass","Piano","Guitar"]<br />    },<br />    {<br />      name: "George",<br />      instruments: ["Guitar","Vocals"]<br />    },<br />    {<br />      name: "Ringo",<br />      instruments: ["Drums","Vocals"]<br />    }<br />  ]<br />};<br /><br />// Interrogate the band object<br />var musician = band.members[3];<br />alert( musician.name<br />        + " played " + musician.instruments[0] <br />        + " with " + band.name );<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>既然 JSON
是一个有趣的语言特性，那么它对 Ajax 有什么意义呢？妙处在于可以用 JSON 在 Ajax 服务器响应中通过网络发送 JavaScript
对象图。这意味着在客户端可以避免使用笨拙的 DOM API 对 XML 进行导航 —— 只需要分析 JSON 响应，就会立即得到可以访问的
JavaScript 对象图。但是，首先需要把 JavaBean 变成 JSON。</p>
		<p>
				<a name="N1020E">
						<span class="smalltitle">从 Java 类产生 JSON</span>
				</a>
		</p>
		<p>不同 XML 生成技术所具有的优缺点也适用于 JSON 的产生。而且可以证明，存在需要再次使用表示模板技术的情况。但是，使用 JSON 在理念上更接近于在应用层之间传递序列化的对象，而不是创建应用程序状态的视图。我将介绍如何用 <code>org.json</code> 这个 Java API 在 Java 类上创建 <code>toJSONObject()</code> 方法。然后，就可以把 <code>JSONObject</code> 简单地序列化成 JSON。清单 8 反映了 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#code1">清单 1</a> 讨论的 XML，显示了 <code>Order</code> 类的 <code>toJSONObject()</code> 实现。</p>
		<br />
		<a name="code8">
				<b>清单 8. Order 类的 toJSONObject() 方法实现</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />public JSONObject toJSONObject() {<br /><br />  JSONObject json = new JSONObject();<br />  json.put("id",id);<br />  json.put("cost",getFormattedCost());<br />  json.put("date",date);<br /><br />  JSONArray jsonItems = new JSONArray();<br />  for (Iterator&lt;Item&gt; iter = <br />   items.iterator() ; iter.hasNext() ; ) {<br />    jsonItems.put(iter.next().toJSONObject());<br />  }<br />  json.put("items",jsonItems);<br /><br />  return json;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>可以看到，<code>org.json</code> API 非常简单。 <code>JSONObject</code> 代表 JavaScript 对象（即联合数组），有不同的 <code>put()</code> 方法，方法接受的 <code>String</code> 键和值是原生类型、<code>String</code> 类型或其他 JSON 类型。<code>JSONArray</code> 代表索引数组，所以它的 <code>put()</code> 方法只接受一个值。请注意在清单 8 中，创建 <code>jsonItems</code> 数组，然后再用 <code>put()</code> 把它附加到 <code>json</code> 对象上；可以用另外一种方法做这项工作，就是对每个项目调用 <code>json.accumulate("items",iter.next().toJSONObject());</code>。<code>accumulate()</code> 方法与 <code>put()</code> 类似，区别在于它把值添加到按照键进行识别的索引数组。</p>
		<p>清单 9 显示了如何序列化 <code>JSONObject</code> 并把它写入 servlet 响应。</p>
		<br />
		<a name="code9">
				<b>清单 9. 从 JSONObject 生成序列化的 JSON 响应</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />public void doGet(HttpServletRequest req, HttpServletResponse res) <br />  throws java.io.IOException, ServletException {<br /><br />	String custId = req.getParameter("username");<br />	Customer customer = getCustomer(custId);<br /><br />	res.setContentType("application/x-json");<br />	res.getWriter().print(customer.toJSONObject());<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>可以看到，它实际上什么也没有做。在这里隐式调用的 <code>JSONObject</code> 的 <code>toString()</code> 方法做了所有工作。请注意，<code>application/x-json</code> 内容类型还有一点不确定 —— 在编写这篇文章的时候，关于 JSON 应当属于什么 MIME 类型还没有定论。但是，目前 <code>application/x-json</code> 是合理的选择。清单 10 显示了这个 servlet 代码的示例响应。</p>
		<br />
		<a name="code10">
				<b>清单 10. Customer bean 的 JSON 表示</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />{<br />  "orders": [<br />    {<br />      "items": [<br />        {<br />          "price": "$49.99",<br />          "description": "512 Megabyte Type 1 CompactFlash card. <br />                              Manufactured by Oolong Industries",<br />          "name": "Oolong 512MB CF Card",<br />          "id": "i-55768"<br />        },<br />        {<br />          "price": "$299.99",<br />          "description": "7.2 Megapixel digital camera featuring six <br />            shooting modes and 3x optical zoom. Silver.",<br />          "name": "Fujak Superpix72 Camera",<br />          "id": "i-74491"<br />        }<br />      ],<br />      "date": "08-26-2005",<br />      "cost": "$349.98",<br />      "id": "o-11123"<br />    }<br />  ],<br />  "realname": "James Hyrax",<br />  "username": "jimmy66"<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="N1029B">
						<span class="smalltitle">在客户端使用 JSON </span>
				</a>
		</p>
		<p>处理的最后一步是把在客户端把 JSON 数据变成 JavaScript 对象。这可以通过对 <code>eval()</code> 的简单调用实现，这个函数可以即时地解释包含 JavaScript 表达式的字符串。清单 11 把 JSON 响应转变成 JavaScript 对象图，然后执行清单 5 的任务，从顾客的最后一次订单中得到第一个商品的名称。</p>
		<br />
		<a name="code11">
				<b>清单 11. 评估 JSON 响应</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var jsonExpression = "(" + req.responseText + ")";<br />var customer = eval(jsonExpression);<br /><br />// Find name of first item in customer's last order<br />var lastOrder = customer.orders[customer.orders.length-1];<br />var name = lastOrder.items[0].name;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>比较清单 11 和 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#code5">清单 5</a> 可以发现使用 JSON 的客户端的优势。如果在 Ajax 项目中要在客户端对许多复杂的服务器响应进行导航，那么 JSON 可能适合您的需要。JSON 和 <code>XMLHttpRequest</code> 结合还会让 Ajax 交互看起来更像 RPC 调用而不是 SOA 请求，这对应用程序的设计可能会有意义。在下一篇文章中，我要研究的框架，就是明确地为了让 JavaScript 代码对服务器端对象进行远程方法调用而设计的。</p>
		<p>
				<a name="N102BC">
						<span class="smalltitle">JSON 的不足</span>
				</a>
		</p>
		<p>JSON 也有它的不足。使用这里介绍的 JSON 方式，就没有办法针对每个请求对对象的序列化进行裁剪，所以不需要的字段可能经常会在网络上发送。另外，添加 <code>toJSONObject()</code>
方法到每个 JavaBean，可伸缩性不太好，虽然用内省和标注编写一个通用的 JavaBean 到 JSON
的序列化器可能很简单。最后，如果服务器端代码是面向服务的，没有单独针对处理 Ajax 客户请求调整过，那么由于对 XML 一致的支持，XML
会是更好的选择。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N102C9">
						<span class="atitle">比较序列化技术</span>
				</a>
		</p>
		<p>现
在已经看到了把 Java 状态传输到 Ajax 客户端的五种不同技术。我讨论了自行手工编码 XML 序列化、通过代码生成的 XML
绑定、通过映射机制的 XML 绑定、基于模板的 XML 生成以及手工编码到 JSON
的序列化。每种技术都有自己的优势和不足，分别适用于不同的应用程序架构。
</p>
		<p>为了总结每种方式的优势与不足，表 1 从六个方面进行了粗略的评分：</p>
		<dl>
				<dt>
						<b>可伸缩性</b>
				</dt>
				<dd>描述技术适应大量数据类型的容易程度。对于每个附加类型，编码和配置工作量是否会增长？</dd>
				<dt>
						<b>易于集成</b>
				</dt>
				<dd>评估把技术集成到项目的简单程度。是否需要更加复杂的构建过程？是否增加了部署的复杂性？</dd>
				<dt>
						<b>Java 类 API</b>
				</dt>
				<dd>描述以指定方式处理服务器端 Java 对象的容易程度。是可以编写普通的 bean，还是不得不处理笨拙的文档表示？</dd>
				<dt>
						<b>对输出的控制</b>
				</dt>
				<dd>描述对类的序列化表示控制的精确程度。</dd>
				<dt>
						<b>视图灵活性</b>
				</dt>
				<dd>评估从同一组对象是否可以创建不同的、定制的数据序列化。</dd>
				<dt>
						<b>客户端数据访问</b>
				</dt>
				<dd>描述 JavaScript 代码处理服务器响应数据的难易程度。</dd>
		</dl>
		<p>
		</p>
		<table class="data-table-1" summary="数据生成技术的相对价值" border="0" cellpadding="0" cellspacing="0" width="100%">
				<caption>
						<em>
表 1. 数据生成技术的相对价值</em>
				</caption>
				<tbody>
						<tr>
								<th>
										<br />
								</th>
								<th>自行编写 XML</th>
								<th>通过代码生成的 XML 绑定</th>
								<th>通过映射的 XML 绑定</th>
								<th>页面模板 XML</th>
								<th>手工编码的 JSON 序列化</th>
						</tr>
						<tr>
								<td class="tb-row">可伸缩性</td>
								<td>差</td>
								<td>好</td>
								<td>一般</td>
								<td>一般</td>
								<td>差</td>
						</tr>
						<tr class="alt-row">
								<td class="tb-row">易于集成</td>
								<td>好</td>
								<td>差</td>
								<td>一般</td>
								<td>一般</td>
								<td>好</td>
						</tr>
						<tr>
								<td class="tb-row">Java 类 API</td>
								<td>好</td>
								<td>差</td>
								<td>好</td>
								<td>好</td>
								<td>好</td>
						</tr>
						<tr class="alt-row">
								<td class="tb-row">对输出的控制</td>
								<td>好</td>
								<td>好</td>
								<td>一般</td>
								<td>好</td>
								<td>好</td>
						</tr>
						<tr>
								<td class="tb-row">视图灵活性</td>
								<td>差</td>
								<td>差</td>
								<td>差</td>
								<td>好</td>
								<td>差</td>
						</tr>
						<tr class="alt-row">
								<td class="tb-row">客户端数据访问</td>
								<td>差</td>
								<td>差</td>
								<td>差</td>
								<td>一般</td>
								<td>好</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N103A9">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>表
1
中的数据并不表明某项序列化技术比其他的技术好。毕竟，六种标准的相对重要性取决于项目的具体情况。例如，如果要处理数百种数据类型，这时想要的是可伸缩
性，那么代码生成可能就是最好的选择。如果需要为同一数据模型生成多个不同视图，那么就应当使用页面模板。如果处理的是小规模项目，想降低需要编写的
JavaScript 代码数量，那么请考虑 JSON。</p>
		<p>希望这篇文章为您提供了选择适合自己应用程序的序列化技术所需要的信息。请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#resources">参考资料</a>
一节，学习关于这里讨论的技术的更多内容。您还应当继续关注这个系列的下一篇文章，在下一篇文章中，我将介绍如何用直接 Web 远程（DWR）编写
Java Ajax 应用程序。DWR 框架支持从 JavaScript 代码中直接调用 Java
类上的方法。换句话说，它替您负责数据序列化的工作，所以您可以在更高的抽象层次上使用 Ajax。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>
			您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/java/library/j-ajax2/" target="_blank">英文原文</a> 。
			<br /><br /></li>
				<li>
“<a href="http://www.ibm.com/developerworks/xml/library/x-databdopt/">Data binding, Part 1: Code generation approaches -- JAXB and more</a>”（Dennis Sosnoski，developerWorks，2003 年 1 月）：对 XML 数据绑定技术的深入观察。<br /><br /></li>
				<li>
“<a href="http://www-128.ibm.com/developerworks/cn/xml/x-bindcastor/">XML 与 Java 技术: 用 Castor 进行数据绑定</a>”（Dennis Sosnoski，developerWorks，2003 年 4 月）：使用 Castor 的映射方式的入门教程。<br /><br /></li>
				<li>
“<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-ajax1/">AJAX 及使用 E4X 编写 Web 服务脚本，第 1 部分</a>”（Paul Fremantle 和 Anthony Elder，developerWorks，2005 年 4 月）：对使用 E4X 的 Ajax 的介绍，E4X 是对 JavaScript 的扩展，可以简化 XML 脚本编写。<br /><br /></li>
				<li>
						<a href="http://www.manning.com/books/crane/">Ajax In Action（Dave Crane，Eric Pascarello，Darren James；Manning，2005 年 11 月）</a>：深入介绍了 Ajax 的 MVC 技术，也涉及了 JSON。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/views/opensource/projectnews.jsp">developerWorks open source project news</a>：当前开源项目的清单，例如 PAJAJ（PHP 异步 Javascript 和 JSON）。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/">Java 技术专区</a>：数百篇关于 Java 编程各方面的文章。<br /><br /></li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
						<a href="http://sourceforge.net/projects/sarissa">Sarissa</a>：一个支持 XPath 的跨浏览器的 JavaScript 库。<br /><br /></li>
				<li>
						<a href="http://jakarta.apache.org/commons/betwixt/">Jakarta Commons Betwixt</a>：一个灵活的基于映射的 XML 绑定库。<br /><br /></li>
				<li>
						<a href="http://www.json.org/">JSON</a>：用于 Java 和其他语言的 JavaScript 对象标注 API。<br /><br /></li>
		</ul>
		<br />
		<b>讨论</b>
		<br />
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/community/">参与论坛讨论</a>。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/blogs/">developerWorks
blogs</a>：加入 developerWorks 社区。</li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Philip
McCarthy 是一位软件开发顾问，专攻 Java 和 Web 技术。他目前在位于 Bristol 的 HP 实验室从事 Hewlett
Packard 数字媒体平台的工作 。在最近几年中，Phil 开发了多个采用异步服务器通信和 DOM 脚本的富 Web
客户端。他很高兴我们现在有了一个针对它们的名称。可以通过 Phil 的电子邮件 <a href="mailto:philmccarthy@gmail.com">philmccarthy@gmail.com</a> 与他联系。</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/36074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-19 16:03 <a href="http://www.blogjava.net/Vencent/articles/36074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 AJAX 调用 SOAP Web 服务，第 1 部分: 构建 Web 服务客户机</title><link>http://www.blogjava.net/Vencent/articles/36073.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sun, 19 Mar 2006 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/36073.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/36073.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/36073.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/36073.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/36073.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#author">James Snell</a>, 软件工程师, IBM<br /></p>
		<p>2006 年  1 月  16 日</p>
		<blockquote>本文介绍如何使用异步 JavaScript 和 XML (Asynchronous JavaScript and XML, AJAX) 设计模式来实现基于 Web 浏览器的 SOAP Web 服务客户机。</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>本文是一篇短的系列文章的第 1 部分，演示了如何使用针对 Web 应用程序的 AJAX 设计模式来实现跨平台的基于 JavaScript 的 SOAP Web 服务客户机。</p>
		<p>AJAX
已普遍用于许多知名的 Web 应用程序服务，例如 GMail、Google Maps、Flickr 和 Odeo.com。通过使用异步 XML
消息传递，AJAX 为 Web 开发人员提供了一种扩展其 Web 应用程序价值和功能的途径。这里介绍的 Web Services
JavaScript
Library 扩展了该基础机制，其通过引入对调用基于 SOAP 的 Web 服务的支持来增强 AJAX 设计模式。</p>
		<p>
				<a name="N10066">
						<span class="atitle">从浏览器中调用 Web 服务</span>
				</a>
		</p>
		<p>从 Web 浏览器中调用 SOAP Web 服务可能会比较麻烦，这是因为大多数流行的 Web 浏览器在生成和处理 XML 方面都略有不同。所有浏览器都一致实现且用于 XML 处理的标准 API 或功能少之又少。</p>
		<p>浏
览器实现人员一致支持的机制之一是 XMLHttpRequest API，它是 AJAX 设计模式的核心。developerWorks
网站最近发布的另一篇由 Philip McCarthy 撰写的的文章详细介绍了该 API。XMLHttpRequest 是一个用于执行异步
HTTP 请求的 JavaScript 对象。Philip McCarthy 在其文章中描述了一个顺序图（请参见<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#figure1">图 1</a>），此图对于理解 XMLHttpRequest 对象如何支持 AJAX 设计非常有帮助（请参阅<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#resources">参考资料</a>，以获得指向全文的链接）。</p>
		<br />
		<a name="figure1">
				<b>图 1. Philip McCarthy 的 AJAX 顺序图</b>
		</a>
		<br />
		<img alt="Philip McCarthy 的 AJAX 顺序图" src="http://www.ibm.com/developerworks/java/library/j-ajax1/ajax.gif" height="630" width="556" />
		<br />
		<p>从
此图中，您可以清楚地看到 XMLHttpRequest 对象是如何工作的。一些运行在 Web 浏览器内的 JavaScript 创建了一个
XMLHttpRequest 实例和一个用于异步回调的函数。然后，该脚本使用 XMLHttpRequest 对象对服务器执行 HTTP
操作。在接收到响应后，调用回调函数。在该回调函数内，可能处理返回的数据。如果返回的数据碰巧是 XML，则 XMLHttpRequest
对象将自动使用浏览器中内置的 XML 处理机制来解析该数据。</p>
		<p>遗憾的是，使用 AJAX 方法的主要难题在于 XMLHttpRequest 对象自动解析 XML 的详细过程。例如，假设我正在请求的数据是一个 SOAP 信封，其包含来自许多不同 XML 命名空间的元素，并且我希望提取 <code>yetAnotherElement</code> 中属性 <code>attr</code> 的值。（请参见<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing1">清单 1</a>）</p>
		<br />
		<a name="listing1">
				<b>清单 1. 一个包含多个命名空间的 SOAP 信封</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;s:Envelope <br />  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" <br />  xmlns:xsd="http://www.w3.org/2001/XMLSchema" <br />  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;<br />  &lt;s:Header/&gt;<br />  &lt;s:Body&gt;<br />    &lt;m:someElement xmlns:m="http://example"&gt;<br />      &lt;n:someOtherElement <br />        xmlns:n="http://example" <br />        xmlns:m="urn:example"&gt;<br />        &lt;m:yetAnotherElement <br />          n:attr="abc" <br />          xmlns:n="urn:foo"/&gt;<br />      &lt;/n:someOtherElement&gt;<br />    &lt;/m:someElement&gt;<br />  &lt;/s:Body&gt;<br />&lt;/s:Envelope&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在 Mozilla 浏览器和 Firefox 浏览器中，提取 <code>attr</code> 属性值非常简单，如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing2">清单 2</a>所示。</p>
		<br />
		<a name="listing2">
				<b>清单 2. 在 Mozilla 和 Firefox 中检索 attr 属性值的方法不能运用在 Internet Explorer 中</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var m = el.getElementsByTagNameNS(<br />  'urn:example',<br />  'yetAnotherElement')[0].<br />    getAttributeNS(<br />      'urn:foo',<br />      'attr');<br />alert(m); // displays 'abc'<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="side">
																				<b>关于安全性</b>
																		</a>
																		<br />
																		<p>由
于涉及许多实际安全问题，因此在缺省情况下，大多数 Web 浏览器中的 XMLHttpRequest 对象都限制为只能与用户正在查看的 Web
页所在的域中承载的资源和服务进行交互。例如，如果我正在访问一个位于 http://example.com/myapp/ 的页面，则
XMLHttpRequest 将只允许访问位于 example.com
域中的资源。对于阻止恶意应用程序代码潜在地对其不应该访问的信息进行不适当的访问，这种预防措施非常必要。因为这里介绍的 Web 服务客户机基于
XMLHttpRequest，所以这种限制同样适用于您将会调用的 Web 服务。</p>
																		<p>如果您需要能够访问位于另一个域中的 Web 服务，您可以使用以下两种合理的解决方案：</p>
																		<ul>
																				<li>
																						<b>对 JavaScript 进行数字签名。</b>通过对 JavaScript 脚本进行数字签名，您就告诉了 Web 浏览器可以信任该脚本不会执行任何恶意的活动，并且对 XMLHttpRequest 可以访问的数据的限制也应该取消。</li>
																				<li>
																						<b>使用代理。</b>一
个简单的解决方案是，通过位于加载的页面所在的域中的代理资源来传递所有来自 XMLHttpRequest 的请求。该代理将
XMLHttpRequest 的请求转发到远程位置，并将结果返回给浏览器。从 XMLHttpRequest
对象的角度来看，这种交互发生在现有的安全配置之内。</li>
																		</ul>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>遗
憾的是，以上代码无法在 Internet Explorer Version 6 中运行，因为该浏览器不仅没有实现
getElementsByTagNameNS 功能，而且事实上还使用了一种很糟糕的方法——将 XML
命名空间的前缀作为其元素和属性名称的一部分来对待。</p>
		<p>Internet Explorer 缺少对 XML
命名空间的支持，这使得它很难处理命名空间密集的 XML 格式，例如采用独立于浏览器的方式的
SOAP。即使要执行一些像提取结果中的属性值这样简单的操作，您也必须编写能够在多个浏览器中实现一致预期行为的特殊代码。幸运的是，这种特殊代码可以
封装并重用。</p>
		<p>为了从 Web 浏览器中调用 Web 服务，并可靠地处理 SOAP 消息，您需要首先了解一些安全问题（请参见侧栏<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#side">“关于安全性”</a>）。此外，您还需要编写一个 JavaScript 脚本库（<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#figure2">图 2</a>），以便将底层浏览器 XML 实现中的不一致情况抽象出来，从而使您能够直接处理 Web 服务数据。</p>
		<br />
		<a name="figure2">
				<b>图 2. 在使用 Web Services JavaScript Library 的 Web 浏览器中通过 Javascript 调用 Web 服务</b>
		</a>
		<br />
		<img alt="在 Web 浏览器中通过 Javascript 调用 Web 服务" src="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/soapajax1.gif" height="353" width="362" />
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#figure2">图 2</a> 中的 Web Services JavaScript Library (ws.js) 是一组 JavaScript 对象和实用功能，它们为基于 SOAP 1.1 的 Web 服务提供了基本的支持。Ws.js 定义了下列对象：</p>
		<ul>
				<li>
						<b>WS.Call</b>：一个包装了  XMLHttpRequest 的 Web 服务客户机</li>
				<li>
						<b>WS.QName</b>：XML 限定名实现</li>
				<li>
						<b>WS.Binder</b>：自定义 XML 序列化器/反序列化器的基础</li>
				<li>
						<b>WS.Handler</b>：请求/响应处理程序的基础</li>
				<li>
						<b>SOAP.Element</b>：包装了 XML DOM 的基本 SOAP 元素</li>
				<li>
						<b>SOAP.Envelope</b>：SOAP Envelope 对象扩展了 SOAP.Element</li>
				<li>
						<b>SOAP.Header</b>：SOAP Header 对象扩展了 SOAP.Element</li>
				<li>
						<b>SOAP.Body</b>：SOAP Body 对象扩展了 SOAP.Element</li>
				<li>
						<b>XML</b>：用于处理 XML 的跨平台实用方法</li>
		</ul>
		<p>ws.js 的核心是 WS.Call 对象，该对象提供了调用 Web 服务的方法。WS.Call 主要负责与 XMLHttpRequest 对象进行交互，并处理 SOAP 响应。</p>
		<p>WS.Call 对象公开了以下三个方法：</p>
		<ul>
				<li>
						<b>add_handler。</b>向处理链添加请求/响应处理程序。处理程序对象在调用 Web 服务的前后被调用，以支持可扩展的预调用处理和后调用处理。</li>
				<li>
						<b>invoke。</b>将指定的 SOAP.Envelope 对象发送给 Web 服务，然后在接收到响应后调用回调函数。当调用使用文本 XML 编码的文档样式的 Web 服务时，请使用此方法。</li>
				<li>
						<b>invoke_rpc。</b>创建一个封装 RPC 样式请求的 SOAP.Envelope，并将其发送到 Web 服务。当接收到响应时，调用回调函数。</li>
		</ul>
		<p>在
通常情况下，WS.Call 对象只不过是位于 XMLHttpRequest 对象顶层的瘦包装器 (thin
wrapper)，该包装器能够执行许多简化处理的操作。这些操作包括设置 SOAP 1.1 规范要求的 SOAPAction HTTP
Header。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10159">
						<span class="atitle">使用 ws.js</span>
				</a>
		</p>
		<p>Web services JavaScript Library 提供的 API 非常简单。</p>
		<p>SOAP.* 对象（<code>SOAP.Element</code>、<code>SOAP.Envelope</code>、<code>SOAP.Header</code>
和 <code>SOAP.Body</code>）提供了构建和读取 SOAP 信封的方法，如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing3">清单 3</a> 所示，因而处理 XML 文档对象模型的底层细节就顺利地抽象出来。</p>
		<br />
		<a name="listing3">
				<b>清单 3. 构建一个 SOAP 信封</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var envelope = new SOAP.Envelope();<br />var body = envelope.create_body();<br />var el = body.create_child(new WS.QName('method','urn:foo'));<br />el.create_child(new WS.QName('param','urn:foo')).set_value('bar');<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing4">清单 4</a> 显示了由 <a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing3">清单 3</a> 中的代码生成的 SOAP 信封。</p>
		<br />
		<a name="listing4">
				<b>清单 4. 构建一个 SOAP 信封</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;Envelope xmlns="http://schemas.xmlsoap.org"&gt;<br />  &lt;Body&gt;<br />    &lt;method xmlns="urn:foo"&gt;<br />      &lt;param&gt;bar&lt;/param&gt;<br />    &lt;/method&gt;<br />  &lt;/Body&gt;<br />&lt;/Envelope&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>如果您正在创建的 SOAP 信封代表一个 RPC 样式的请求，则 SOAP.Body 元素提供了一个简便方法 <code>set_rpc</code>（如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing5">清单 5</a> 所示），该方法能够构造一个完整的 RPC 请求——包含一个指定的操作名称、一个指定的输入参数数组和一个 SOAP 编码样式的 URI。</p>
		<br />
		<a name="listing5">
				<b>清单 5. 构建一个 RPC 请求信封</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var envelope = new SOAP.Envelope();<br />var body = envelope.create_body();<br />body.set_rpc(<br />  new WS.QName('param','urn:foo'),<br />  new Array(<br />    {name:'param',value:'bar'}<br />  ), SOAP.NOENCODING<br />);<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>每个参数都作为一个 JavaScript 对象结构进行传递，且可能带有以下属性：</p>
		<ul>
				<li>
						<b>name。</b>一个指定参数名称的字符串或 WS.QName 对象。<i>必需</i>。</li>
				<li>
						<b>value。</b>参数的值。如果该值不是一个简单数据类型（例如，字符串、整数或其他），则应该指定一个能将该值序列化为适当的 XML 结构的 WS.Binder。<i>必需</i>。</li>
				<li>
						<b>xsitype</b>：标识参数的 XML 模式实例类型的 WS.QName（例如，<code>xsi:type="int"</code> 对应 <code>xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema')</code>）。<i>可选</i>。</li>
				<li>
						<b>encodingstyle</b>：标识参数所使用的 SOAP 编码样式的 URI。<i>可选</i>。</li>
				<li>
						<b>binder</b>：能够将参数序列化为 XML 的 WS.Binder 实现。<i>可选</i>。</li>
		</ul>
		<p>例如，如果要指定的参数名为“abc”、XML 命名空间为“urn:foo”、xsi:type 为“int”且值为“3”，则我会使用以下代码：<code>new Array({name:new WS.QName('abc','urn:foo'), value:3, 
xsitype:new WS.QName('int','http://www.w3.org/2000/10/XMLSchema')})</code>。</p>
		<p>一旦我为服务请求构建了 SOAP.Envelope，我就会将该 SOAP.Envelope 传递到 WS.Call 对象的 <code>invoke</code> 方法，以便调用该信封内编码的方法：
<code>(new WS.Call(service_uri)).invoke(envelope, callback)</code></p>
		<p>另一种可选方案是手动构建 SOAP.Envelope。我会将参数 WS.QName、参数数组和编码样式传递到
WS.Call 对象的 <code>invoke_rpc</code> 方法，如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing6">清单 6</a> 所示。</p>
		<br />
		<a name="listing6">
				<b>清单 6. 使用 WS.Call 对象调用 Web 服务</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var call = new WS.Call(serviceURI); <br />var nsuri = 'urn:foo';<br />var qn_op = new WS.QName('method',nsuri);<br />var qn_op_resp = new WS.QName('methodResponse',nsuri);  <br />  call.invoke_rpc(<br />    qn_op,<br />    new Array(<br />      {name:'param',value:'bar'}<br />    ),SOAP.NOENCODING,<br />    function(call,envelope) {<br />      // envelope is the response SOAP.Envelope<br />      // the XML Text of the response is in arguments[2]<br />    }<br />  );<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在调用 <code>invoke</code> 方法或
<code>invoke_rpc</code> 方法时，WS.Call 对象会创建一个基本的 XMLHttpRequest 对象，用包含 SOAP 信封的 XML 元素进行传递，并接收和解析响应，然后调用提供的回调函数。</p>
		<p>为了能够扩展 SOAP 消息的预处理和后处理，WS.Call 对象允许您注册一组 WS.Handler 对象，如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing7">清单 7</a> 所示。对于调用周期内的每个请求、每个响应和每个错误，都将调用这些对象。可以通过扩展 WS.Handler JavaScript 对象来实现新的处理程序。</p>
		<br />
		<a name="listing7">
				<b>清单 7. 创建和注册响应/响应处理程序</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var MyHandler = Class.create();<br />MyHandler.prototype = (new WS.Handler()).extend({<br />  on_request : function(envelope) {<br />     // pre-request processing<br />  },<br />  on_response : function(call,envelope) {<br />     // post-response, pre-callback processing<br />  },<br />  on_error : function(call,envelope) {<br />  }<br />});<br /><br />var call = new WS.Call(...);<br />call.add_handler(new MyHandler());<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>处理程序对插入或提取正在传递的 SOAP 信封中的信息最有用。例如，您可以设想一个处理程序自动向 SOAP Envelope 的 Header 插入适当的 Web 服务寻址 (Web Services Addressing) 元素，如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing8">清单 8</a> 中的示例所示。</p>
		<br />
		<a name="listing8">
				<b>清单 8. 一个将 Web 服务寻址操作 Header 添加到请求中的处理程序示例</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var WSAddressingHandler = Class.create();<br />WSAddressingHandler.prototype = (new WS.Handler()).extend({<br />  on_request : function(call,envelope) {  		<br />    envelope.create_header().create_child(<br />        new WS.QName('Action','http://ws-addressing','wsa')<br />      ).set_value('http://www.example.com');<br />  }<br />});<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>WS.Binder 对象（<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing9">清单 9</a>）执行 SOAP.Element 对象的自定义序列化和反序列化。WS.Binder 的实现必须提供以下两个方法：</p>
		<ul>
				<li>
						<b>to_soap_element。</b>将 JavaScript 对象序列化为 SOAP.Element。传入的第一个参数是要序列化的值。第二个参数是 SOAP.Element，必须将要序列化的值序列化为 SOAP.Element。该方法不返回任何值。</li>
				<li>
						<b>to_value_object。</b>将 SOAP.Element 反序列化为 JavaScript 对象。该方法必须返回反序列化的值对象。</li>
		</ul>
		<br />
		<a name="listing9">
				<b>清单 9. WS.Binding 实现示例</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />var MyBinding = Class.create();<br />MyBinding.prototype = (new WS.Binding()).extend({<br />  to_soap_element : function(value,element) {  		<br />    ...<br />  },<br />  to_value_object : function(element) {<br />    ...<br />  }<br />});<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1025C">
						<span class="atitle">一个简单示例</span>
				</a>
		</p>
		<p>我已经提供了一个示例项目来阐释 Web Services JavaScript Library 的基本功能。该演示所使用的 Web 服务（如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing10">清单 10</a> 所示）已经在 WebSphere Application Server 中进行了实现，并提供了简单的 Hello World 功能。</p>
		<br />
		<a name="listing10">
				<b>清单 10. 一个简单的基于 Java 的“Hello World”Web 服务</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />package example;<br /><br />public class HelloWorld {<br />  public String sayHello(String name) {<br />    return "Hello " + name;<br />  }<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在实现了该服务并将其部署到 WebSphere Application Server 后，该服务（<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing11">清单 11</a>）的 WSDL 描述定义了您需要传递的 SOAP 消息（用于调用 Hello World 服务）。</p>
		<br />
		<a name="listing11">
				<b>清单 11. HelloWorld.wsdl 的代码片段</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;wsdl:portType name="HelloWorld"&gt;<br />  &lt;wsdl:operation name="sayHello"&gt;<br />    &lt;wsdl:input <br />      message="impl:sayHelloRequest" <br />      name="sayHelloRequest"/&gt;<br />    &lt;wsdl:output <br />      message="impl:sayHelloResponse" <br />      name="sayHelloResponse"/&gt;<br />  &lt;/wsdl:operation&gt;<br />&lt;/wsdl:portType&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>通过使用 Web Services JavaScript Library，您可以实现一个调用 Hello World 服务的方法，如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing12">清单 12</a>所示。</p>
		<br />
		<a name="listing12">
				<b>清单 12. 使用 WS.Call 调用 HelloWorld 服务</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;html&gt;<br />&lt;head&gt;<br />...<br />&lt;script <br />  type="text/javascript" <br />  src="scripts/prototype.js"&gt;&lt;/script&gt;<br />&lt;script <br />  type="text/javascript" <br />  src="scripts/ws.js"&gt;&lt;/script&gt;<br />&lt;script type="text/javascript"&gt;<br />function sayHello(name, container) {<br /><span class="boldcode">  var call = new WS.Call('/AjaxWS/services/HelloWorld'); <br />  var nsuri = 'http://example';<br />  var qn_op = new WS.QName('sayHello',nsuri);<br />  var qn_op_resp = new WS.QName('sayHelloResponse',nsuri);  <br />  call.invoke_rpc(<br />    qn_op,<br />    new Array(<br />      {name:'name',value:name}<br />    ),null,<br />    function(call,envelope) {<br />      var ret = <br />        envelope.get_body().get_all_children()[0].<br />          get_all_children()[0].get_value();<br />      container.innerHTML = ret;<br />      $('soap').innerHTML = arguments[2].escapeHTML();<br />    }<br />  );</span><br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br />...<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>然后，您可以在我们的 Web 应用程序中的任意位置通过调用 <code>sayHello</code> 函数来调用 Hello World 服务。请参见<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#listing13">清单 13</a>。</p>
		<br />
		<a name="listing13">
				<b>清单 13. 调用 sayHello 函数</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;body&gt;<br />&lt;input name="name" id="name" /&gt;<br />&lt;input value="Invoke the Web Service"<br />       type="button" <br />       onclick="sayHello($('name').value,$('result'))" /&gt;<br />&lt;div id="container"&gt;Result:<br />&lt;div id="result"&gt;<br />&lt;/div&gt;<br />&lt;div id="soap"&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;<br />&lt;/body&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>调用成功后的结果如<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#figure3">图 3</a> 所示。在 Mozilla、Firefox 和 Internet Explorer 中运行该示例应该会得到相同的结果。</p>
		<br />
		<a name="figure3">
				<b>图 3. Firefox 中的 Hello World 示例</b>
		</a>
		<br />
		<img alt="Firefox 中的 Hello World 示例" src="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/soapajax2.gif" height="342" width="600" />
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N102C4">
						<span class="atitle">后续部分</span>
				</a>
		</p>
		<p>使
用 Web Services JavaScript Library，可以采用简单的独立于浏览器的方式将基本的 SOAP Web 服务合并到
Web 应用程序中。在本系列的下一个部分中，您不仅可以探讨如何使用该库来调用更多基于 Web 服务资源框架 (WS-Resource
Framework ) 系列规范的高级 Web 服务，而且还可以了解扩展该 Web 服务功能并将其集成到 Web 应用程序中的方法。</p>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<span class="atitle">
						<a name="download">下载</a>
				</span>
		</p>
		<table class="data-table-1" border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<th>描述</th>
								<th>名字</th>
								<th style="text-align: right;">大小</th>
								<th>下载方法</th>
						</tr>
						<tr>
								<td class="tb-row">Sample project</td>
								<td nowrap="nowrap">ws-wsajaxcode.zip</td>
								<td style="text-align: right;" nowrap="nowrap">19 KB</td>
								<td nowrap="nowrap">
                               <a class="fbox" href="ftp://www6.software.ibm.com/software/developer/library/ws-wsajaxcode.zip"><b>FTP</b></a></td>
						</tr>
				</tbody>
		</table>
		<table border="0" cellpadding="0" cellspacing="0">
				<tbody>
						<tr valign="top">
								<td colspan="5">
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="12" width="12" />
								</td>
						</tr>
						<tr>
								<td>
										<img alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" height="16" width="16" />
								</td>
								<td>
										<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/whichmethod.html">关于下载方法的信息</a>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="50" />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/v14/icons/sout.gif" height="16" width="16" />
								</td>
								<td>
										<a class="fbox" href="http://www.adobe.com/products/acrobat/readstep2.html">Get Adobe® Reader®</a>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www-128.ibm.com/developerworks/webservices/library/ws-wsajax/" target="_blank">英文原文</a>。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-ajax1/">面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序</a>——Philip McCarthy 在本文中向 Java 开发人员介绍了 Ajax（developerWorks，2005 年 9 月）。<br /><br /></li>
				<li>
						<a href="http://prototype.conio.net/">JavaScript
Framework</a>——了解 Web Services JavaScript Library 所基于的原型框架。<br /><br /></li>
				<li>
						<a href="http://www.xulplanet.com/references/objref/XMLHttpRequest.html">XMLHttpRequest API</a>——从 XUL Planet 网站上了解更多关于 XMLHttpRequest API 的内容。<br /><br /></li>
				<li>
						<a href="http://www.xulplanet.com/references/objref/XMLHttpRequest.html">XMLHttpRequest API</a> -- Learn more about it from the XUL Planet Web site.<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/webservices/library/wa-richcli.html">Exploit the Document Object Model to create enhanced Web applications
</a>——了解更多关于 Microsoft Internet Explorer 6.0 所使用的 XML 文档对象模型的内容（developerWorks，2004 年 2 月）。<br /><br /></li>
				<li>
						<a href="http://www.mozilla.org/projects/webservices/">Mozilla Web services</a>——了解更多关于
Mozilla/Firefox 内置 Web 服务支持的内容。<br /><br /></li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>从 developerWorks 下载 <a href="http://www.ibm.com/developerworks/cn/downloads/">WebSphere Application Server</a> 的免费试用版。</li>
		</ul>
		<br />
		<b>讨论</b>
		<br />
		<ul>
				<li>
通过参与 <a href="http://www.ibm.com/developerworks/blogs/">developerWorks 博客</a>加入 developerWorks 社区。<br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-wsajax/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="James M Snell 的照片" src="http://www.ibm.com/developerworks/i/p-jsnell.jpg" align="left" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>James Snell 是 IBM Emerging Technologies Toolkit 团队的成员。在过去几年里，他一直致力于新兴 Web 服务技术和标准的研究，并且还参与了 Atom 1.0 规范的制定。他现在维护着一个专注于新兴技术的博客 <a href="http://www.ibm.com/developerworks/blogs/dw_blog.jspa?blog=351">http://www.ibm.com/developerworks/blogs/dw_blog.jspa?blog=351</a>。</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/36073.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-19 16:00 <a href="http://www.blogjava.net/Vencent/articles/36073.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 问题: 超越 DOM::轻松使用 DOM 的技巧和诀窍</title><link>http://www.blogjava.net/Vencent/articles/35990.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:33:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35990.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35990.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35990.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35990.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35990.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#author">Dethe Elza</a>, 高级技术架构师, Blast Radius<br /></p>
		<p>2005 年  6 月  16 日</p>
		<blockquote>文
档对象模型（Document Object Model，DOM）是用于操纵 XML 和 HTML
数据的最常用工具之一，然而它的潜力却很少被充分挖掘出来。通过利用 DOM 的优势，并使它更加易用，您将获得一款应用于 XML
应用程序（包括动态 Web 应用程序）的强大工具。</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>
				<i>本期文章介绍了
一位客串的专栏作家，同时也是我的朋友和同事 Dethe Elza。Dethe 在利用 XML 进行 Web
应用程序开发方面经验丰富，在此，我要感谢他对我在介绍使用 DOM 和 ECMAScript 进行 XML
编程这一方面的帮助。请密切关注本专栏，以了解 Dethe 的更多专栏文章。 —— David Mertz</i>
		</p>
		<p>DOM
是处理 XML 和 HTML 的标准 API
之一。由于它占用内存大、速度慢，并且冗长，所以经常受到人们的指责。尽管如此，对于很多应用程序来说，它仍然是最佳选择，而且比 XML
的另一个主要 API —— SAX 无疑要简单得多。DOM 正逐渐出现在一些工具中，比如 Web 浏览器、SVG
浏览器、OpenOffice，等等。</p>
		<p>DOM
很好，因为它是一种标准，并且被广泛地实现，同时也内置到其他标准中。作为标准，它对数据的处理与编程语言无关（这可能是优点，也可能是缺点，但至少使我
们处理数据的方式变得一致）。DOM 现在不仅内置于 Web 浏览器，而且也成为许多基于 XML
的规范的一部分。既然它已经成为您的工具的一部分，并且或许您偶尔还会使用它，我想现在应该充分利用它给我们带来的功能了。</p>
		<p>在使用 DOM 一段时间后，您会看到形成了一些模式 —— 您想要反复做的事情。快捷方式可以帮助您处理冗长的 DOM，并创建自解释的、优雅的代码。这里收集了一些我经常使用的技巧和诀窍，还有一些 JavaScript 示例。</p>
		<p>
				<a name="N10059">
						<span class="atitle">insertAfter 和 prependChild</span>
				</a>
		</p>
		<p>第一个诀窍就是“没有诀窍”。DOM 有两种方法将孩子节点添加到容器节点（常常是一个 <code>Element</code>，也可能是一个 <code>Document</code> 或 <code>DocumentFragment</code>）：<code>appendChild(node)</code> 和 <code>insertBefore(node, referenceNode)</code>。看起来似乎缺少了什么。假如我想在一个参考节点后面插入或者由前新增（prepend）一个子节点（使新节点位于列表中的第一位），我该怎么做呢？很多年以来，我的解决方法是编写下列函数：</p>
		<br />
		<a name="N10076">
				<b>清单 1. 插入和由前新增的错误方法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />function insertAfter(parent, node, referenceNode) {<br />    if(referenceNode.nextSibling) {<br />        parent.insertBefore(node, referenceNode.nextSibling);<br />    } else {<br />        parent.appendChild(node);<br />    }<br />}<br />function prependChild(parent, node) {<br />    if (parent.firstChild) {<br />        parent.insertBefore(node, parent.firstChild);<br />    } else {<br />        parent.appendChild(node);<br />    }<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>实际上，像清单 1 一样，<code>insertBefore()</code> 函数已经被定义为，在参考节点为空时返回到 <code>appendChild()</code>。因此，您可以不使用上面的方法，而使用 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#listing2">清单 2</a> 中的方法，或者跳过它们仅使用内置函数：</p>
		<br />
		<a name="listing2">
				<b>清单 2. 插入和由前新增的正确方法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />function insertAfter(parent, node, referenceNode) {<br />    parent.insertBefore(node, referenceNode.nextSibling);<br />}<br />function prependChild(parent, node) {<br />    parent.insertBefore(node, parent.firstChild);<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>如果您刚刚接触 DOM
编程，有必要指出的是，虽然您可以使多个指针指向一个节点，但该节点只能存在于 DOM
树中的一个位置。因此，如果您想将它插入到树中，没必要先将它从树中移除，因为它会自动被移除。当重新将节点排序时，这种机制很方便，仅需将节点插入到新
位置即可。</p>
		<p>根据这种机制，若想交换两个相邻节点（称为 <code>node1</code> 和 <code>node2</code>）的位置，可以使用下列方案之一：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">node1.parentNode.insertBefore(node2, node1);</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>或</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">node1.parentNode.insertBefore(node1.nextSibling, node1);</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100B6">
						<span class="atitle">还可以使用 DOM 做什么？</span>
				</a>
		</p>
		<p>Web 页面中大量应用了 DOM。若访问 bookmarklets 站点（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#resources">参考资料</a>），您会发现很多有创意的简短脚本，它们可以重新编排页面，提取链接，隐藏图片或 Flash 广告，等等。</p>
		<p>但是，因为 Internet Explorer 没有定义 <code>Node</code> 接口常量（可以用于识别节点类型），所以您必须确保在遗漏接口常量时，首先为 Web 在 DOM 脚本中定义接口常量。</p>
		<br />
		<a name="N100CA">
				<b>清单 3. 确保节点被定义</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />if (!window['Node']) {<br />    window.Node = new Object();<br />    Node.ELEMENT_NODE = 1;<br />    Node.ATTRIBUTE_NODE = 2;<br />    Node.TEXT_NODE = 3;<br />    Node.CDATA_SECTION_NODE = 4;<br />    Node.ENTITY_REFERENCE_NODE = 5;<br />    Node.ENTITY_NODE = 6;<br />    Node.PROCESSING_INSTRUCTION_NODE = 7;<br />    Node.COMMENT_NODE = 8;<br />    Node.DOCUMENT_NODE = 9;<br />    Node.DOCUMENT_TYPE_NODE = 10;<br />    Node.DOCUMENT_FRAGMENT_NODE = 11;<br />    Node.NOTATION_NODE = 12;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#listing4">清单 4</a> 展示如何提取包含在节点中的所有文本节点：</p>
		<br />
		<a name="listing4">
				<b>清单 4. 内部文本</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />function innerText(node) {<br />    // is this a text or CDATA node?<br />    if (node.nodeType == 3 || node.nodeType == 4) {<br />        return node.data;<br />    }<br />    var i;<br />    var returnValue = [];<br />    for (i = 0; i &lt; node.childNodes.length; i++) {<br />        returnValue.push(innerText(node.childNodes[i]));<br />    }<br />    return returnValue.join('');<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100E9">
						<span class="atitle">快捷方式</span>
				</a>
		</p>
		<p>人们常常抱怨 DOM 太过冗长，并且简单的功能也需要编写大量代码。例如，如果您想创建一个包含文本并响应点击按钮的 <code>&lt;div&gt;</code> 元素，代码可能类似于：</p>
		<br />
		<a name="listing5">
				<b>清单 5. 创建 &lt;div&gt; 的“漫长之路”</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />function handle_button() {<br />    var parent = document.getElementById('myContainer');<br />    var div = document.createElement('div');<br />    div.className = 'myDivCSSClass';<br />    div.id = 'myDivId';<br />    div.style.position = 'absolute';<br />    div.style.left = '300px';<br />    div.style.top = '200px';<br />    var text = "This is the first text of the rest of this code";<br />    var textNode = document.createTextNode(text);<br />    div.appendChild(textNode);<br />    parent.appendChild(div);<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>若频繁按照这种方式创建节点，键入所有这些代码会使您很快疲惫不堪。必须有更好的解决方案 —— 确实有这样的解决方案！下面这个实用工具可以帮助您创建元素、设置元素属性和风格，并添加文本子节点。除了 <code>name</code> 参数，其他参数都是可选的。</p>
		<br />
		<a name="N10109">
				<b>清单 6. 函数 elem() 快捷方式</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />function elem(name, attrs, style, text) {<br />    var e = document.createElement(name);<br />    if (attrs) {<br />        for (key in attrs) {<br />            if (key == 'class') {<br />                e.className = attrs[key];<br />            } else if (key == 'id') {<br />                e.id = attrs[key];<br />            } else {<br />                e.setAttribute(key, attrs[key]);<br />            }<br />        }<br />    }<br />    if (style) {<br />        for (key in style) {<br />            e.style[key] = style[key];<br />        }<br />    }<br />    if (text) {<br />        e.appendChild(document.createTextNode(text));<br />    }<br />    return e;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>使用该快捷方式，您能够以更加简洁的方法创建 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#listing5">清单 5</a> 中的 <code>&lt;div&gt;</code> 元素。注意，<code>attrs</code> 和 <code>style</code> 参数是使用 JavaScript 文本对象而给出的。</p>
		<br />
		<a name="N10128">
				<b>清单 7. 创建 &lt;div&gt; 的简便方法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />function handle_button() {<br />    var parent = document.getElementById('myContainer');<br />    parent.appendChild(elem('div',<br />      {class: 'myDivCSSClass', id: 'myDivId'}<br />      {position: 'absolute', left: '300px', top: '200px'},<br />      'This is the first text of the rest of this code'));<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在您想要快速创建大量复杂的 DHTML
对象时，这种实用工具可以节省您大量的时间。模式在这里就是指，如果您有一种需要频繁创建的特定的 DOM
结构，则使用实用工具来创建它们。这不但减少了您编写的代码量，而且也减少了重复的剪切、粘贴代码（错误的罪魁祸首），并且在阅读代码时思路更加清晰。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10137">
						<span class="atitle">接下来是什么？</span>
				</a>
		</p>
		<p>DOM 通常很难告诉您，按照文档的顺序，下一个节点是什么。下面有一些实用工具，可以帮助您在节点间前后移动：</p>
		<br />
		<a name="N10140">
				<b>清单 8. nextNode 和 prevNode</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />// return next node in document order<br />function nextNode(node) {<br />    if (!node) return null;<br />    if (node.firstChild){<br />        return node.firstChild;<br />    } else {<br />        return nextWide(node);<br />    }<br />}<br />// helper function for nextNode()<br />function nextWide(node) {<br />    if (!node) return null;<br />    if (node.nextSibling) {<br />        return node.nextSibling;<br />    } else {<br />        return nextWide(node.parentNode);<br />    }<br />}<br />// return previous node in document order<br />function prevNode(node) {<br />    if (!node) return null;<br />    if (node.previousSibling) {<br />      return previousDeep(node.previousSibling);<br />    }<br />    return node.parentNode;<br />}<br />// helper function for prevNode()<br />function previousDeep(node) {<br />    if (!node) return null;<br />    while (node.childNodes.length) {<br />        node = node.lastChild;<br />    }<br />    return node;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1014C">
						<span class="atitle">轻松使用 DOM</span>
				</a>
		</p>
		<p>有
时候，您可能想要遍历 DOM，在每个节点调用函数或从每个节点返回一个值。实际上，由于这些想法非常具有普遍性，所以 DOM Level 2
已经包含了一个称为 DOM Traversal and Range 的扩展（为迭代 DOM 所有节点定义了对象和 API），它用来为 DOM
中的所有节点应用函数和在 DOM 中选择一个范围。因为这些函数没有在 Internet Explorer
中定义（至少目前是这样），所以您可以使用 <code>nextNode()</code> 来做一些类似的事情。</p>
		<p>在这里，我们的想法是创建一些简单、普通的工具，然后以不同的方式组装它们来达到预期的效果。如果您很熟悉函数式编程，这看起来会很亲切。Beyond JS 库（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#resources">参考资料</a>）将此理念发扬光大。</p>
		<br />
		<a name="N10160">
				<b>清单 9. 函数式 DOM 实用工具</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />// return an Array of all nodes, starting at startNode and<br />// continuing through the rest of the DOM tree<br />function listNodes(startNode) {<br />    var list = new Array();<br />    var node = startNode;<br />    while(node) {<br />        list.push(node);<br />        node = nextNode(node);<br />    }<br />    return list;<br />}<br />// The same as listNodes(), but works backwards from startNode.<br />// Note that this is not the same as running listNodes() and<br />// reversing the list.<br />function listNodesReversed(startNode) {<br />    var list = new Array();<br />    var node = startNode;<br />    while(node) {<br />        list.push(node);<br />        node = prevNode(node);<br />    }<br />    return list;<br />}<br />// apply func to each node in nodeList, return new list of results<br />function map(list, func) {<br />    var result_list = new Array();<br />    for (var i = 0; i &lt; list.length; i++) {<br />        result_list.push(func(list[i]));<br />    }<br />    return result_list;<br />}<br />// apply test to each node, return a new list of nodes for which<br />// test(node) returns true<br />function filter(list, test) {<br />    var result_list = new Array();<br />    for (var i = 0; i &lt; list.length; i++) {<br />        if (test(list[i])) result_list.push(list[i]);<br />    }<br />    return result_list;<br />}<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>清单 9 包含了 4 个基本工具。<code>listNodes()</code> 和 <code>listNodesReversed()</code> 函数可以扩展到一个可选的长度，这与 <code>Array</code> 的 <code>slice()</code> 方法效果类似，我把这个作为留给您的练习。另一个需要注意的是，<code>map()</code> 和 <code>filter()</code> 函数是完全通用的，用于处理<i>任何</i> 列表（不只是节点列表）。现在，我向您展示它们的几种组合方式。</p>
		<br />
		<a name="N1018A">
				<b>清单 10. 使用函数式实用工具</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />// A list of all the element names in document order<br />function isElement(node) {<br />    return node.nodeType == Node.ELEMENT_NODE;<br />}<br />function nodeName(node) {<br />    return node.nodeName;<br />}<br />var elementNames = map(filter(listNodes(document),isElement), nodeName);<br />// All the text from the document (ignores CDATA)<br />function isText(node) {<br />    return node.nodeType == Node.TEXT_NODE;<br />}<br />function nodeValue(node) {<br />    return node.nodeValue;<br />}<br />var allText = map(filter(listNodes(document), isText), nodeValue);<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>您可以使用这些实用工具来提取 ID、修改样式、找到某种节点并移除，等等。一旦 DOM Traversal and Range API 被广泛实现，您无需首先构建列表，就可以用它们修改 DOM 树。它们不但功能强大，并且工作方式也与我在上面所强调的方式类似。</p>
		<p>
				<a name="N10199">
						<span class="smalltitle">DOM 的危险地带</span>
				</a>
		</p>
		<p>注
意，核心 DOM API 并不能使您将 XML 数据解析到 DOM，或者将 DOM 序列化为 XML。这些功能都定义在 DOM Level 3
的扩展部分“Load and Save”，但它们还没有被完全实现，因此现在不要考虑这些。每个平台（浏览器或其他专业 DOM 应用程序）有自己在
DOM 和 XML 间转换的方法，但跨平台转换不在本文讨论范围之内。</p>
		<p>DOM 并不是十分安全的工具 —— 特别是使用 DOM API 创建不能作为 XML 序列化的树时。绝对不要在同一个程序中混合使用 DOM1 非名称空间 API 和 DOM2 名称空间感知的 API（例如，<code>createElement</code> 和 <code>createElementNS</code>）。如果您使用名称空间，请尽量在根元素位置声明所有名称空间，并且不要覆盖名称空间前缀，否则情况会非常混乱。一般来说，只要按照惯例，就不会触发使您陷入麻烦的临界情况。</p>
		<p>如果您一直使用 Internet Explorer 的 <code>innerText</code> 和 <code>innerHTML</code> 进行解析，那么您可以试试使用 <code>elem()</code> 函数。通过构建类似的一些实用工具，您会得到更多便利，并且继承了跨平台代码的优越性。将这两种方法混合使用是非常糟糕的。</p>
		<p>某
些 Unicode 字符并没有包含在 XML 中。DOM 的实现使您可以添加它们，但后果是无法序列化。这些字符包括大多数的控制字符和
Unicode 代理对（surrogate
pair）中的单个字符。只有您试图在文档中包含二进制数据时才会遇到这种情况，但这是另一种转向（gotcha）情况。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101BF">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>我已经介绍了 DOM 能做的很多事情，但是 DOM（和 JavaScript）可以做的事情远不止这些。仔细研究、揣摩这些例子，看看是如何使用它们来解决可能需要客户端脚本、模板或专用 API 的问题。</p>
		<p>DOM
有自己的局限性和缺点，但同时也拥有众多优点：它内置于很多应用程序中；无论使用 Java 技术、Python 或
JavaScript，它都以相同方式工作；它非常便于使用 SAX；使用上述的模板，它使用起来既简洁又强大。越来越多的应用程序开始支持
DOM，这包括基于 Mozilla 的应用程序、OpenOffice 和 Blast Radius 的 XMetaL。越来越多的规范需要
DOM，并对它加以扩展（例如，SVG），因此 DOM 时时刻刻就在您的身边。使用这种被广泛部署的工具，绝对是您的明智之举。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li> 您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/xml/library/x-matters41.html" target="_blank">英文原文</a>。<br /><br /></li>
				<li>下载 <a href="http://livingcode.org/xmlmatters/beyondthedom/BeyondTheDom.js">JavaScript 库</a>，它包含了上面的脚本和一个用于测试这些脚本的简单 <a href="http://livingcode.org/xmlmatters/beyondthedom/BeyondTheDomTest.html">测试页面</a>。<br /><br /></li>
				<li>直接访问 DOM 发源地 —— W3C 的 <a href="http://www.w3.org/DOM/">DOM 资源页面</a> ，其中包含到所有与文档对象模型相关的标准的链接。<br /><br /></li>
				<li>查看 Jesse Ruderman 的 <a href="http://www.squarefree.com/bookmarklets/">bookmarklets</a>。虽然 Ruderman 没有创造术语“bookmarkets”，但他收集了很多一流的、简短的、书签似的 JavaScript，使用它们开发 DOM 的巨大潜力，使您的浏览器可以为您带来更多帮助。<br /><br /></li>
				<li>访问 Sjoerd Visscher 的 <a href="http://w3future.com/html/beyondJS/">Beyond JS</a> 库，它提供了远远超过我在这里提及的用于函数式编程的工具。如果您可以将事物抽象为函数，那么 JavaScript 将会成为您得心应手的工具。<br /><br /></li>
				<li>DOM API 的标准参考在 W3C。这里是 <a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html">DOM2 到 JavaScript （ECMAScript）映射</a> 的网址。<br /><br /></li>
				<li>了解 AJAX 为什么已经引起了这么大的反响。它使用了异步调用来使服务器实时升级 Web 应用程序。您可以使用上述的许多技术，并阅读 <a href="http://www.mod-pubsub.org/kn_docs/faq.html">异步通信工具</a>。<br /><br /></li>
				<li>了解一下 XML 编辑器和工具的 <a href="http://xmetal.com/">XMetaL</a> 系列，它们都支持 DOM API。它们由作者所在的公司 Blast Radius 开发。<br /><br /></li>
				<li>在 developerWorks 的 <a href="http://devworks.krcinfo.com/">Developer Bookstore</a> 了解更多 XMl 相关的书籍，其中包括 David Mertz 的 <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0321112547"><i>Text Processing in Python</i></a> 一书。<br /><br /></li>
				<li>了解如何才能成为 <a href="http://www-1.ibm.com/certify/certs/adcdxmlrt.shtml"> IBM 认证的 XML 及相关技术的开发人员</a>。<br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters41.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Dethe Elza 现在最喜爱的头衔是“首席疯狂科学家（Chief Mad Scientist）”。可以通过电子邮件 <a href="mailto:delza@livingcode.org">delza@livingcode.org</a> 与他联系。他在 <a href="http://livingcode.blogspot.com/">http://livingcode.blogspot.com/</a> 上主要记录着关于 Python 和 Mac OS X 方面的 blog。欢迎对本专栏提出意见和建议。</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35990.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:33 <a href="http://www.blogjava.net/Vencent/articles/35990.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 事件简介::用较少的脚本编写动态文档</title><link>http://www.blogjava.net/Vencent/articles/35988.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:28:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35988.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35988.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35988.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35988.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35988.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#author">Micah Dubinko</a>, 首席顾问, Brain Attic, L.L.C.<br /></p>
		<p>2004 年  12 月  01 日</p>
		<blockquote>一
些标记技术涉及到为文档的某些部分附加上行为。XML Events 是 W3C
推荐的一种标准，它允许通过声明为特定的元素附加行为，这种行为可以是 XML
中预先定义的一组动作，也可以是更一般的脚本语言调用。本文将简要地介绍 XML Events 的由来、用途以及其工作方式。</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>
				<a name="h1">
						<span class="atitle">两种类型的事件</span>
				</a>
		</p>
		<p>清单 1 列出了一些可能的变体。它定义了两个事件处理程序，一个用于 
        <code>load</code> 事件，另一个用于 
        <code>unload</code> 事件。一个处理程序是用 VBScript 编写的，通过一种不常见的技术附加到元素上，并用到了 
        <code>script</code> 元素的额外属性。另一个则是用 ECMAscript（请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#resources">参考资料</a>）编写的。
      </p>
		<br />
		<a name="code1">
				<b>清单 1. 两种类型的事件</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"<br />       "http://www.w3.org/TR/html4/loose.dtd"&gt;<br />&lt;html&gt;<br />  &lt;head&gt;<br />    &lt;title&gt;Intrinsic Events&lt;/title&gt;<br />    &lt;script event="onload" for="window" language="vbscript"&gt;<br />&lt;!--<br />alert "hello"<br />--&gt;<br />    &lt;/script&gt;<br />  &lt;/head&gt;<br />  &lt;body onunload="alert('goodbye')"&gt;<br />  &lt;/body&gt;<br />&lt;/html&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>如果使用
Microsoft Internet Explorer 或者其他支持 VBScript
的浏览器查看，在加载文档的时候，就会出现一个显示“hello”的警告框。基本上所有的浏览器在关闭窗口或者导航到其他页面时都会显示
“goodbye”。要完整地描述这到底是怎么发生的，就需要了解 DOM Events，该标准目前由 Document Object Model
(DOM) Level 2 Events Specification（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#resources">参考资料</a>）授权的 W3C 文档指定。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h2">
						<span class="atitle">事件的工作原理</span>
				</a>
		</p>
		<p>
				<b>事件</b>到底是什么呢？对于本文而言，最好不要从“事件”一词的传统含义上思考，而应将其看作一种数据结构，包含变化的某些事物的详细信息。比方说，在 
        <code>mouseover</code> 事件中，我们所关心的事件对象的信息是鼠标指针的坐标、按下了哪个键、当前是否按下了修饰键如“shift”等等。单个事件对象的存活期非常短，在其消失之前刚够时间进行即时处理。
      </p>
		<p>每个事件都有一个
        <b>目标</b>，XML 或 HTML 元素和事件的关系最密切。事件
        <b>处理程序</b>是对应特定事件的一段可执行代码或者标记。某些事件和其他处理程序不同，比如单击一个超链接，会引发称为
        <b>默认动作</b>的活动。
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code1">清单 1</a> 中 
        <code>unload</code> 事件的目标是 
        <code>body</code> 元素，事件处理程序 
        <code>onunload</code> 属性中为数不多的那一点脚本。
      </p>
		<p>
				<a name="h3">
						<span class="smalltitle">事件流</span>
				</a>
		</p>
		<p>最简单、最常用的技术是直接将事件处理程序附加到目标上，过去，浏览器只支持这种技术。但是，这样做常常行不通，比如清单 2 中的例子：</p>
		<br />
		<a name="code2">
				<b>清单 2. 论证是否需要事件观测者</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;p&gt;You want to capture all clicks on this paragraph,<br />even if the text has &lt;em&gt;special markup&lt;/em&gt;.&lt;/p&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code2">清单 2</a> 中，假设对目标为 
        <code>p</code> 元素的 
        <code>click</code> 事件有一个处理程序。如果用户恰好单击“special markup”这两个词，则会创建目标为 
        <code>em</code> 元素的一个事件。因为目标不是段落，单击事件处理程序就不会被触发。解决这个问题的方法是在 
        <code>p</code> 元素上放一个 
        <b>observer</b> 事件，它能够对以该元素自身或者
        <i>它的所有子元素</i>为目标的事件作出响应。
      </p>
		<p>DOM Level 2 Events 描述了如何连接事件处理程序，以解决
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code2">清单 2</a> 中所示的问题，尽管由于浏览器的历史原因，这种方法可能有点过于复杂（Internet Explorer 和 Netscape 的早期版本各有自己的特点，其中一些要比正式的 DOM 规范早得多）。事件按照文档的树状结构进行假想的旅行，这个过程称为
        <b>传播</b>。实际上它的旅行有两次：第一次旅行称为
        <b>捕获</b>，从文档根开始，前进到目标元素。进行常规的目标处理后，第二次旅行称为
        <b>冒泡（bubbling）</b>，从目标元素开始，再回到文档根。每个阶段中，路径中的任何元素都可以注册为事件观测者，从而能够触发事件处理程序。然后事件将停止传播，避免后面的观测者再检测到发生的事件。图 1 说明了传播的过程。
      </p>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="30%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="side1">
																				<b>事件和可访问性</b>
																		</a>
																		<br />
																		<p>无论何时考虑事件，都需要判断您到底需要哪种事件。比方说，确实关心按钮是否被鼠标单击吗？如果用其他某种方式激活又怎么样？一些 Web 用户没有鼠标，甚至都没有这样的图形用户界面。更好的办法是尽量使用设备无关的事件，比如用 
          <code>DOMActivate</code> 代替按钮的 
          <code>click</code> 事件。
        </p>
																		<p>W3C 发布的一些文档（请参阅
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#resources">参考资料</a>）描述了增强 Web 内容访问性的技术。
        </p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<a name="fig1">
				<b>图 1. 事件的传播</b>
		</a>
		<br />
		<img alt="一个树状结构，包括根、 &lt;html&gt;、&lt;body&gt;、&lt;p&gt; 和 &lt;em&gt;。标记为“capture”的箭头从根开始直到 &lt;em&gt;，后者标记为“target”。从目标回溯到根的箭头标记为“bubble”。&lt;p&gt; 元素标记为“observer”。" src="http://www-128.ibm.com/developerworks/cn/xml/x-events/propagation.gif" height="337" width="269" />
		<br />
		<p>如果需要设置事件观测者，应该使用捕获阶段还是冒泡阶段呢？下面是一些指导原则：</p>
		<ul>
				<li>如果处理单个观测点 —— 这也是最常见的情况，使用哪个阶段都行，两者没有实际区别。只有需要从文档树中的多个位置观测一个事件时才会造成区别。</li>
				<li>某些事件（如 
          <code>focus</code>）不参与冒泡阶段，因此只能在捕获阶段观测，或者直接在目标上观测。
        </li>
				<li>当存在多个观测者时，如果希望首先触发最近的观测者则使用冒泡阶段。比如，假设在
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#fig1">图 1</a> 中，
          <code>body</code> 和 
          <code>p</code> 上都有观测者。捕获的时候 
          <code>body</code> 上的观测者将首先被触发，然后再激活 
          <code>p</code> 上的观测者。而冒泡阶段，将首先激活 
          <code>p</code> 上的观测者，然后才是 
          <code>body</code> 上的观测者。
        </li>
				<li>要记住，对于
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code1">清单 1</a> 中 
          <code>onunload</code> 所用的 HTML 4.0 风格的语法，观测者被注册到冒泡阶段。
        </li>
				<li>无论使用冒泡阶段还是捕获阶段，默认动作总是在所有的传播完成后执行。停止事件传播本身不会禁止默认动作的执行。一个单独的 API 特性允许取消默认动作，无论传播过程中发生什么事。</li>
		</ul>
		<p>DOM Events 规范定义了从脚本中附加事件观测者的方法，如清单 3 所示。</p>
		<br />
		<a name="code3">
				<b>清单 3. 附加事件观测者</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />var el = document.getElementById('observer_element_id');<br />el.addEventListener("mouseover", highlight_func, true);<br />el.addEventListener("mouseout", normal_func, true);<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<code>addEventListener</code> 调用中的第一个参数是事件名，第二个参数是要执行的函数引用，第三个参数是 
        <code>true</code>（表示在捕获阶段）或者 
        <code>false</code>（表示在冒泡阶段）。DOM Events 规范定义了一些核心事件，以及停止事件传播和取消关联的默认动作的 API 方法。
      </p>
		<p>需要注意的是，这些 API 的不同浏览器的实现有很大的不同。具体地说，Internet Explorer 直到 6.0 版还不支持 
        <code>addEventListener</code>，但它使用了名为 
        <code>attachEvent</code> 的一个类似函数。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h4">
						<span class="atitle">从事件到 XML Events</span>
				</a>
		</p>
		<p>到目前为止，所有和事件有关的一切都和过程性脚本联系在一起。XML Events 规范在 DOM Level 2 Events 的基础上，增加了连接事件观测者的声明性方法。W3C XForms 规范（请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#resources">参考资料</a>）是率先定义兼容 XML Events 的元素库的标准之一，该元素库可以通过声明完成一般性的任务。清单 4 给出了 XForms 中的一个例子。（关于其中使用的完整名称空间声明，请参考
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code5">清单 5</a> 中的完整例子。）
      </p>
		<br />
		<a name="code4">
				<b>清单 4. 声明性事件处理程序</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;xf:trigger&gt;<br />  &lt;xf:label&gt;Reset the form&lt;/xf:label&gt;<br />  &lt;xf:reset ev:event="DOMActivate" model="mymodel" /&gt;<br />&lt;/xf:trigger&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>XML Events 被定义成一些属性。
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code4">清单 4</a> 中的 
        <code>ev:event</code> 属性规定了要监听的特定事件，处理程序是 
        <code>xf:reset</code> 元素，观测者被默认为父元素 
        <code>xf:trigger</code>。注意，该清单中根本没有脚本。
      </p>
		<p>XML Events 规范主要由可以放置在现有元素中的属性定义组成，还有一个 
        <code>listener</code> 元素用来容纳这些属性。每个属性都映射为 DOM Level 2 事件的一个特性。表 1 列出了所有的 XML Events 属性。
      </p>
		<p>
				<a name="table1">
						<span class="smalltitle">表 1. XML Events 属性</span>
				</a>
		</p>
		<p>
		</p>
		<table border="1" cellpadding="3" cellspacing="0" width="90%">
				<tbody>
						<tr valign="top">
								<td>
										<b>属性</b>
								</td>
								<td>
										<b>功能</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>event</code>
								</td>
								<td>如
              <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code4">清单 4</a> 所示，这个必需的属性用于命名触发监听者的事件
            </td>
						</tr>
						<tr valign="top">
								<td>
										<code>observer</code>
								</td>
								<td>该属性指向作为观测者的元素的惟一 ID</td>
						</tr>
						<tr valign="top">
								<td>
										<code>handler</code>
								</td>
								<td>该属性指向执行某种动作或处理的元素的 URI，该元素可能在不同的文档中</td>
						</tr>
						<tr valign="top">
								<td>
										<code>phase</code>
								</td>
								<td>
										<code>capture</code> 或 
              <code>default</code>，该属性规定使用捕获阶段
            </td>
						</tr>
						<tr valign="top">
								<td>
										<code>propagate</code>
								</td>
								<td>
										<code>stop</code> 或 
              <code>continue</code>（默认值），该属性规定事件是否继续传播
            </td>
						</tr>
						<tr valign="top">
								<td>
										<code>defaultAction</code>
								</td>
								<td>
										<code>cancel</code> 或 
              <code>perform</code>（默认值），该属性规定传播后是否激活默认动作
            </td>
						</tr>
						<tr valign="top">
								<td>
										<code>target</code>
								</td>
								<td>该属性要求监听者
              <i>仅</i> 对指向特定目标的事件作出响应，并且仅在特殊情况下使用
            </td>
						</tr>
						<tr valign="top">
								<td>
										<code>id</code>
								</td>
								<td>该属性为 
              <code>listener</code> 元素赋予文档中惟一的标识符
            </td>
						</tr>
				</tbody>
		</table>
		<p>
				<a name="h5">
						<span class="smalltitle">简便的默认值</span>
				</a>
		</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code4">清单 4</a> 说明了用最少的属性使用 XML Events 的便捷方法：XML Events 属性直接附加到处理程序元素上。如果省略 
        <code>ev:handler</code> 属性，拥有 XML Events 属性的元素就被看作是处理程序。观测者可以通过 
        <code>ev:observer</code> 属性指定，或者默认为父元素。在
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code4">清单 4</a> 中，观测者为 
        <code>xf:trigger</code>。
      </p>
		<p>另一种类型的默认允许将 XML Events 属性附加到观测者元素上，这种情况下没有 
        <code>ev:observer</code> 属性，但是出现了 
        <code>ev:handler</code> 属性。
      </p>
		<p>清单 5 重新创建了 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#code1">清单 1</a> 中的行为，显示了这两种默认技术，并使用了脚本和声明性动作。
      </p>
		<br />
		<a name="code5">
				<b>清单 5. 使用 XML Events 的两种方法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"<br />       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;<br />&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"<br />         xmlns:ev="http://www.w3.org/2001/xml-events"<br />         xmlns:xf="http://www.w3.org/2002/xforms"&gt;<br />  &lt;head&gt;<br />    &lt;title&gt;XML Events&lt;/title&gt;<br />    &lt;script type="text/javascript" ev:event="load" ev:observer="bod_id"&gt;<br />alert("hello");<br />    &lt;/script&gt;<br />    &lt;xf:message level="modal" id="hndl_id"&gt;goodbye&lt;/xf:message&gt;<br />  &lt;/head&gt;<br />  &lt;body id="bod_id" ev:event="unload" ev:handler="#hndl_id"&gt;<br />  &lt;/body&gt;<br />&lt;/html&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这里的 
        <code>script</code> 元素是一个处理程序，被附加到 
        <code>bod_id</code> 上的一个观测者（
        <code>body</code> 元素）。
        <code>xf:message</code> 元素本身什么也不做，但观测者元素（还是 
        <code>body</code>）又指向了它，注册了事件处理程序。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h6">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>脚
本显然在很多方面都很有用。尽管如此，它仍然难以通过脚本完成某些任务。XML Events
为通过声明将脚本附加到文档中提供了统一的语法，甚至能够定义不依赖于脚本解释器的行为。现在有越来越多的标记技术开始采用 XML
Events，其中包括 XForms、XHTML、SVG 等。在以后的文章中，我将详细探讨如何使用和实现 XML Events。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li> 您可以参阅本文在 developerWorks 全球站点上的 
          <a href="http://www.ibm.com/developerworks/xml/library/x-events/" target="_blank">英文原文</a>。
        <br /><br /></li>
				<li>请阅读 
          <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript 标准</a>，它正式定义了被广泛实现的一种脚本语言，该语言通常称为 JavaScript。
        <br /><br /></li>
				<li>要进一步了解事件流，请参阅 
          <a href="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/">The DOM Level 2 Events Specification</a>，它是 W3C 推荐的一种标准。
        <br /><br /></li>
				<li>然后看一看写得不错的 
          <a href="http://www.w3.org/TR/2003/REC-xml-events-20031014/">XML Events</a> 规范，它也是 W3C 推荐的标准。
        <br /><br /></li>
				<li>从不同的角度观察 XML Events，请阅读 W3C 站点上 Steven Pemberton 撰写的“
          <a href="http://www.w3.org/MarkUp/2004/xmlevents-for-html-authors">XML Events for HTML Authors</a>”。
        <br /><br /></li>
				<li>关于如何决定需要处理的事件和其他可访问性问题，请参考工作草案 
          <a href="http://www.w3.org/TR/2004/WD-WCAG20-20040730/">Web Content
  Accessibility Guidelines 2.0</a> 和链接的文档。
        <br /><br /></li>
				<li>关于基于 XML Events 的声明性动作的实际例子，请参阅 
          <a href="http://www.w3.org/TR/xforms/">W3C XForms 规范</a>的 
          <a href="http://www.w3.org/TR/xforms/slice10.html">XForms Actions</a> 一章。关于这方面的资料，还可以参阅 Micah Dubinko 最近撰写的 developerWorks 文章“
          <a href="http://www-128.ibm.com/developerWorks/cn/xml/x-xfvalid.shtml">XForms 验证程序揭密</a>”（2004 年 9 月）。
        <br /><br /></li>
				<li>在线阅读 Micah Dubinko 撰写 
          <a href="http://xformsinstitute.com/essentials"><i>XForms Essentials</i></a> （O'Reilly 出版）一书，其中有一章是关于事件的，也可以从 
          <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0596003692">developerWorks Developer Bookstore</a> 购买该书。
        <br /><br /></li>
				<li>如果希望对主要 XML 标准的相互关系有全面的了解，请参阅 Uche Ogbuji 在 developerWorks 上发表的 XML 标准调查（分为 4 部分）：

          <ul><li><a href="http://www-128.ibm.com/developerWorks/cn/xml/x-stand1/index.shtml">XML 标准概览：  第 1 部分</a>（2004 年 1 月）
            </li><li><a href="http://www-128.ibm.com/developerWorks/cn/xml/x-stand2/index.shtml">XML 标准概览：  第 2 部分</a>（2004 年 2 月）
            </li><li><a href="http://www-128.ibm.com/developerWorks/cn/xml/x-stand3/index.shtml">XML 标准概览：  第 3 部分</a>（2004 年 2 月）
            </li><li><a href="http://www-128.ibm.com/developerWorks/cn/xml/x-stand4/index.shtml">XML 标准概览：  第 4 部分</a>（2004 年 3 月）
            </li></ul><br /></li>
				<li>在 
          <a href="http://www-128.ibm.com/developerworks/cn/xml/">developerWorks XML 专区</a>可以找到更多 XML 资源。
        <br /><br /></li>
				<li>了解如何才能成为一名 
          <a href="http://www-1.ibm.com/certify/certs/adcdxmlrt.shtml">IBM 认证的 XML 及相关技术的开发人员</a>。
        <br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-events/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="Micah Dubinko 的照片" src="http://www.ibm.com/developerworks/i/p-dubinko.jpg" align="left" border="0" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Micah Dubinko 是 Brain Attic, L.L.C. 的顾问和缔造者之一，这是一家专门应对信息过载的软件供应商和咨询公司。他为 O'Reilly Media 撰写了 
        <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0596003692"><i>XForms Essentials</i></a> 一书，并参加了开发 XForms 1.0 的工作组。他在亚利桑那州菲尼克斯定居和工作，您可以通过 
        <a href="mailto:micah@brainattic.info?subject=Introduction%20to%20XML%20Events&amp;cc=dwxed@us.ibm.com">micah@brainattic.info</a> 与他联系。
      </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:28 <a href="http://www.blogjava.net/Vencent/articles/35988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 标准概览: 第 2 部分::XML 处理标准</title><link>http://www.blogjava.net/Vencent/articles/35985.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:27:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35985.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35985.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35985.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35985.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#author">Uche Ogbuji</a>, 首席顾问, Fourthought,Inc.<br /></p>
		<p>2004 年  2 月  01 日</p>
		<blockquote>XML
世界非常庞大，而且还在不断成长，存在大量不同的标准和技术，它们以复杂的方式互相影响。新手很难确定哪些是 XML
最重要的方面，用户也难以跟踪这个领域出现的新生事物和变化。在这一系列的文章中，Uche Ogbuji 提供了 XML
标准的指南，并为进一步的学习推荐了广泛的资料。Uche Ogbuji 继续关于 XML 的论述，这次主要讨论 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>XML
变得越来越强大，得到了迅速的发展。它已经证明自己是一种非常有价值的技术，但可能也是一种令人害怕的技术，如果考虑到挂在“XML”一词下面不断变化的
各个部分。在这一系列的文章中，我将简述我认为最重要的 XML 技术，讨论它们如何在 XML
世界中更大范围内的彼此融合。为了进一步评估和学习使用各种技术，我还推荐了一些教程和其他有用的参考资料。</p>
		<p>这里介绍的所有技术都是
        <b>标准</b>，尽管这个词本身就有点捉摸不定。标准有各种各样的形式，而且在同一个领域中常常有多种标准互相竞争。我按照实践的方法把标准定义为：被不同的供应商大量采用的或者有影响、独立于供应商的组织推荐的规范。
      </p>
		<p>在
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml" target="_new">第一篇文章</a>中，我主要讨论了核心 XML 技术。（关于各种标准开发团体和规范分类的概述，请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml#sidebar1" target="_new">文章的侧栏</a>。）本文中我将讨论和开发人员处理 XML 有关的标准。下一篇文章中将介绍选择的一些最重要的 XML 应用（即词汇表）。
      </p>
		<p>
				<a name="IDATMKPB">
						<span class="atitle">XSLT</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xslt">Extensible  Stylesheet
Language Transformations (XSLT) 1.0</a>
				</b>[W3C
推荐标准]是一种转换语言，描述从输入 XML 文档到输出树的转换。比如，输出树可以是 HTML 文档的形式也可以是另一种 XML
格式。因此，XSLT 可以作为把 XML 呈现为遗留浏览器显示格式的语言，也可以保持格式不变作为对 XML
文件操作的语言。转换本身使用一种专门的词汇表定义为 XML 文档。使用XPath（ <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml#xpath" target="_new">前文</a>
已述）访问原文档和生成表达处理。专门的指令建立处理规则（XSLT 是一种声明性语言）并控制输出树的创建。
XSLT 1.0 是一种非常成功的语言，涵盖了多数常用的 XML 处理任务。如果熟悉 XML，学习 XSLT
的基础并不难，但精通这门语言还是需要很大的努力。它有一种设计很好的扩展机制。它的声明性处理模型使代码很容易维护和重用。把 XML
文档链接到它的 XSLT 样式表文档的标准方式在 <b><a href="http://www.w3.org/TR/xml-stylesheet/">Associating Style Sheets with XML documents, Version 1.0</a></b>[W3C 推荐标准]中定义。XSLT 规范被
        <a href="http://www.w3.org/Style/XSL/translations.html">翻译</a>成了各种不同的语言。
      </p>
		<p>如前所述，XSLT 有一种很好的扩展机制，允许您使用自己选择的语言定义另外的功能。但更好的是，您甚至不必去编写扩展，因为别人已经替您做了。
        <b><a href="http://www.exslt.org/">EXSLT</a></b>[社区规范]是这类扩展的一个标准集，采用了隐藏实现的定义方式。EXSLT 试图囊括通常需要的多数扩展，比如日期处理、正则表达式和数学操作。许多 XSLT 实现都实现了一个或多个 EXSLT 模块。
      </p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xslt20/">XSLT 2.0</a>
				</b>[开发中]根据收集的 XSLT 1.0 使用经验提供了一些重要的改进，但缺点是对 XPath 2.0 的密切依赖，我认为后者存在根本上的缺陷（请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml" target="_new">第 1 部分</a>）。

      </p>
		<p>
				<a name="IDAAOKPB">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>W3Schools 提供了一个简要的
          <a href="http://www.w3schools.com/xsl/">XSLT 教程</a>。
        </li>
				<li>ZVON 提供了更深入的
          <a href="http://www.zvon.org/xxl/XSLTutorial/Books/Book1/">XSLT 教程</a>。
        </li>
				<li>IBM
          <i>developerWorks</i> 提供了几种 XSLT 教程，包括：

          <ul><li>“
              <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/D1681EA80FC2799EC8256D78000437C0?OpenDocument">用 XSLT 创建多用途 Web 内容</a>” （2003 年 3 月）
            </li><li>“
              <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/82376AC83B71ADE648256AD20009A489?OpenDocument">转化 XML 文档</a>” （2000 年 5 月）
            </li><li>“
              <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/2DC9F60C0DC5254A48256B45001F69E9?OpenDocument">用 4Suite 进行 Python 和 XML 开发,第二部分:4XPath和4XSLT</a>”（2001 年 10 月），其中包括 XSLT 的简要介绍
            </li></ul></li>
				<li>如果准备使用 EXSLT，请参阅“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-exslt/index.shtml">EXSLT 实例</a>”（
          <i>developerWorks</i>，2003 年 2 月）。
        </li>
		</ul>
		<p>
				<a name="IDATPKPB">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 提供了一个
          <a href="http://www.zvon.org/xxl/XSLTreference/Output/index.html">XSLT Reference</a>。
        </li>
				<li>Dave Pawson 的
          <a href="http://www.dpawson.co.uk/xsl/xslfaq.html">XSL FAQ</a>谈到了 XSLT 和 XPath 以及 XSL-FO（本系列文章后面将述及）。
        </li>
				<li>TopXML 分类提供了
          <a href="http://www.topxml.com/xsltstylesheets/default.asp">100 多个 XSLT 样式表的例子</a>。
        </li>
				<li>Jeni Tennison 以其对 XSLT 奥秘清晰而深刻的阐述而知名，她的
          <a href="http://www.jenitennison.com/xslt/">XSLT 页面</a>是常见 XSLT 问题非常棒的参考。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAXIZAD">
						<span class="atitle">SAX</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.saxproject.org/">Simple API for XML (SAX)</a>
				</b>[社区规范]是一种事件驱动的 API。XML 标记的不同部分（如起始和结束标签、文本、实体）触发特殊的事件，开发人员为这些事件注册处理程序代码。然后，解析器根据输入的 XML 发出事件流，处理程序代码依次处理这些事件。
      </p>
		<p>SAX 的创立基本上是一个马拉松式的过程，从 1997 年后期由
        <a href="http://www.xml.org/xml/xmldev.shtml">XML-DEV 邮件列表</a>
发起，长期以来这个邮件列表一直是 XML 专家的主要据点。David Megginson 领导了这个讨论组，造就了最成功的 XML
研究项目之一，没有任何大公司或标准团体的资助。在 SAX 之前，每种解析器都通过自己私有的 API 在 XML
结构与处理程序代码之间通信，SAX 提供了重要的统一性。通常提供 SAX 驱动程序的解析器都把底层的解析器事件转化成 SAX
标准事件，以支持代码的移植。SAX 最初的想法是用 Java 语言开发，但已经普及到多种语言和环境，尽管有时候它的以 Java
为中心的特点增加了移植的复杂性。SAX 目前处在第二代，包括 XML 名称空间处理和相对于文档结构可以选择的某些事件报告。 </p>
		<p>在主流语言中，基于事件的接口通常使用
        <b>回调</b>函数实现，这是一种在 GUI 之类的编程中常见的方式。在面向对象语言中，回调函数通常是对象的注册方法，使用多态匹配方法名和处理程序代码，并在两次回调之间通过封装在处理程序中管理状态。基于事件编程的整个模型被称为
        <b>推式</b>模型，背着多数程序员都难以掌握的名声。但是，多数被认为容易编程的模型都需要对文档进行随机访问，从而造成效率低下，因此 SAX 享有处理 XML 最有效的标准方式的美誉，如果不是最容易的方式的话。
      </p>
		<p>
				<a name="IDAQJZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>请参阅 Nicholas Chase 所写的
          <i>developerWorks</i>教程，“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/CA45E09F1E2EF41E48256B1B000C6C7B?OpenDocument">理解 SAX</a>”（2003 年 7 月）。
        </li>
				<li>Sun 为 Java 技术用户提供了一个
          <a href="http://java.sun.com/xml/jaxp/dist/1.0.1/docs/tutorial/sax/index.html">SAX 教程</a>。
        </li>
				<li>C++ 开发人员应该看一看 Martin Naughton 所写的“
          <a href="http://www.vbxml.com/xml/articles/vbxmlsax.asp">The Joy of SAX</a>”。
        </li>
				<li>我的文章“
          <a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/20259.htm">Taking
Applications to the Next Level with XML, Part 3: The Toolbox of XML APIs</a>” 涉及到了 SAX 和 DOM（参见后述）。
        </li>
				<li>Perl 程序员应该看一看“
          <a href="http://www.devshed.com/c/a/Perl/Using-Perl-with-XML-part-1/">Using Perl with XML (part 1)</a>”，其中涉及到了 SAX。
        </li>
		</ul>
		<p>
				<a name="IDAYKZAD">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>XML.org 的
          <a href="http://www.xml.org/xml/resources_focus_sax.shtml">SAX 专栏</a>提供了很有用的资源链接。
        </li>
		</ul>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidelang">
																				<b>XML 的编程语言</b>
																		</a>
																		<br />
																		<p>从一开始，XML 就受到了程序员的广泛关注。这里对使用各种语言处理 XML 的程序员列出了一些有用的资源：</p>
																		<p>
																				<b>Java 技术：</b>
																				<a href="http://www.alphaworks.ibm.com/xml">IBM
            <i>alphaworks</i>XML 页面
          </a>；
          <a href="http://xml.apache.org/">Apache XML 页面</a>；
          <a href="http://java.sun.com/xml/">Sun 的 Java 技术和 XML 社区</a></p>
																		<p>
																				<b>C/C++：</b>“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-ctlbx/index.shtml">C/C++ 开发人员：充实您的 XML 工具箱</a>” （
          <i>developerWorks</i>，2001 年 9 月）
        </p>
																		<p>
																				<b>Python:
</b>
																				<a href="http://www.python.org/sigs/xml-sig/">Special Interest Group for XML Processing in Python</a>； XML.com 上的“
          <a href="http://www.xml.com/pub/q/pyxml">Python &amp; XML</a>”专栏； “
          <a href="http://www.xml.com/pub/a/2003/09/10/py.html">The State of the Python-XML Art, 2003</a>”；“
          <a href="http://uche.ogbuji.net/tech/akara/nodes/2003-01-01/pyxml-akara">Uche Ogbuji 关于在 Python 中处理 XML 的 Akara 网站</a>”
        </p>
																		<p>
																				<b>Perl:</b>
“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/perl-xml-toolkit/index.shtml">Perl 开发人员：充实您的 XML 工具箱</a>” (
          <i>developerWorks</i>，2001 年 6 月）；
          <a href="http://perl-xml.sourceforge.net/">Perl-XML Project</a>；XML.com 上的“
          <a href="http://www.xml.com/pub/q/perlxml">Perl &amp; XML</a>”；
          <a href="http://www.xmlperl.com/">XMLperl.com</a></p>
																		<p>
																				<b>其他：</b>
																				<a href="http://phpxmlclasses.sourceforge.net/">
																						<b>PHP</b>XML Classes
          </a>；
          <a href="http://www.rubyxml.com/">&lt;
            <b>ruby</b>XML/&gt;
          </a>；
          <a href="http://okmij.org/ftp/Scheme/xml.html">XML 与
            <b>Scheme</b></a></p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDA5NZAD">
						<span class="atitle">DOM</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/DOM/">Document Object Model (DOM)</a>
				</b>[W3C
推荐标准]是一种 XML 文档对象模型，可用于直接访问 XML 文档的各个部分。在 DOM 中，文档被模型化为一棵树，其中每个 XML
语法成分（如元素和文本内容）都用一个节点表示。DOM 是一种
API，允许您在这种树中导航，从父节点移动到子节点或者在兄弟节点之间移动，并利用特定节点类型的特性（比如，元素可以有属性，而文本节点有文本数
据）。DOM 被设计成语言中立的。使用了 Object Management Group（对象管理组，OMG）的 <b><a href="http://www.omg.org/gettingstarted/omg_idl.htm">CORBA Interface Definition Language （接口定义语言，IDL）</a></b>[ISO 国际标准，编号 14750]表示 DOM 节点和支持接口。
      </p>
		<p>DOM
作为一种对象模型，最初实际上是用于在 Web 浏览器中标准化 HTML 和 XML 对象的脚本操作。作为独立的编程 API
使用时，有时候这种转换非常笨拙。DOM 的演进经过了几个级别，每个版本都在上一级别的基础上增加了新的功能。Level 1
包括了基本的功能，Level 2 增加了对名称空间的支持、一个 UI 事件模型、迭代器等等。Level 3 增加了用于从 XML
文档文件中加载和保存的 API，集成了 XPath，增加了对验证的支持等等。</p>
		<p>DOM 一般比 SAX
更容易掌握，因为它没有涉及到回调和复杂的状态管理，但是 DOM 实现通常在内存中保存所有的 XML
节点，对于较大的文档效率可能非常低。尽管许多语言都有 DOM 实现，DOM 还是努力保持语言的中立性。特定语言的拥护者常常抱怨 DOM
难以使用，不能利用任何语言的特长。结果涌现了许多针对特定语言的树处理 API。</p>
		<p>
				<a name="IDATOZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>请阅读 Nicholas Chase 所写的
          <i>developerWorks</i>教程“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/386674F65A47844C48256BD10023D453?OpenDocument">理解 DOM</a>”（2003 年 7 月）。
        </li>
				<li>W3Schools 提供的
          <a href="http://www.w3schools.com/dom/default.asp">教程</a>主要讨论将 DOM Level 1 用于 HTML 以及 XML 在浏览器 JavaScript 脚本中的应用。
        </li>
				<li>Perl 程序员应该阅读“
          <a href="http://www.devshed.com/c/a/Perl/Using-Perl-with-XML-part-1/">Using Perl with XML (part 1)</a>”，这篇教程讨论了 DOM。
        </li>
				<li>Python 程序员应该看一看
          <a href="http://www.python.org/doc/current/lib/module-xml.dom.html">标准 Python Library Reference 上的 DOM 页</a>。
        </li>
		</ul>
		<p>
				<a name="IDAVPZAD">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 提供了
          <a href="http://zvon.org/xxl/DOM1reference/Output/index.html">DOM Level 1</a>和
          <a href="http://zvon.org/xxl/DOM2reference/DOM2/Output/index.html">DOM Level 2</a>很好的参考指南，有大量的 JavaScript 例子。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAKQZAD">
						<span class="atitle">XAPI</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.xmldb.org/xapi/index.html">XML Database API (XAPI)</a>
				</b>[开
发中]是一种用于 XML 数据库的独立于供应商和语言（尽管是面向对象的）的 API。XML:DB 是致力于 XML
数据库管理工具的开发人员兴趣小组。XAPI 涵盖了 XML 数据库中数据的存储、检索、修改和查询，以及对事务管理的支持。它类似于 ODBC 和
JDBC。和 DOM 一样，XAPI 也指定使用 OMG IDL，并按照功能级别组织。Level 0 是基本的 API，Level 1 增加了
XPath 支持（XPathQueryService）。XAPI 在原生 XML 数据库管理工具中得到了广泛的实现，尤其是开源工具如
Apache XIndice 和 SleepyCat Berkeley XML DB。尽管如此，除了 XML:DB 规范本身外，这方面的
Web 资源还很少。 <a href="http://www.xmldb.org/xapi/UseCases.html">API Use Cases</a>提供了一些在 Java 语言中使用这种 API 的很粗略的例子。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDA1QZAD">
						<span class="atitle">XUpdate</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.xmldb.org/xupdate/index.html">XUpdate</a>
				</b>[开
发中]定义了修改 XML 文档中的数据的更新工具。尽管 XUpdate 是由 XML:DB 小组定义的，但 XUpdate
被设计成能够处理常规的 XML 文档和存储在数据库中的 XML，甚至虚拟的 XML 数据模型。XUpdate 是一种类似 XSLT 的 XML
词汇表，但是比 XSLT 简单得多，总体上是一种很容易理解的词汇表。和 XSLT 相似，它也使用 XPath
访问修改的文档，并使用专门的元素定义输出操作。XUpdate 也有广泛的实现，特别是在开源工具中，如 XML DBMS 和 XML
比较和修补工具。 <a href="http://www.xmldatabases.org/projects/XUpdate-UseCases/">XUpdate Use Cases</a>草案也是很好的 XUpdate 入门参考。
      </p>
		<p>
				<a name="IDAMRZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Arun Gaikwad 的“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xindice/index.shtml">Xindice 简介</a>”在最后谈到了 XUpdate（
          <i>developerWorks</i>，2002 年 9 月）
        </li>
				<li>“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/DDCF775A3623394FC8256CB8001E909E?OpenDocument">4Suite 进行 Python 和 XML 开发,第四部分:合成和更新</a>”中有一节介绍 XUpdate（
          <i>developerWorks</i>，2002 年 10 月）。
        </li>
				<li>X-Hive 的
          <a href="http://support.x-hive.com/xupdate/input">在线 XUpdate 演示</a>是通过实验学习这种语言的一种好方法。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAKSZAD">
						<span class="atitle">XQuery</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xquery/">XQuery 1.0: An XML Query Language</a>
				</b>[开
发中]是一种用于查询 XML 数据源——文档和数据库——的规范。XQuery 是一种非常复杂的编程语言，组成了 XPath
的一个超集。XQuery 是与 XPath 2.0 一起开发的，同样因为其复杂性而备受争议，其实许多争论是不必要的。XQuery
1.0/XPath 2.0 系统包括令人生畏的一大批规范定义，包括语义、语法以及核心函数库： </p>
		<ul>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xmlquery-use-cases">XML Query Use Cases</a>
						</b>[开发中]通过带有 XQuery 例子的预想应用场景把握着 XQuery 的发展方向。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/query-datamodel/">XQuery 1.0 和 XPath 2.0 Data Model</a>
						</b>[开发中]精确定义了 XSLT 2.0 或 XQuery 处理程序可以包含的信息，以及 XSLT 2.0、XQuery 和 XPath 2.0 表达式中所有允许的值。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/query-semantics/">XQuery 1.0 和 XPath 2.0 Formal Semantics</a>
						</b>[开发中]在其数据模型的基础上，给出了 XPath 2.0 和 XQuery 1.0 规范中每种表达式精确的、形式化的含义。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xpath20">XPath 2.0</a>
						</b>[开发中]定义了 XPath 2.0 的核心语法。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xquery-operators">XQuery 1.0 和 XPath 2.0 Functions and Operators</a>
						</b>[开发中]定义了表达式中常用的处理任务。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xquery">XQuery 1.0</a>
						</b>[开发中]定义了 XQuery 1.0 的核心语法。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xqueryx/">XML Syntax for XQuery 1.0 (XQueryX)</a>
						</b>[开发中]提供了一种可选的 XQuery 的 XML 表示。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xslt-xquery-serialization/">XSLT 2.0 和 XQuery 1.0 Serialization</a>
						</b>[开发中]定义了数据模型中的值在 XML、HTML 和文本中是什么样子，如何在处理程序输出中替换 XSLT 中的节。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/xslt20">XSLT 2.0</a>
						</b>[开发中]不是 XQuery 家族的直接成员，但是和 XPath 2.0 与 XQuery 1.0 密切相关，并且完全依赖于前者。
        </li>
		</ul>
		<p>
				<a name="IDAOUZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Howard Katz 撰写的“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery/index.shtml">XQuery 简介</a>”介绍了 XQuery，并提供了一些例子，根据最近的工作草案作了更新（
          <i>developerWorks</i>，2003 年 9 月）。
        </li>
				<li>Nicholas Chase 的“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/5FE0E9CBD1F8AD36C8256C9500302B0F?OpenDocument">使用XML Query 处理XML</a>”讲授 XQuery 并考察了 XPath 2.0 中的变化。它讨论的是较早版本的工作草案，但是因为此后的变化很小，我还是推荐这个教程（
          <i>developerWorks</i>，2002 年 9 月）。
        </li>
				<li>Per Bothner 撰写的文章“
          <a href="http://www.xml.com/pub/a/2002/10/16/xquery.html">What
is XQuery?</a>”，最近的
          <a href="http://www.xml.com/pub/a/2003/09/10/xquery.html">修订</a>论及最新的草案。
        </li>
		</ul>
		<p>
				<a name="IDAQVZAD">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>
						<a href="http://www.xquery.com/">xquery.com</a>是一个很好的 XQuery 资源集散站，还包括一个
          <b>Wiki</b>，这是一种协作式的资源索引和讨论网页。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDA5VZAD">
						<span class="atitle">SQL/XML</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=35341&amp;ICS1=35">SQL/XML</a>
				</b>[ISO
国际标准 ISO/IEC 9075-14:2003]是 SQL 标准的一个新的分支，包括大量和 XML 有关的对 SQL
的扩展。SQL/XML 最初是由“SQLX Informal Group of Companies（非正式企业组织）”开发的，其中包括
IBM，后来交给了美国国家标准局（ANSI——维护 SQL 的标准组织）中的委员会。SQL/XML 所涉及到的范围包括（引自 Andrew
Eisenberg 与 Jim Melton）： </p>
		<ul>
				<li>SQL 数据（具体而言就是行和表，以及视图和查询结果）以 XML 形式表示（或者相反）的规范。</li>
				<li>与 SQL 架构和 XML 架构之间的映射有关的规范，可能包括实现任何已有 XML 架构和 SQL 架构之间的映射。</li>
				<li>SQL 架构在 XML 中表示的规范。</li>
				<li>SQL 动作（插入、更新、删除）表示的规范。</li>
				<li>和 SQL 一起使用时 XML 的消息规范。</li>
		</ul>
		<p>SQL/XML 与 XQuery 很少交叉，两个标准中同时涉及的部分一般能一起工作。</p>
		<p>
				<a name="IDATWZAD">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>Andrew Eisenberg 和 Jim Melton 撰写的“
          <a href="http://www.acm.org/sigmod/record/issues/0109/standards.pdf">SQL/XML and the SQLX Informal Group of Companies [PDF]</a>”列举了 SQL/XML 的成就。
        </li>
				<li>J. E. Funderburk、S. Malaika 和 B. Reinwald 撰写的“
          <a href="http://www.research.ibm.com/journal/sj/414/reinwald.pdf">XML programming with SQL/XML and XQuery [PDF]</a>”（
          <i>IBM Systems Journal</i>,Vol. 41, No. 4, 2002）彻底分析了所有这些 XML 和 DBMS 技术的交叉之处。
        </li>
				<li>SQL/XML 草案现在是正式的，只有向 ISO（或者所在国家的相关会员）付费后才能得到一个副本，但是如果希望很好地理解该标准，可以使用
          <a href="http://xml.coverpages.org/SQLX-5wd-14-xml-2002-08.pdf">2003 年 3 月的一个较早版本 [PDF]</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAQXZAD">
						<span class="atitle">CSS</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/Style/CSS/">Cascading Style Sheets (CSS)</a>
				</b> [W3C 推荐标准]是一种将表示样式应用于标记的系统。最知名的是在样式化 HTML Web 页中的应用，但尤其是从 CSS Level 2 发布以来，它也非常适合在 Web 或者其他媒介上表示 XML 文档。把 XML 文档映射到输出结构通过使用 
        <code>display</code> 属性完成。XML 文档链接到它的 CSS 样式表文档的标准方式在 
        <b><a href="http://www.w3.org/TR/xml-stylesheet/">Associating Style Sheets with XML documents Version 1.0</a></b>[W3C 推荐规范]中定义。
      </p>
		<p>
				<a name="IDAJYZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Simon St. Laurent 撰写的“
          <a href="http://www.xml.com/pub/a/2000/03/29/tutorial/">On
Display: XML Web Pages with Mozilla</a>”是一篇较老的文章，但使用 Mozilla 浏览器（包括与
MSIE 5 的比较）的例子较好地说明了其中的基本原理。
        </li>
				<li>ZVON 的“
          <a href="http://www.zvon.org/xxl/CSS2Tutorial/General/htmlIntro.html">CSS
2 Tutorial</a>”讲解如何使用 CSS 2 显示 XML 文档。
        </li>
				<li>Dr. David Mertz 的
          <i>developerWorks</i>技巧文章，“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/tips/x-tipcss2/index.shtml">技巧： 使用 CSS2 显示 XML 文档</a>”，对详尽的例子作简要的说明（2001 年 12 月）。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAFZZAD">
						<span class="atitle">XForms</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/MarkUp/Forms/">XForms 1.0</a>
				</b>[W3C
推荐标准]，不要与名称相同的 XWindows GUI 库混淆，这是用于 XML 数据处理的 Web
表单规范，可通过不同的媒介用于不同的平台。XForms 希望把表单的用途和表示分开。它把表单做什么与表单看起来怎么样分离开。它是一种 XML
词汇表，可用于开发表单 UI 以操纵 XML 内容。XForms 最初是 XHTML
家族的一部分，但已经完全独立出来了。尽管其复杂程度超出了需要，但看来是一种能够把混乱的 Web 表单世界带入正轨的技术。 </p>
		<p>
				<a name="IDASZZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Micah Dubinko 写的“
          <a href="http://www.xml.com/pub/a/2001/09/05/xforms.html">What
Are XForms?</a>”对这种技术作了一般性的介绍。
        </li>
				<li>Joel Rivera 和 Len Taing 撰写的“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xforms/index.shtml">准备使用 XForms</a>”，通过几个详细的例子介绍了 XForms（
          <i>developerWorks</i>，2002 年 9 月）。
        </li>
				<li>Nicholas Chase 的“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/AC0870E97A197B8BC8256E12001C33B9?OpenDocument">理解 XForms</a>”更深入地分析了一系列的例子（
          <i>developerWorks</i>，2002 年 12 月）。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAQ0ZAD">
						<span class="atitle">SOAP</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/2000/xp/Group/">SOAP</a>
				</b>[W3C 推荐标准]（尽管使用大写，但已经成为正式的名词而不再是缩写词了）是一种协议，在使用底层 Internet 协议连接的系统之间使用 XML 通信。一些用户认为 SOAP 是
        <b>XML Web 服务</b>的
基础，这是一组技术的统称，用于管理和组织使用 XML 数据格式和 Internet 通信协议连接的系统之间交互的一组技术。SOAP
最初是在数量不多、临时拼凑的个人之间开发的，这些人来自各种不同的公司，其中包括 IBM。之所以能够得到迅速普及，是因为它提供了与早期对 XML
消息的研究成果相似的功能，并且有更牢固的体系结构基础和更多的商业支持。SOAP 的开发交给了 W3C，W3C 开发了 SOAP
1.2，在体系结构上作了许多改进，但是也对许多争议作了折衷。SOAP 定义了一种 XML 信封格式，可以包含伪 XML 载荷（SOAP
消息的实际有效载荷不能使用 XML 的所有功能，这是引起激烈争论的一个焦点）。 </p>
		<p>Web 服务不一定必须使用 SAOP，许多人鼓吹直接在 HTTP 上交换原始 XML 文档的观点，这是松散地聚在“
        <a href="http://internet.conveyor.com/RESTwiki/moin.cgi/FrontPage">REpresentational State Transfer (REST)</a>”
大旗下的人吹捧的一种方法。REST 本身是它的架构师之一，Roy Fielding，为一种 Web 体系结构方式所取的名字。REST 风格
Web 服务的鼓吹者抱怨 SOAP 太复杂、XML 有效载荷像是杂耍，而且没有充分利用 Web 的基本能力。在 SOAP
的提倡者中，最近的重点已经从 SOAP 的 RPC 源头转移到了所谓的 <i>实文档</i>方式的 SOAP。在 RPC 方式中，传输的数据使用专门的 XML 符合格式（称为 SOAP 编码）编组成离散的数据类型。在实文档方式中，XML 负荷由更自然的 XML 格式组成，通常更具有描述性，更便于人类阅读。
      </p>
		<p>
				<a name="IDAH1ZAD">
						<span class="smalltitle">SOAP 大厦</span>
				</a>
		</p>
		<p>建立在 SOAP 基础上的大批标准——许多已经超出了本文中所能讨论的范围。关于这些标准的信息有一些很好的资源：</p>
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/views/webservices/standards.jsp">IBM
            <i>developerWorks</i>上的 Web 服务标准列表
          </a>
				</li>
				<li>
						<a href="http://www.w3.org/2002/ws/">W3C Web Services Activity 主页</a>
				</li>
				<li>
						<a href="http://webservices.xml.com/">webservices.xml.com</a>
				</li>
		</ul>
		<p>至今仍然广泛使用的一种 SOAP 先驱是
        <b><a href="http://www.xmlrpc.com/spec">XML Remote Procedure Calls (XML-RPC)</a></b>[社
区规范]。XML-RPC 定义了使用 XML 编码通过 HTTP 通信的过程调用。之所以流行至今是因为它的简单性（整个规范打印出来不超过 10
页），而且现在的多数语言和许多应用程序框架，都有标准的或者容易应用的 XML-RPC
实现。它确实有一些很突出的不足，包括非常原始的数据类型化以及缺乏对字符编码的支持（对于使用 XML 而言，这真是一个令人吃惊的瑕疵） </p>
		<p>
				<a name="IDAF2ZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>W3C 有正式的
          <a href="http://www.w3.org/TR/2003/REC-soap12-part0-20030624/">SOAP 入门</a>，推荐它是因为它对 XML 传输格式的关注。
        </li>
				<li>Perl 程序员可以看看 Paul Kulchenko 的“
          <a href="http://www.perl.com/pub/a/2001/01/soap.html">Quick Start with SOAP</a>”，尽管这篇文章很老了，但它讨论的主要是开发人员所用的 API 而不是实际的传输格式，仍然很实用。我建议您最好特别熟悉 SOAP 的有线格式。
        </li>
				<li>Python 程序员可以看看 IBM
          <i>developerWorks</i>上的
          <a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-pyth/index.shtml">Python Web 服务开发人员专栏</a>。
        </li>
				<li>关于实文档风格的 SOAP 推荐以下资源。请参阅 James McCarthy 的文章“
          <a href="http://www.ibm.com/developerworks/webservices/library/ws-docstyle.html">Reap the benefits of document style Web services</a>”（
          <i>developerWorks</i>，2002 年 6 月）。
        </li>
				<li>Paul Prescod 的“
          <a href="http://webservices.xml.com/pub/a/ws/2002/02/06/rest.html">Second
Generation Web Services</a>” 和“
          <a href="http://webservices.xml.com/pub/a/ws/2002/02/20/rest.html?page=1">REST and the Real World</a>”，对 REST 的观点和动机作了很好地介绍。
        </li>
				<li>对 XML-RPC 感兴趣的 Perl 用户应该从“
          <a href="http://www.ibm.com/developerworks/webservices/library/ws-xpc1/">Using XML-RPC for Web services: Getting started with XML-RPC in Perl</a>”入手，然后参考“
          <a href="http://www.ibm.com/developerworks/webservices/library/ws-xpc2/">XML-RPC Middleware</a>”，作者都是 Joe Johnston（
          <i>developerWorks</i>，2001 年 3 月）。
        </li>
				<li>关注 XML-RPC 的 Python 用户可以阅读 Mike Olson 与 Uche Ogbuji 撰写的“
          <a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-pyth/part10/index.shtml">针对 Python 的 XML-RPC</a>”（
          <i>developerWorks</i>，2002 年 8 月）。
        </li>
				<li>Eric Kidd 的“
          <a href="http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html">XML-RPC
HOWTO</a>”讨论了如何在 Java 语言、C、C++、Perl、Ruby 和 NET 中使用这种协议。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAN4ZAD">
						<span class="atitle">WSDL</span>
				</a>
		</p>
		<p>根据正式的定义，
        <b><a href="http://www.w3.org/2002/ws/desc/">Web Services Description Language (WSDL) Version 1.2</a></b>[开
发中]是“一种描述网络服务的 XML
格式，它把网络服务描述为对消息的一组端点操作，消息可以包含面向文档的信息或者面向过程的信息。”它在一系列抽象层次上定义了 Web
服务中端到端通信的组件。WSDL 最初是作为 IBM 和 Microsoft 的合作项目发起的，但在 WSDL 1.2 的开发是已经交给了
W3C。WSDL 通常伴随着 SOAP 作为 Web 服务核心技术，但也可用于描述 SOAP 之外的其他协议。 </p>
		<p>
				<a name="IDA14ZAD">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>IBM
          <i>developerWorks</i>上的一篇文章讨论了旧版本的 WSDL，即 Bilal Siddiqui 撰写的“
          <a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-intwsdl/part1/index.shtml">使用 WSDL 部署 Web 服务</a>”（2001 年 11 月）。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAL5ZAD">
						<span class="atitle">后续内容</span>
				</a>
		</p>
		<p>本文综述了和应用程序开发有关的最重要的 XML 标准。下一篇文章中，我将分析最重要的通用 XML 词汇表。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的
          <a href="http://www.ibm.com/developerworks/library/x-stand2.html">英文原文</a>.
        <br /><br /></li>
				<li>阅读本系列关于 XML 标准的文章的
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml">第 1 部分</a>，主要讨论 Uche Ogbuji 认为是核心的 XML 技术（
          <i>developerWorks</i>，2004 年 1 月）。
          <br /><br /><br /><br /></li>
				<li>看看 IBM
          <i>developerWorks</i>上的
          <a href="http://www.ibm.com/developerworks/views/xml/standards.jsp">XML 标准列表</a>。
          <br /><br /><br /><br /></li>
				<li>如果希望就 XML 获得坚实的基础，请阅读
          <a href="http://www.ibiblio.org/xml/books/bible2/"><i>The XML Bible, 2nd Edition</i></a>，Elliotte Rusty Harold 著（John Wiley &amp; Sons, 2001），前提是您愿意买下这本书。
          <br /><br /><br /><br /></li>
				<li>访问开发 XML 标准的最重要组织的网站：

          <ul><li><a href="http://www.w3.org/">W3C（万维网联盟）</a></li><li><a href="http://www.oasis-open.org/">OASIS （结构化信息标准推进组织）</a></li><li>ISO（国际标准化组织），尤其是它的项目
              <a href="http://dsdl.org/">ISO/IEC 19757 - Document Schema Definition Languages （文档模式定义语言，DSDL）</a></li></ul><br /><br /></li>
				<li>Simon St. Laurent 所写的
          <a href="http://simonstl.com/articles/civilw3c.htm">Outsider's Guide to the W3C</a>是一个 FAQ，澄清了这个为您带来 HTML 和 XML 的组织的许多方面。
          <br /><br /><br /><br /></li>
				<li>Robin Cover 的
          <a href="http://xml.coverpages.org/">The Cover Pages</a>基本上涉及到了 XML 的每个方面，这是一个令人瞠目的、包罗万象的 XML 资源指南。
          <br /><br /><br /><br /></li>
				<li>访问
          <a href="http://xmlhack.com/">xmlhack</a>，XML 开发人员的新闻站点，Uche 帮助编辑。
          <br /><br /><br /><br /></li>
				<li>在
          <a href="http://www-128.ibm.com/developerworks/cn/xml/"><i>developerWorks</i>XML 专区
          </a>可以找到更多的 XML 资源，包括 Uche Ogbuji 的
          <a href="http://www-128.ibm.com/developerworks/cn/xml/rdf/index.shtml"><i>Thinking XML</i>专栏
          </a>。
          <br /><br /><br /><br /></li>
				<li>IBM 的
          <a href="http://www-3.ibm.com/software/data/db2/">DB2</a>数据库不仅提供了关系数据库存储，也包括和 XML 有关的工具，如
          <a href="http://www-3.ibm.com/software/data/db2/extenders/xmlext/index.html">DB2 XML Extender</a>提供了连接 XML 和关系系统的桥梁。要进一步了解 DB2，请访问
          <a href="http://www-128.ibm.com/developerworks/cn/dmdd/"><i>developerWorks</i>上的 DB2 专区
          </a>。
          <br /><br /><br /><br /></li>
				<li>了解如何才能成为一名
          <a href="http://www-128.ibm.com/developerworks/cn/xml/theme/x-cert.html">IBM 认证的 XML 及相关技术开发人员</a>。
          <br /><br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="Author photo" src="http://www-128.ibm.com/developerworks/cn/i/p-uche.jpg" align="left" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Uche Ogbuji 是
        <a href="http://fourthought.com/">Fourthought Inc.</a>的顾问和共同创始人，该公司是专为企业知识管理提供 XML 解决方案的软件供应商和咨询公司。 Fourthought 开发了
        <a href="http://4suite.org/">4Suite</a>，这是一个用于 XML、RDF 和知识管理应用程序的开放源代码平台。Ogbuji 先生是
        <a href="http://uche.ogbuji.net/tech/rdf/versa/">Versa</a>RDF 查询语言的首席开发人员。他是一位出生于尼日利亚的计算机工程师和作家，在美国科罗拉多的博耳德生活和工作。可以通过
        <a href="mailto:uche.ogbuji@fourthought.com">uche.ogbuji@fourthought.com</a>和 Ogbuji 先生联系。
      </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:27 <a href="http://www.blogjava.net/Vencent/articles/35985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 标准概览: 第 1 部分::核心标准——XML 大世界的基石</title><link>http://www.blogjava.net/Vencent/articles/35987.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:27:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35987.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35987.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35987.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35987.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35987.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#author">Uche Ogbuji</a>, 首席顾问, Fourthought, Inc.<br /></p>
		<p>2004 年  2 月  01 日</p>
		<blockquote>XML
世界非常庞大，而且还在不断成长，存在大量不同的标准和技术，它们以复杂的方式互相影响。新手很难确定哪些是 XML
最重要的方面，用户也难以跟踪这个领域出现的新生事物和变化。在这一系列的文章中，Uche Ogbuji 提供了 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>XML 变得越来越强大，得到了迅速的发展。它已经证明自己是一种非常有价值的技术，但可能也是一种令人害怕的技术，如果考虑到挂在“XML”一词下面不断变化的各个部分。在这一系列的文章中，我将简述我认为最重要的
XML 技术，讨论它们如何在 XML 世界中更大范围内的彼此融合。为了进一步评估和学习使用各种技术，我还推荐了一些教程和其他有用的参考资料。</p>
		<p>这里介绍的所有技术都是
        <b>标准</b>，尽管这个词本身就有点捉摸不定。标准有各种各样的形式，而且在同一个领域中常常有多种标准互相竞争。我按照实践的方法把标准定义为：被不同的供应商大量采用的或者有影响的、独立于供应商的组织推荐的规范。
      </p>
		<p>在第一篇文章中，我主要讨论我认为是核心的 XML 技术。这些技术构成了 XML 文档中所表达的内容的基础。在以后的文章中，我将讨论和开发人员处理
XML 有关的标准，和选择一些最重要的 XML 应用（即词汇表）。</p>
		<p>
				<a name="IDADEMHE">
						<span class="atitle">XML</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/REC-xml">XML
1.0 （第 2 版）</a>
				</b>[W3C 推荐标准]当然是衍生出 XML 技术大树的主干。它在
        <b><a href="http://www.unicode.org/">Unicode</a></b>
[Unicode Consortium 技术报告和 ISO 标准]的基础上定义了文本格式的严格规则，以及 
        <b>Document
Type Definition （文档类型定义，DTD）</b>验证语言。该规范的当前版本（第 2 版）包含了规范的历次修订。它被
        <a href="http://www.w3.org/XML/Core/Translations">翻译</a>
成多种语言，尽管英语版本是唯一的
        <b>规范</b>版本，就是说只有这个版本被认为具有标准的效力。
      </p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xml11/">XML
1.1</a>
				</b>[开发中]是改变了
        <i>结构良好的</i>
XML 文档的定义的第一个修订版。主要的变化是修订了 XML 规范中对字符的处理，使其更自然地适应 Unicode 规范的变化，并通过引用

        <b><a href="http://www.w3.org/TR/charmod/">Character
Model for the World Wide Web（万维网字符模型）1.0</a></b> [开发中]，提供了不同 Unicode 版本字符的规范化。XML
1.1 还增加了行结束字符列表，新增加的 NEL 用于在 IBM 大型机系统中表示行结束（EOL）。这种变化存在争议，有人认为对大型机用户带来的有限好处不值得做这种基础性的改变。还有一些其他的争论，因为一些评论者发现所有的修改都太稳妥了，在
XML 版本变换中不会造成各种可能的互操作性问题。
      </p>
		<p>XML 是基于
        <b>Standard Generalized Markup Language（标准通用标记语言，SGML）</b>的，后者由 ISO 8879:1986 [ISO 标准]定义。它在很大程度上简化了 SGML，包括一些调整使其更适合于 Web 环境。
      </p>
		<p>
				<a name="IDAOFMHE">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>以 Doug Tidwell 的文章“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/098067B621EEBFBFC8256C80002A2DF6?OpenDocument">XML 入门</a>” （
          <i>developerWorks</i>, 2002 年 8 月）作为起点。
        </li>
				<li>ZVON 的
          <a href="http://www.zvon.org/xxl/XML%E6%95%99%E7%A8%8B/General/book.html">XML 教程</a>和
          <a href="http://www.zvon.org/xxl/DTD%E6%95%99%E7%A8%8B/General/book.html">DTD 教程</a>有多种语言的版本。
        </li>
				<li>Ken Sall 所著的
          <i>XML Family of Specifications: A Practical Guide</i>中的
          <a href="http://wdvl.internet.com/Authoring/Languages/XML/XMLFamily/XMLSyntax/">Excerpts</a>一章提供了简单的介绍。
        </li>
				<li>W3Schools 和 W3C 没有任何从属关系，提供了包罗万象的
          <a href="http://www.w3schools.com/xml/default.asp">XML 教程</a>。
        </li>
				<li>Mike Brown 的“
          <a href="http://skew.org/xml/%E6%95%99%E7%A8%8B/">skew.org
XML 教程</a>”是对 XML 的重新介绍，强调了编码的问题，突出了其他文献中经常掩盖的一些主题。
        </li>
		</ul>
		<p>
				<a name="IDA1GMHE">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>在“
          <a href="http://www.xml.com/axml/testaxml.htm">The
Annotated XML Specification</a>”中，Tim Bray 对 XML 1.0 的文本以脚注的形式作了很好的解释和说明。
        </li>
				<li>“
          <a href="http://www.ucc.ie:8080/cocoon/xmlfaq">The
XML FAQ</a>” 是由 Peter Flynn 编辑的。
        </li>
				<li>Markus Kuhn 的“
          <a href="http://www.cl.cam.ac.uk/%7Emgk25/unicode.html">UTF-8
and Unicode FAQ for Unix/Linux</a>”实际上对任何平台上的用户都是很好的参考。
          <b>UTF-8</b>
是一种很常用的 Unicode 编码。
        </li>
				<li>“
          <a href="http://www.unicode.org/reports/tr20/">Unicode
in XML and other Markup Languages</a>” 对于需要非常严格地讨论 Unicode 与 XML 的交集的人（可能的实现者）而言，是一份正式的技术报告。
        </li>
				<li>IBM 的“
          <a href="http://oss.software.ibm.com/icu/userguide/unicodeBasics.html">Introduction
to Unicode</a>”站点深入探讨了 Unicode 的基础。
        </li>
				<li>
						<a href="http://www.i18ngurus.com/index.html">Open Internationalization Resources Directory</a>对于管理国际化数据的方方面面都是很好的参考，国际化也是 XML 建立在 Unicode 基础上的核心目标。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAMIFAF">
						<span class="atitle">Catalogs</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.oasis-open.org/committees/entity/spec-2001-08-06.html">XML
Catalogs</a>
				</b>[OASIS 委员会规范]定义了一种格式，指导 XML 处理程序把 XML
        <b>实体</b>标识符解析成实际的文档。比如，给定一个
DTD 的系统标识符和公共标识符，
        <b>实体目录</b>可用于规定
XML 处理程序从哪里加载 DTD。
        <b>系统标识符</b>通常使用

        <b>Uniform Resource
Identifiers（统一资源标识符，URI）</b>给出，后者受
        <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC
2396: Uniform Resource Identifiers</a> [IETF RFC]的控制。URI 仅仅是对 Web 浏览器或者类似工具中所用的一般
URL 的扩展。所有的 URL 都是 URI，但是 URI 还包括 URN，URN 由 
        <a href="http://www.ietf.org/rfc/rfc2141.txt">RFC
2141: Uniform Resource Names</a> [IETF RFC]控制，这是使用名称而不是位置标志 Web 资源的一种方式（请参阅“

        <a href="http://www.ietf.org/html.charters/urn-charter.html">The
URN Charter</a>”）。
        <b>公共标志符</b>通常用
SGML 中定义的 Formal Public Identifiers（正式公共标志符，FPI）指定。目录可能在这样的情况下使用：所用的计算机不能访问
URL 所指定的网络资源，或者企业希望用当地版本代替外部资源。
      </p>
		<p>XML 目录本身是一个 XML 文档，不过是一种用于 SGML 的较老的格式，而 XML 使用更简单文本定义了一种目录格式：
        <b><a href="http://www.oasis-open.org/specs/tr9401.html">Entity
Management, OASIS Technical Resolution 9401:1997</a></b> [OASIS 标准]。这种格式经常被称为

        <b>OASIS Open Catalog</b>。
      </p>
		<p>
				<a name="IDAYJFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<p>目录处理通常作为 XML 解析器完整的一部分提供，但是有一些介绍性的资料专门讨论使用目录解析实体：</p>
		<ul>
				<li>Norman Walsh 在其文章“
          <a href="http://wwws.sun.com/software/xml/developers/resolver/article/">XML
Entity and URI Resolvers</a>”中同时讨论了两种目录。
        </li>
				<li>Bob Stayton 的电子书
          <i><a href="http://www.sagehill.net/docbookxsl/">DocBook XSL: The Complete Guide</a></i>的
          <a href="http://www.sagehill.net/docbookxsl/Catalogs.html">第 4 章 XML 目录</a>中只讨论了 XML 目录。
        </li>
		</ul>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidebar1">
																				<b>多种风格的标准</b>
																		</a>
																		<br />
																		<p>
有几种组织和非正式的团体参与了为 XML 用户指定标准的过程。在
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#resources">参考资料</a>中提供了大多数链接，但这里我要解释一下在本文中用于修饰标准的一些词汇
        </p>
																		<p>
																				<b>
																						<a href="http://www.w3.org/">W3C</a>
																				</b>正式发布的
          <b>推荐标准</b>，在技术上讲仅仅是关于进一步标准化的建议，但是由于该组织自身的权威性往往成为
          <i>事实上的</i>标准。首先是
          <b>工作草案</b>，然后成为
          <b>候选推荐标准</b>（提出来供开发人员通过实现进行测试的最终形式），接下来是
          <b>提议的推荐标准</b>（准备进行推荐标准的待定 W3C 投票），最后规范进入推荐标准状态。
        </p>
																		<p>
																				<b>
																						<a href="http://www.iso.ch/iso/en/ISOOnline.frontpage">国际标准化组织（ISO）</a>
																				</b>可能是世界上最权威的标准体。它的许多标准在相关行业中都具有法律效力。
        </p>
																		<p>
																				<b>
																						<a href="http://www.oasis-open.org/home/index.php">结构化信息标准推进组织（OASIS）</a>
																				</b>大约从 SGML 的时代开始在结构上就发生了变化，但工作的成果是类似的。过去 OASIS 所称的
          <b>Technical Resolutions（技术解决方案）</b>现在变成了
          <b>Committee Specifications（委员会规范）</b>，目的和 W3C 推荐标准是类似的。
        </p>
																		<p>
																				<b>
																						<a href="http://www.ietf.org/">Internet
工程任务组（IETF）</a>
																				</b>是一种依靠基层力量发达昌盛的组织模型，同时也尝试引入正式组织的一些节制手段。差不多能够访问
Internet 的任何人都可以提交 
          <b>Internet
草案</b>，并建议作为一种可能的标准。一个指导小组对草案进行了评估，并可能推荐作为
          <b>Request
for Comment（请求注释，RFC）</b>发布。RFC 可以标记为
          <b>Standards
Track RFC（标准跟踪 RFC）</b>或者直接成为
          <b>Standard
RFC（标准 RFC）</b>，但是成为 RFC 的多数文档都经过详细的考察，并且经常已经很好地实现过。
        </p>
																		<p>最后还要向
          <b>XML 社区</b>致意，他们创建非正式的但是重要的标准的努力填补了大型组织留下的空白。SAX、RDDL 和 EXSLT 是一些非常著名的例子。OASIS 通过努力已经成为吸引这类标准争鸣的阵地，但是愿意通过邮件列表打造一种事实标准的仍然不乏其人。
        </p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAUMFAF">
						<span class="atitle">XML Namespaces</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/REC-xml-names/">Namespaces
in XML 1.0</a>
				</b> [W3C 推荐标准]提供了一种统一命名 XML 文档中的元素和属性的机制。一些这些简单的例子可以解释
XML NameSpace 幕后的动机：假设您有一个 XML 词汇表，其中名为“head”和“body”的元素作为解剖学描述的标记，但是您希望在文档中嵌入

        <b>XHTML</b> （参见后述）片段。XHTML
也定义了“head”和“body”元素。如何从同名的宿主词汇表元素中区分 XHTML 元素呢？使用 XML Namespaces 就可以为每种词汇表指定一个标记。在
XML 名称空间中，每种词汇表被称为一个名称空间，有专门的语法表示词汇表标记。每个元素或属性名都和一个名称空间联系，这样就能把解剖学上的“head”和
XHTML “head”区分开来。在 XML 专家中，对 XML 名称空间曾经存在争议，因为对 XML 处理模型增加了一点复杂性，一些人认为这样做带来的好处不能抵消引起的问题。无论如何，XML
名称空间已经在 XML 用户中得到了广泛的认可，差不多所有的 XML 处理技术都能处理 XML 名称空间。
      </p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xml-names11/">Namespaces in XML 1.1</a>
				</b>[开发中]是一次更新，结合了勘误表与补充，其中包括对国际化 URI 的支持。
      </p>
		<p>经常提出的和 XML 名称空间有关的一个问题是，应该标识哪一类资源的名称空间 URI。Jonathan Borden 和 Tim BrayOne
领导的 XML 专家组提出了 
        <b><a href="http://www.rddl.org/">Resource
Directory Description Language （资源目录描述语言，RDDL）</a></b>作为在名称空间中打包信息的一种标准。RDDL
使用 XHTML 提供词汇表的简单描述，用内嵌的 
        <b>XLink</b>（将在本文中讨论）提供到重要资源的指针，帮助理解和处理这种名称空间。
        <a href="http://www.rddl.org/RDDL2">RDDL
2.0</a>[开发中]是一个升级版本，寻求通过两种选择代替 XLink：
        <b>Resource
Description Framework（资源描述框架，RDF）</b>（后面讨论）以及在邮件列表上为
        <b>W3C
Technical Architecture Group（技术体系结构组，TAG）</b>开发的替代 XML 链接建议。
      </p>
		<p>
				<a name="IDA0NFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<p>上面提到的一些 XML 1.0 教程涉及到了 XML 名称空间。此外还有：
</p>
		<ul>
				<li>ZVON 提供了一个
          <a href="http://www.zvon.org/xxl/Namespace%E6%95%99%E7%A8%8B/Output/index.html">XML namespace 教程</a>。
        </li>
				<li>Tim Bray 所写的“
          <a href="http://www.xml.com/pub/a/1999/01/namespaces.html">XML
Namespaces by Example</a>”，给出了一个简单的名称空间的例子。
        </li>
				<li>Anders Miller 和 Michael I. Schwartzbach 所著的“
          <a href="http://www.brics.dk/%7Eamoeller/XML/common/">XML
Namespaces, XInclude, and XML Base</a>”从关于 XML 名称空间的轻松介绍入手。
        </li>
		</ul>
		<p>
				<a name="IDAXOFAF">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>Ronald Bourret 维护的
          <a href="http://www.rpbourret.com/xml/NamespacesFAQ.htm">XML Namespaces FAQ</a>。
        </li>
				<li>James Clark 在他的文章“
          <a href="http://www.jclark.com/xml/xmlns.htm">XML
Namespaces</a>”中详细分析了名称空间，并介绍了描述名称空间常用的符号。
        </li>
				<li>Elliotte Rusty Harold 在文章“
          <a href="http://xml.oreilly.com/news/xmlnut2_0201.html">RDDL
Me This: What Does a Namespace URL Locate?</a>”中介绍了 RDDL。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDARPFAF">
						<span class="atitle">XML Base</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xmlbase/">XML Base</a>
				</b>[W3C
推荐标准]提供了一种联系 XML 元素和 URI 方法，以便更精确地规定在相关的 XML 处理活动中如何解析相对 URI。比方说，如果一个
XML 元素包含使用相对 URL 的链接，要链接的绝对 URL 就要通过参考该元素的基 URL 来决定。多数 XML
处理程序都对组成文档的每个 XML 实体假定一个基 URL，可以使用 XML Base 替换这种默认设置。 </p>
		<p>
				<a name="IDA4PFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>ZVON 提供了
          <a href="http://www.zvon.org/xxl/XMLBase%E6%95%99%E7%A8%8B/Output/">XML Base 教程</a>。
        </li>
				<li>我的 IBM
          <i>developerWorks</i>教程，“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/DDCF775A3623394FC8256CB8001E909E?OpenDocument">4Suite 进行 Python 和 XML 开发,第四部分:合成和更新</a>” （2002 年
10 月）介绍了 XML Base 以及 
          <b>XPointer</b>、
          <b>XInclude</b>（参见后述）和
          <b>XUpdate</b>
（本系列文章将予以介绍）。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDA3QFAF">
						<span class="atitle">XInclude</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xinclude/">XML Inclusions (XInclude) 1.0</a>
				</b>[开发中]提供了一种合并 XML 文档的系统。XInclude 通常用于希望将 XML 文档分成多个可管理的段的情况。可以根据需要分割文档，然后再使用 XInclude 把文档合并回去。
        <b>外部已解析实体</b>是一种 XML 1.0 结构，允许从单独的文件中加载文档的一部分，可以完成类似的功能，从某种程度上说 XInclude 是一种不必要的规范。XInclude 提供了一些特殊的便利之处，比如在包含文档时可以选择包含文档的哪些部分。
      </p>
		<p>
				<a name="IDAMRFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Elliotte Rusty Harold 在“
          <a href="http://www.xml.com/pub/a/2002/07/31/xinclude.html">Using
XInclude</a>”中做了很好的介绍。
        </li>
				<li>ZVON 提供了
          <a href="http://www.zvon.org/xxl/XInclude%E6%95%99%E7%A8%8B/Output/">XInclude 教程</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAASFAF">
						<span class="atitle">XML Infoset</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xml-infoset/">XML Information Set</a>
				</b>[W3C 推荐标准]也称为 XML Infoset，定义了一种抽象的方式把 XML 文档描述为一系列带有特定属性的对象，即
        <b>信息项</b>。这种抽象数据集结合了在 XML 1.0、XML Namespaces 和 XML Base 中定义的 XML 文档的各个方面。XML Infoset 被用作其他几种规范的基础，这些规范试图把 XML 文档分解成一些组成对象的集合。
      </p>
		<p>
				<a name="IDAPSFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Ken Sall 的文章“
          <a href="http://www.informit.com/isapi/product_id%7E%7B1EC2D86B-1679-4648-9E4A-FE70BCE17671%7D/content/index.asp">Exploring
the XML Infoset</a>”摘录自他所著的
          <i><a href="http://www.informit.com/isapi/product_id%7E%7B0C9BD0F5-3800-45DF-8C86-283F5DE38D84%7D/session_id%7E%7B37EA2FED-7424-42BB-B5E4-6C0864D9E041%7D/content/index.asp">XML
Family of Specifications: A Practical Guide</a></i>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDACTFAF">
						<span class="atitle">Canonical XML ("c14n")</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xml-c14n">Canonical
XML Version 1.0</a>
				</b> [W3C 推荐规范]是一种生成 XML 文档物理表示的标准方法，称为规范化形式，用于统一 XML
语法中不影响语义的几种变体。比如，在 XML 中属性的顺序并不重要，因此如果一个文档中所有的属性都按照字母顺序排列，而另一个相同的文档以不同的方式保存属性，尽管其物理表示不同，但对于
XML 1.0 而言两个文档是等价的。这有时候会造成应用中的问题。比如，如果希望用数字加密的签名保护文档不被篡改，改变属性的顺序会破坏签名，尽管对
XML 1.0 来讲文档实际上并没有改变。解决的办法是在签名、文本比较或者其他此类操作之前把文档转化成规范的形式（这个过程称为“规范化（c14n）”）。这样就可以保证正确地接纳
XML 1.0 中认为不重要的变动。
      </p>
		<p>有时候需要比较或者签署的 XML 实际上是一个更大的文档的一部分。即便如此，c14n 通常也需要解决这种问题以便处理名称空间声明这样的细节。如果需要把 c14n 严格限制在一个文档子集中，就必须使用相关的算法
        <b><a href="http://www.w3.org/TR/xml-exc-c14n/">Exclusive XML Canonicalization Version 1.0</a></b>[W3C 推荐标准]。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="xpath">
						<span class="atitle">XPath</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) 1.0</a>
				</b>[W3C 推荐标准]是处理 XML 文档部分的一种语法和处理模型。它包括一些通用表达式语言的特性，被设计成一种小型的语言，以便在 XML 系统中进行应用程序中立的处理。比如，可以使用 XPath 定位文档中所有的节标题元素。
      </p>
		<p>除了 XML 1.0 本身，XPath 可能是最成功的 XML 技术。它是
        <b>XSLT</b>（本系列文章中间加以论述）的核心，后者是一种非常成功的 XML 转换语言，差不多所有的平台上都提供它处理 XML。
        <b><a href="http://www.w3.org/TR/xpath20/">XPath 2.0</a></b>[开发中]增加了新的特性，包括对
        <b>W3C XML Schema</b>（后面将讨论）的支持和许多新的核心功能。这是一个饱受争议的规范，因为它的庞大增加了复杂性；许多用户和实现者（包括我自己）都说除非 XPath 2.0 得到很大的简化，否则就避免使用它。
      </p>
		<p>
				<a name="IDAOUFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<p>基本上所有关于 XSLT 的介绍都同时涉及到 XPath。这里列出专门讨论 XPath 的教程：
</p>
		<ul>
				<li>ZVON 的
          <a href="http://www.zvon.org/xxl/XPath%E6%95%99%E7%A8%8B/Output/">XPath 教程</a>是一个以例子为主的教程。
        </li>
				<li>W3Schools 的
          <a href="http://www.w3schools.com/xpath/">XPath 教程</a>对这个规范的各个方面作了介绍。
        </li>
				<li>
						<i>
								<a href="http://www.oreilly.com/catalog/xmlnut/">XML in a Nutshell</a>
						</i>（Elliotte Rusty Harold 与 W. Scott Means 合著）中的
          <a href="http://www.oreilly.com/catalog/xmlnut/chapter/ch09.html">第 9 章：XPath</a>，是一篇更浅显的介绍。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDANVFAF">
						<span class="atitle">XPointer</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xptr-framework/">XPointer Framework</a>
				</b>[W3C 推荐标准]定义了一种语言，可用语音用 XML 文档中的片段。对于使用带有井号（#）的 URL 链接到 XML 文档中的特定片段，您可能已经非常熟悉了。在链接和引用 XML 文档时，XPointer 带来了类似但是更广泛的能力。这种框架可以和
        <b><a href="http://www.w3.org/TR/xptr-xpointer/">xpointer() scheme</a></b>[开发中]、
        <b><a href="http://www.w3.org/TR/xptr-element/">element() scheme</a></b>[W3C 推荐标准]以及
        <b><a href="http://www.w3.org/TR/xptr-xmlns/">xmlns() scheme</a></b>[W3C 推荐标准]一起使用，这些标准定义了在 XPointer 框架中表达所关心的文档片段的具体要求。
      </p>
		<p>XPointer 经历了一段艰难的历程，饱受非议。XPointer 工作组本身的成员开发了一种相反的建议，
        <b><a href="http://lists.w3.org/Archives/Public/www-xml-linking-comments/2001AprJun/att-0074/01-NOTE-FIXptr-20010425.htm">FIXptr</a></b>
[社区标准]。几种替代的 XPointer 方案包括 
        <a href="http://www.simonstl.com/ietf/draft-stlaurent-xpath-frag-00.txt">the
xpath1() scheme</a>[IETF Internet 草案]。
      </p>
		<p>
				<a name="IDAVWFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<p>
在成为推荐标准之前，XPointer 进行了非常大的修改，所以要注意有许多教程所讨论的是旧版本。 </p>
		<ul>
				<li>ZVON 提供了
          <a href="http://www.zvon.org/xxl/XPointer%E6%95%99%E7%A8%8B/Output/">XPointer 教程</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAEXFAF">
						<span class="atitle">XLink</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xlink/">XML
Linking Language (XLink) 1.0</a>
				</b> [W3C 推荐标准]提供了一种在 XML 文档中表示链接的通用框架。需要链接的超文本是
Web 的基础，加入完善的链接能力一直被认为是 XML 的基石。事实上，XLink 最初被称为 "XML part 2"。不幸的是实践证明，为
XML 定义一种链接系统和为 HTML 这样的静态词汇表定义链接系统相比要远远复杂得多。XLink 的开发经历了漫长的过程，遭受了种种非议。比如，XHTML
（本系列文章将讨论）的开发者决定不使用 XLink 而创建他们自己的系统，称为 
        <b><a href="http://www.w3.org/TR/hlink/">HLink</a></b>
[开发中]。即使到现在，XLink 已经完成两年了，对它的采用仍然非常缓慢。。
      </p>
		<p>无论如何，XLink 都非常重要，处在许多 XML 相关项目中的中心位置，与基本的、单向的 HTML 链接相比提供了更丰富的链接功能。XLink 页提供了这种链接（
        <b>简单链接</b>)，同时还提供了更复杂的可以有多个端点的链接（
        <b>扩展链接</b>），甚至还有在链接的文档中没有表达而是在专门的中心文档（称为
        <b>链接库</b>）中表示的链接。
      </p>
		<p>
				<a name="IDA4XFAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<p>您可能会找到讨论该语言的旧的、废止的草案的 XLink 教程。下面是最新的教程：
</p>
		<ul>
				<li>Eve Maler 的文章“
          <a href="http://wwws.sun.com/software/xml/developers/xlink/">XML
Linking: State of the Art</a>”是关于该规范中形式化概念的一般描述。
        </li>
				<li>ZVON 提供了单独的 XLink 教程：
          <a href="http://www.zvon.org/xxl/xlink/OutputExamples/xlinksimple_intro.html">简单链接</a>和
          <a href="http://www.zvon.org/xxl/xlink/xlink_extend/OutputExamples/xlinkextend_intro.html">扩展链接</a>。
        </li>
		</ul>
		<p>
				<a name="IDA0YFAF">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 也提供了一份“
          <a href="http://www.zvon.org/xxl/xlink/Output/xlink_refs.html">XLink
Reference</a>”。
        </li>
				<li>Bob DuCharme 在他的文章中“
          <a href="http://www.xml.com/pub/a/2002/03/13/xlink.html">XLink:
Who Cares?</a>”中讨论了 XLink 的历史并研究了它的实现。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAOZFAF">
						<span class="atitle">RELAX NG</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://relaxng.org/spec-20011203.html">RELAX
NG</a>
				</b>[OASIS 委员会规范和 ISO 草案标准]是一种
        <b>XML
模式</b>语言，即一种可用于定义和限制 XML 词汇表的语言。最初的 XML 模式语言是 XML 1.0 自己定义的文档类型定义（DTD）。但是，一些人不喜欢
DTD，因为它丑陋的语法、表达文本和标记结构的局限性，并且难以处理 XML Namespaces。出现了几种新的 XML 模式语言以取代或者增强
DTD，其中包括 RELAX NG，以其简单性和表达能力而闻名。RELAX NG 的核心规范定义了架构的 XML 语法，此外
        <b><a href="http://relaxng.org/compact-20021121.html">RELAX
NG Compact Syntax</a></b> [OASIS 委员会规范]还为 RELAX NG 架构定义了一种简单的文本语法。人们期望这种文本语法作为补充添加到
ISO 标准中。RELAX NG 是称为 
        <a href="http://www.dsdl.org/">Document
Schema Definition Languages（文档模式定义语言，DSDL）</a>的整个 ISO XML 模式处理系统的研究工作的一部分。
      </p>
		<p>
				<a name="IDAG0FAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>阅读 Nicholas Chase 的入门教程“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/FE680FD009FE6968C8256E0B000EA2D3?OpenDocument">理解
RELAX NG</a>”，它可以帮助您迅速领略 RELAX NG 的简单性和强大功能，包括它的完全基于 XML 的语法和紧凑语法（
          <i>developerWorks</i>，2003
年 12 月）。
        </li>
				<li>David Mertz 在
          <i>developerWorks</i> 上的“XML 问题”专栏，在其系列文章“使用 RELAX NG 反击”中专门讨论了 RELAX NG：

          <ul><li><a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters/part25/index.shtml">第 1 部分</a>考察了 RELAX NG 的一般语法，并涉及到数据类型化（2003 年 3 月）。
            </li><li><a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters/part26/index.shtml">第 2 部分</a>通过解决几个附加的语义问题继续前面的讨论，并考察了可以使用 RELAX NG 的工具（2003 年 3 月）。
            </li><li><a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters/part27/index.shtml">第 3 部分</a>详细探讨了 RELAX NG 紧凑语法，并揭示了紧凑语法和 XML 语法之间的完全对应关系（2003 年 5 月）。
            </li></ul></li>
				<li>RELAX NG 的正式教程
          <a href="http://relaxng.org/tutorial-20011203.html">核心</a>和它的
          <a href="http://relaxng.org/compact-tutorial-20030326.html">紧凑语法</a>。
        </li>
				<li>ZVON 提供了一个混合教程
          <a href="http://www.zvon.org/xxl/XMLSchematutorial/Output/index.html">RELAX NG and W3C XML Schema language</a>（本系列文章将讨论）。
        </li>
		</ul>
		<p>
				<a name="IDA01FAF">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>许多资料都链接到了
          <a href="http://relaxng.org/">RELAX NG 主页</a>。
        </li>
				<li>ZVON 提供了“
          <a href="http://www.zvon.org/xxl/RelaxNG/Output/index.html">RELAX
NG Reference</a>”。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAO2FAF">
						<span class="atitle">W3C XML Schema</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xmlschema-1/">XML Schema Part 1: Structures</a>
				</b>和
        <b><a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes</a></b>[W3C
推荐标准]定义了另一种 XML 模式语言。 第一部分用于约束文档的结构，第二部分则用于约束简单元素和属性的内容。W3C XML Schema
(WXS) 由于过于复杂和表达能力不足而受到了批评，结果造成与其他语言如 RELAX NG
的竞争。逐渐地，人们开始仅仅使用最适合自身的模式语言，而根据需要求助于转换工具从一种形式转化成另一种形式，这类工具的大量涌现给人留下了深刻的印
象。许多其他的规范已经采用了 WXS DataTypes 规范，尽管也有开发其他数据类型系统的呼声。工作组已经开始 WXS 1.1
的研发工作。 </p>
		<p>
				<a name="IDAA3FAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Nicholas Chase 的
          <i>developerWorks</i>教程“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/5938A56DCD6980E348256B9D003285AA?OpenDocument">验证 XML</a>”同时涉及到 DTD 和 WXS（2003 年 8 月）。
        </li>
				<li>W3Schools 有一个
          <a href="http://www.w3schools.com/schema/default.asp">WXS 教程</a>.
        </li>
				<li>W3C XML Schema 工作组在
          <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: Primer</a>中对这种技术作了透彻而浅显的介绍。
        </li>
		</ul>
		<p>
				<a name="IDA23FAF">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 提供了一份
          <a href="http://www.zvon.org/xxl/xmlSchema2001Reference/Output/">WXS 参考</a>。
        </li>
				<li>W3Schools 上有一个
          <a href="http://www.w3schools.com/schema/schema_elements_ref.asp">WXS Elements Reference</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAQ4FAF">
						<span class="atitle">Schematron</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.ascc.net/xml/resource/schematron/Schematron2000.html">Schematron Assertion Language 1.5</a>
				</b>[社
区标准和草案 ISO 标准]是一种模式语言，使用了不同于 DTD、RELAX NG 和 WXS 的方法。在 Schematron
中，您需要对要检查的 XML 文档登记一组规则，而不是绘制出试图表达的 XML 格式从根节点到叶子的整个树结构。这就使得 Schematron
不仅可以作为一种独立的、非常有用的模式语言，也可以作为其他模式语言的补充。Schematron
可以表达我所讨论的其他语言所不能表达的约束，因此经常与其他语言协同使用。 </p>
		<p>
				<a name="IDA34FAF">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>ZVON 提供了一个
          <a href="http://www.zvon.org/xxl/Schematrontutorial/General/contents.html">Schematron 教程</a>。
        </li>
				<li>Chimezie Thomas-Ogbuji 撰写了一篇介绍文章，“
          <a href="http://www.xml.com/lpt/a/2000/11/22/schematron.html">Validating
XML with Schematron</a>”。
        </li>
		</ul>
		<p>
				<a name="IDAR5FAF">
						<span class="smalltitle">参考资料与其他资源</span>
				</a>
		</p>
		<ul>
				<li>
						<a href="http://www.ascc.net/xml/resource/schematron/schematron.html">Schematron 主页</a>与
          <a href="http://www.ascc.net/xml/schematron/">资源目录</a>提供了许多有用的链接。
        </li>
				<li>ZVON 还提供了一份
          <a href="http://www.zvon.org/ZvonSW/ZvonSchematron/Reference/Output/">Schematron 参考</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAMAGAF">
						<span class="atitle">后续内容</span>
				</a>
		</p>
		<p>本文中综述了最重要的核心 XML 标准。在第 2 部分，我将介绍对于在应用程序处理中使用 XML 的人而言非常重要的标准。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的
          <a href="http://www.ibm.com/developerworks/library/x-stand1.html">英文原文</a>.
        <br /><br /></li>
				<li>如果希望就 XML 获得坚实的基础，请阅读
          <a href="http://www.ibiblio.org/xml/books/bible2/"><i>The
XML Bible, 2nd Edition</i></a>，Elliotte Rusty Harold 著（John Wiley &amp;
Sons，2001 年），前提是您愿意买下这本书。
          <br /><br /><br /><br /></li>
				<li>访问开发 XML 标准的最重要组织的网站：

          <ul><li><a href="http://www.w3.org/">W3C （万维网联盟）</a></li><li><a href="http://www.oasis-open.org/">OASIS （结构化信息标准推进组织）</a></li><li>ISO （国际标准化组织），尤其是它的项目
              <a href="http://dsdl.org/">ISO/IEC 19757 - Document Schema Definition Languages （文档模式定义语言，DSDL）</a></li></ul><br /><br /></li>
				<li>Simon St. Laurent 所写的
          <a href="http://simonstl.com/articles/civilw3c.htm">Outsider's Guide to the W3C</a>是一个 FAQ，澄清了这个为您带来 HTML 和 XML 的组织的许多方面。
          <br /><br /><br /><br /></li>
				<li>Robin Cover 的
          <a href="http://xml.coverpages.org/">The Cover Pages</a>基本上涉及到了 XML 的每个方面，这是一个令人瞠目的、包罗万象的 XML 资源指南。
          <br /><br /><br /><br /></li>
				<li>访问
          <a href="http://xmlhack.com/">xmlhack</a>，XML 开发人员的新闻站点，Uche 帮助编辑。
          <br /><br /><br /><br /></li>
				<li>在
          <a href="http://www-128.ibm.com/developerworks/cn/xml/"><i>developerWorks
</i>XML 专区
          </a>可以找到更多的 XML 资源，包括 Uche Ogbuji 的
          <a href="http://www-128.ibm.com/developerworks/cn/xml/rdf/index.shtml"><i>Thinking
XML</i>专栏
          </a>。
          <br /><br /><br /><br /></li>
				<li>了解如何才能成为一名
          <a href="http://www-128.ibm.com/developerworks/cn/xml/theme/x-cert.html">IBM 认证的 XML 及相关技术开发人员</a>。
          <br /><br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="Uche Ogbuji 的照片" src="http://www-128.ibm.com/developerworks/cn/i/p-uche.jpg" align="left" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Uche
Ogbuji 是 
        <a href="http://fourthought.com/">Fourthought
Inc.</a>的顾问和共同创始人，该公司是专为企业知识管理提供 XML 解决方案的软件供应商和咨询公司。 Fourthought
开发了 
        <a href="http://4suite.org/">4Suite</a>，这是一个用于
XML、RDF 和知识管理应用程序的开放源代码平台。Ogbuji 先生是一位出生于尼日利亚的计算机工程师和作家，他现在美国科罗拉多州的博耳德生活和工作。可以通过

        <a href="mailto:uche.ogbuji@fourthought.com">uche.ogbuji@fourthought.com</a>
和 Ogbuji 先生联系。 
      </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35987.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:27 <a href="http://www.blogjava.net/Vencent/articles/35987.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 观察: 追溯 RDF 数据的源头::RDF 工具正逐渐成熟起来</title><link>http://www.blogjava.net/Vencent/articles/35984.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:26:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35984.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35984.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35984.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35984.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#author">Edd Dumbill</a>, 编辑兼发行人, xmlhack.com<br /></p>
		<p>2003 年  3 月  01 日</p>
		<blockquote>当
您开始聚集来自 Web 的数据时，了解其来源是至关重要的。本文中，Edd Dumbill 研究了 Redland
资源描述格式（Resource Description Format，RDF）应用程序框架的上下文特性并创建了作为演示的一个 RDF Site
Summary（RSS）1.0 聚集器。</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>一年前，我为
        <i>developerWorks</i>写了两篇有关
        <b>朋友的朋友（Friend-of-a-Friend，FOAF）</b>项目的文章。FOAF 是一种 XML/RDF 词汇表，用于以计算机可读的形式描述您通常可以放在主 Web 页上的某种个人信息，如您的姓名、即时信使昵称和工作地点等。
      </p>
		<p>在我有关 FOAF 的第二篇文章（请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#resources">参考资料</a>）的清单 6 中，我演示了
        <b>FOAFbot</b>，一个我编写的聚集人们的 FOAF 文件并回答相关问题的社区支持代理。FOAFbot 能够记录谁说了关于谁的什么事情。当问及我叫什么名字时，FOAFbot 答道：
      </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="600">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />edd@xml.com's name is 'Edd Dumbill',<br />according to Dave Beckett, Edd Dumbill,<br />Jo Walsh, Kip Hampton, Matt Biddulph,<br />Dan Brickley, and anonymous source Anon47<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>FOAFbot 背后的思想是，如果您能够验证不同的几个人（您所信任的人）都记录了一个事实，那么您很可能相信这是真实的。</p>
		<p>以
下是追溯这样的元数据源头的另一个运用。搜索引擎在其早期历史中被滥用的一个主要表现是恶意元标记（meta tag
spamming）。网站会把错误的元数据放到它们的页面中以提高它们的搜索引擎排名。由此，搜索引擎不再关注元标记，因为它们极有可能提供虚假信息。事
实上，象 Google 这样的搜索引擎找到了其它更高级的度量来评定页面关联性。</p>
		<p>展望 Web 的未来，避免诸如恶意元标记这样的滥用将变得至关重要。Tim Berners-Lee 对 Semantic
Web 的展望（请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#resources">参考资料</a>）是希望出现这样一个 Web：其上大多数的数据都是机器可读的，从而使得目前由人类完成的大多数信息处理自动进行。
      </p>
		<p>元数据滥用在 Semantic Web 上可能造成的麻烦甚至更大：网站不再限于仅仅造自己站点的假。它还可以造其它站点的假。例如，一家书店对竞争者的报价作假，这是有可能的。</p>
		<p>我不会探究各种安全性和可信机制（这些机制将防止这种语义的破坏行为）的细节，而是将重点讨论这样的机制之所以成为可能的基础：
        <b>追溯源头</b>。
      </p>
		<p>
				<a name="0">
						<span class="atitle">存储 RDF</span>
				</a>
		</p>
		<p>处理 RDF 然后存储它的应用程序使用
        <b>三元组存储（triple store）</b>来做到这一点。RDF/XML 输入文档被分解成一列包含 
        <code>主语、谓语和宾语</code>
的三元组。然后后续处理就是操作和查询存储中的三元组。只有在涉及到交换时，才会用 RDF 的 XML 语法。由于将数据直接分解成三元组，所以
XML 工具（象 XPath 或 XQuery）就没有多少用处了。已经有人编写了直接使用 XQuery 操作 XML 语法的 RDF
处理工具，但我认为对于通用的 RDF 处理，这多少有点多此一举。 </p>
		<p>为了进行演示，我将向您展示如何将简单的 RSS 1.0 文档用作测试数据。最近我建立了一个 weblog 站点，其中，我对不知情的公众强加了我的观点。为了将我涂鸦式的元数据放在一起，我生成了一个 RSS 1.0 文件（请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#resources">参考资料</a>获取链接）。该文件的开始部分类似于清单 1，曾接触过 RSS 的任何人应该对它非常熟悉。
      </p>
		<br />
		<a name="code1">
				<b>清单 1. 摘自 RSS 1.0 文件的开始部分</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">&lt;rdf:RDF<br />  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"<br />  xmlns:dc="http://purl.org/dc/elements/1.1/"<br />  xmlns="http://purl.org/rss/1.0/"<br />&gt;<br />  &lt;channel rdf:about="http://usefulinc.com/edd/blog"&gt;<br />    &lt;title&gt;Edd Dumbill's Weblog: Behind the Times&lt;/title&gt;<br /><br />    &lt;description&gt;<br />      Thoughts and comment from Edd Dumbill, technology writer<br />      and free software hacker.<br />    &lt;/description&gt;<br />    &lt;link&gt;http://usefulinc.com/edd/blog&lt;/link&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在 RDF 处理器将这一部分解析成三元组时，我获得了清单 2 中显示的数据。</p>
		<br />
		<a name="code2">
				<b>清单 2. 与清单 1 的开始部分对应的 RDF 三元组</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">[http://usefulinc.com/edd/blog,<br />    http://www.w3.org/1999/02/22-rdf-syntax-ns#type,<br />    http://purl.org/rss/1.0/channel]<br />[http://usefulinc.com/edd/blog,<br />    http://purl.org/rss/1.0/title,<br />    "Edd Dumbill's Weblog: Behind the Times"]<br />[http://usefulinc.com/edd/blog,<br />    http://purl.org/rss/1.0/description,<br />    "Thoughts and comment from Edd Dumbill,<br />     technology writer and free software hacker."]<br />[http://usefulinc.com/edd/blog,<br />    http://purl.org/rss/1.0/link,<br />    "http://usefulinc.com/edd/blog"]<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>随后 RDF 应用程序所要操作的就是
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#code2">清单 2</a>中显示的这列三元组了。至此，一切都很顺利。但在存储这个数据时，您会丢失一些重要信息的线索，即数据的出处和其它相关数据，如我是何时对数据拍了快照。要记录这个信息，我需要通过一些方式使该信息与我所找到的 RDF 语句相关联。
      </p>
		<p>首先，对于
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#code2">清单 2</a>中的数据，我需要模拟出一个描述，记录下对于这些数据我可能要说的内容。清单 3 就包含了这样一个示例描述，它使用了专为这一目的而虚构出的一个示例名称空间。
      </p>
		<br />
		<a name="code3">
				<b>清单 3. 检索清单 1 和清单 2 中数据的示例描述</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">&lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"<br />  xmlns:me="http://example.org/ns/mymeta#"&gt;<br /><br />&lt;rdf:Description rdf:about="http://example.org/retrieval/52365"&gt;<br />    &lt;me:origin rdf:resource="http://usefulinc.com/edd/blog/rss" /&gt;<br />    &lt;me:retrieved&gt;2003-06-24T08:59:55.00Z&lt;/me:retrieved&gt;<br />&lt;/rdf:Description&gt;<br />&lt;/rdf:RDF&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>您可以从
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#code3">清单 3</a>中看出：我已经（任意）虚构了一个 URI 来表示对一个文件进行的第 52365 次检索。这似乎是一个合理的方法，如同任何对远程资源的每次轮询所命名的那样。这个资源的出处是这个 RSS 1.0 文件的 URI，而时间戳记表明何时找到它的。
      </p>
		<p>现在，剩下的就是存储四元组，而不是存储三元组。清单 4 展示了我如何修改
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#code2">清单 2</a>以显示我现在添加到存储中的所有数据。
      </p>
		<br />
		<a name="code4">
				<b>清单 4. 增加了上下文 URI 和上下文元数据的三元组</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">[http://usefulinc.com/edd/blog,<br />    http://www.w3.org/1999/02/22-rdf-syntax-ns#type,<br />    http://purl.org/rss/1.0/channel,<br />    http://example.org/retrieval/52365]<br />[http://usefulinc.com/edd/blog,<br />    http://purl.org/rss/1.0/title,<br />    "Edd Dumbill's Weblog: Behind the Times",<br />    http://example.org/retrieval/52365]<br />[http://usefulinc.com/edd/blog,<br />    http://purl.org/rss/1.0/description,<br />    "Thoughts and comment from Edd Dumbill,<br />     technology writer and free software hacker.",<br />    http://example.org/retrieval/52365]<br />[http://usefulinc.com/edd/blog,<br />    http://purl.org/rss/1.0/link,<br />    "http://usefulinc.com/edd/blog",<br />    http://example.org/retrieval/52365]<br />[http://example.org/retrieval/52365,<br />    http://example.org/ns/mymeta#origin,<br />    http://usefulinc.com/edd/blog/rss,<br />    &lt;NULL&gt;]<br />[http://example.org/retrieval/52365,<br />    http://example.org/ns/mymeta#retrieved,<br />    "2003-06-24T08:59:55.00Z",<br />    &lt;NULL&gt;]<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#code4">清单 4</a>中演示的思想是每个 RDF 语句都增加了一个 URI，它将该 RDF 语句链接到我想要存储的有关该 RDF 语句的元数据上。这个简单机制给我带来了无穷的力量。除了使我能够检索有关该 RSS 文件的元数据以外，它还提供了从存储中除去该信息的便利方法。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="1">
						<span class="atitle">实际实现</span>
				</a>
		</p>
		<p>在运用这个思想时，我已将上面四元组的第四个元素称为
        <b>上下文</b>。这个术语并不规范，但它对我而言非常有效。而且，Redland RDF 应用程序框架中也使用了这个术语，我将使用该框架来演示这个追溯源头的应用程序。
      </p>
		<p>（顺
便提一下，我要对 Dave Beckett（Redland 的创建者）表示感谢。在我去年编写 FOAFbot 时，Redland
不支持上下文，所以我最终只能以一种非常繁冗的格式来实现上下文。Dave 回应了我的请求，他将上下文的支持添加到了他的工具箱中。）</p>
		<p>Redland
是一个基于 C 的工具箱，带有许多语言绑定，包括 Python、Perl 和 Java。它由一个 RDF 解析器、raptor
和一个数据存储组成。该存储目前使用 Berkeley DB 文件，不过还在开发对底层 SQL 存储的支持。对于我的示例而言，我将使用到
Redland 的 Python 绑定。</p>
		<p>这里的目标是要创建一个简单的 RSS 1.0
聚集器。使用聚集器的目的是对多个 RSS 馈送进行重复拍快照，并允许您以有趣的方式组合它们。随着新内容项的加入，RSS
文件会随着时间的变化而发生更改 － 我想避免多个冗余项，而仍能保留历史项。在本文后面，我将开发所需的一些功能。</p>
		<p>您将在
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#resources">参考资料</a>中找到一个到这个项目的 Python 代码（fraggle.tar.gz）的链接。还有一个到 Redland 工具箱的链接，您也需要安装这个工具箱。
      </p>
		<p>
				<code>Aggregator</code> 类会处理访存和存储 RDF 数据这个有趣的工作。清单 5 摘自这个类的 
        <code>load_uri</code> 方法，它从 
        <code>aggregate.py</code> 的第 189 行开始。
      </p>
		<br />
		<a name="code5">
				<b>清单 5. 追溯检索到的 RDF 的上下文</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">stream = self._parser.parse_as_stream(<br />        RDF.Uri(string="file:./%s" % fname),<br />        base_uri=urinode.uri)<br />if stream:<br />    channel = None<br /><br /><span class="boldcode">context = self.context_uri_node()</span><br />    timestamp = RDF.Node(literal=<br />        time.strftime("%Y-%m-%dT%H:%M:%S.00Z"))<br />    while not stream.end():<br />        statement = stream.current()<br />        # add the statement to the model, with context<br /><br /><span class="boldcode">self._model.add_statement(statement, context)</span><br /><br />        # if it's a &lt;rss:channel&gt; remember the URI<br />        if ( statement.predicate == _rdfType and<br />            statement.object == _rssChannel ):<br />            channel = RDF.Node(node=statement.subject)<br /><br />        # move on<br />        stream.next()<br /><br />	# now to add the context information<br />	# first, the source URI<br /><br /><span class="boldcode">self._model.add_statement(RDF.Statement(<br />	subject=context, predicate=_fraggieSource,<br />	object=urinode), _globalContext)</span><br />	# second, the channel URI<br /><br /><span class="boldcode">self._model.add_statement(RDF.Statement(<br />	subject=context, predicate=_fraggieChannel,<br />	object=channel), _globalContext)</span><br />	# third, the timestamp<br /><br /><span class="boldcode">self._model.add_statement(RDF.Statement(<br />	subject=context, predicate=_fraggieTimestamp,<br />	object=timestamp), _globalContext)</span><br />	# fourth, the checksum<br /><br /><span class="boldcode">self._model.add_statement(RDF.Statement(<br />	subject=context, predicate=_fraggieChecksum,<br />	object=RDF.Node(literal=checksum)), _globalContext)<br />	self.register_fetch(urinode, context)</span><br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>该清单中用粗体显示的几行与追溯上下文有关。首先，使用 
        <code>context_uri_node()</code> 生成上下文的 URI。这返回形式为 
        <code>http://usefulinc.com/fraggie/global/1</code> 的 URI 结果。这个上下文然后被追加到在检索到的 RSS 中找到的每个语句中。一旦存储了 RSS 数据，我随后就将有关上下文 URI 的数据添加到存储中。在本例中，我存储了作为 RSS 文件来源的 URI、RSS 通道本身的 URI（ 
        <code>rss:channel</code> 元素中的 
        <code>rdf:about</code> 值）、访存文件的时间以及文件的 MD5 校验和（以便以后确定 RSS 文件是否随时间变化而发生了更改）。
      </p>
		<p>如果您下载了源代码，那么正如您将看到的， 
        <code>Aggregator</code> 类的其余部分实现了两个功能：第一个是 RSS 搜索所需的内务处理方法；第二个向聚集器的询问者提供了查询方法。请注意，所有的内务处理变量（如 
        <code>fetch</code> 计数）都是用 RDF 表示的，并且保存在 RDF 存储中。清单 6 展示了将计数变量表示为 RDF/XML 语句。
      </p>
		<br />
		<a name="code6">
				<b>清单 6. 用 RDF 表示的内部计数器</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">&lt;rdf:Description<br />    rdf:about="http://usefulinc.com/fraggie/counter"<br />    rdf:value="0" /&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>我发现在 RDF 存储中持久地保存任何拥有全局作用域的变量是很有意义的。这种方法的一个直接优点是它在多次调用后仍能保持状态。</p>
		<p>该演示归档文件包括两个您可以运行的示例 RSS 文件。使用 
        <code>python fraggle.py</code>
可以调用该演示。该演示首先使聚集器装入这两个示例 RSS 文件，它们都引用了 Mark Pilgrim 最近在 XML.com
上发表的一篇文章。这个练习的目的是找到谁对这篇文章作了什么评价。运行该演示产生的输出如清单 7
所示（为可读性起见，已对一些输出行重新进行了格式处理）。 </p>
		<br />
		<a name="code7">
				<b>清单 7. fraggle.py 的输出</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">Links to http://www.xml.com/pub/a/2003/07/02/dive.html<br /><br />From : Meerkat: An Open Wire Service: XML.com<br />       &lt;http://meerkat.oreillynet.com/&gt;<br />Time : 2003-07-05T15:39:26.00Z<br />Title: The Vanishing Image: XHTML 2 Migration Issues<br />Desc :  In Mark Pilgrim's latest Dive Into XML column,<br />       Pilgrim examines XHTML 2.0 &lt;tt&gt;object&lt;/tt&gt;<br />       element, which is a replacement for the more<br />       familiar and widely supported &lt;tt&gt;img&lt;/tt&gt;.<br /><br />From : paranoidfish.org/links<br />       &lt;http://www.paranoidfish.org/links/&gt;<br />Time : 2003-07-05T15:39:25.00Z<br />Title: XML.com: The Vanishing Image: XHTML 2 Migration<br />       Issues [Jul. 02, 2003]<br />Desc : using &lt;object&gt; as a replacement for &lt;img&gt;<br />       is not a safe bet right now<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>摘自 XML.com 的第一部分展示了对这篇文章的正式描述。第二部分摘录展示了由 paranoidfish.org 网站所有者提供的摘要。</p>
		<p>如果您研究过 
        <code>fraggle.py</code>
的源代码，那么将明白所有查询都围绕上下文进行。首先，会询问聚集器哪些上下文提到了这篇文章的
URI。然后根据上下文请求文章元数据并建立索引。请注意，上下文在时间上对应于一个馈送的快照。如果我的示例随时间变化要获得更多 RSS
文件的快照，那么您可能会看到有几项都是来自同一来源的 － 可能在描述上稍作了更改（人们常常会随时修正拼写错误）。对 <code>fraggle.py</code> 中查询的一个明显改进是根据源进行分组，而不是单单根据时间顺序进行显示。
      </p>
		<p>尽
管从浏览、自我冲浪（ego-surfing）的角度而言，weblog 和其它因特网站点的 RSS
馈送很有趣，但我认为象这样一个项目的真正价值很有可能体现在企业中。许多组织常常会生成大量以时间为序的数据流。举一个简单的示例，URI
分配给了客户或项目，然后就可以生成并聚集活动的 RSS 流。</p>
		<p>然后可以很轻松的为那些对这样的聚集数据感兴趣
的任何人划分和切割这些数据。例如，管理者可能希望知道每个工人在做什么，项目经理可能希望获得最近的三个状态更新，更高级的管理层可能希望获得整个部门
的快照视图，等等。不难想象，这种工具很可能会在客户关系管理（CRM）这一领域中产生最佳收益。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>本文中演示的简单示例只触及了追溯 RDF 源头的皮毛。在 Web 上，信息来自哪里与信息本身同样重要。源头追溯的 RDF 工具刚开始兴起，当它们的使用变得更广泛时，它们的能力无疑会更加完善。</p>
		<p>毫无疑问，Redland RDF 应用程序框架是一个值得进一步研究的工具箱。它具有到您最喜爱的脚本编制语言的接口；它运行在 UNIX、Windows 和 Mac OS X 上；而且它是一个开放源码项目，所以您所做的任何改进会使整个社区受益。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的
          <a href="http://www.ibm.com/developerworks/library/x-rdfprov.html">英文原文</a>.
        <br /><br /></li>
				<li>请参加有关本文的
          <a href="javascript:void forumWindow()">论坛</a>。（您也可以单击本文顶部或底部的
          <b>讨论</b>访问该论坛。）
          <br /><br /><br /><br /></li>
				<li>查阅
          <a href="http://rdfweb.org/">RDFWeb 站点</a>，它是 FOAF 项目的“老家”。
          <br /><br /><br /><br /></li>
				<li>请阅读“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-watch/part3/index.shtml">Finding friends with XML and RDF</a>”，这是作者描述“朋友的朋友”项目的第一篇文章（
          <i>developerWorks</i>，2002 年 6 月）。
          <br /><br /><br /><br /></li>
				<li>请阅读“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-watch/part4/index.shtml">Support online communities with FOAF</a>”，其中包含了上面提到的清单 6（
          <i>developerWorks</i>，2002 年 8 月）。
          <br /><br /><br /><br /></li>
				<li>探究
          <a href="http://www.w3.org/2001/sw/">W3C 的 Semantic Web 主页</a>，其中说明了 Semantic Web 远景和 W3C 正在对此进行的开发工作。
          <br /><br /><br /><br /></li>
				<li>浏览
          <a href="http://purl.org/rss/1.0/">RSS 1.0 规范</a>，其中描述了 RSS 核心词汇表和扩展机制。
          <br /><br /><br /><br /></li>
				<li>链接到作者自己的
          <a href="http://usefulinc.com/edd/blog/rss">RSS 文件</a>，其中含有他的 weblog 中最新项的元数据。
          <br /><br /><br /><br /></li>
				<li>请阅读 Dave Beckett 编写的开放源码“
          <a href="http://www.redland.opensource.ac.uk/">Redland RDF Application Framework</a>”，以获得本文示例中所用的框架。
          <br /><br /><br /><br /></li>
				<li>查阅
          <a href="http://www.redland.opensource.ac.uk/docs/python.html">Redland 的 Python 绑定</a>，它们使得在 Python 脚本编制语言中能够轻松建立基于 RDF 的应用程序的原型。
          <br /><br /><br /><br /></li>
				<li>下载
          <a href="http://usefulinc.com/software/fraggle/fraggle.tar.gz">fraggle 的源代码</a>和示例项目：fraggle.tar.gz。您还可以在
          <a href="http://svn.usefulinc.com/svn/repos/trunk/fraggle/src/">fraggle 的子版本（subversion）资源库</a>上跟踪作者对这个代码的持续开发。
          <br /><br /><br /><br /></li>
				<li>在
          <i>developerWorks</i><a href="http://www-128.ibm.com/developerworks/cn/xml/">XML 专区</a>上查找更多的 XML 参考资料。阅读
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-watch/index.shtml"><i>XML 观察</i></a>专栏系列以前的专栏文章。
          <br /><br /><br /><br /></li>
				<li>获取
          <a href="http://www-3.ibm.com/software/info1/websphere/index.jsp?tab=landings/studiosplashv5">IBM WebSphere Studio</a>，它是一套 XML 开发自动化的工具，可以使用 Java 和其它语言进行开发。它与
          <a href="http://www.ibm.com/developerworks/cgi-bin/click.cgi?url=http://www-3.ibm.com/software/webservers/appserv/&amp;origin=x">WebSphere Application Server</a>紧密地集成在一起，而且还可以和其它 J2EE 服务器一起使用。
          <br /><br /><br /><br /></li>
				<li>查找如何成为
          <a href="http://www-128.ibm.com/developerworks/cn/xml/theme/x-cert.html">IBM 认证的 XML 和相关技术的开发人员</a>。
          <br /><br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-rdfprov/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Edd Dumbill 是
        <a href="http://xml.com/">XML.com</a>的执行编辑以及 XML 开发人员新闻站点
        <a href="http://xmlhack.com/">XMLhack</a>的编辑和发行人。他是
        <a href="http://www.oreilly.com/catalog/progxmlrpc/">O'Reilly 的
          <i>Programming Web
Services with XML-RPC</i></a>一书的合著者，以及
        <a href="http://pharmalicensing.com/">Pharmalicensing</a>生命科学知识产权交易事务所的共同创始人和顾问。Edd 还是
        <a href="http://www.xmleurope.com/">每年一度的 XML 欧洲大会</a>的议程主席。您可以通过
        <a href="mailto:edd@xml.com">edd@xml.com</a>与 Edd 联系。
      </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:26 <a href="http://www.blogjava.net/Vencent/articles/35984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 标准概览: 第 4 部分:主要 XML 标准的详细交叉引用</title><link>http://www.blogjava.net/Vencent/articles/35982.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:12:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35982.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35982.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35982.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 级别: 初级						Uche Ogbuji, 首席顾问, Fourthought, Inc.		2004 年  3 月  01 日		XML世界非常庞大，而且还在不断成长，存在大量不同的标准以复杂的方式互相影响。新手很难确定哪些是 XML最重要的方面，用户也难以跟踪这个领域出现的新生事物和变化。XML 是一种基本语法，可用于开发本地或全局的词汇表。Uche Ogbuji...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/35982.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/35982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:12 <a href="http://www.blogjava.net/Vencent/articles/35982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XQuery 简介：W3C 的 XML 查询语言提议标准一瞥</title><link>http://www.blogjava.net/Vencent/articles/35980.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:11:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35980.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35980.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35980.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35980.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#author">Howard Katz</a>, 所有者, Fatdog Software<br /></p>
		<p>2001 年  6 月  01 日<br />2006 年  2 月  06 日  更新 </p>
		<blockquote>Howard
Katz 介绍了 W3C XQuery 规范，该规范目前正在努力成为推荐标准。这个复杂的规范目前包含 15
个不同的工作草案，而且在最终完成之前可能还会增加。本文提供了该规范的一些历史背景、形成文档的路线图和规范当前状态的简单介绍。侧栏简要描述了
XQuery 表层语法的一些主要特性。通过示例代码示范了 XQuery 和 XQueryX 之间的区别，并给出了关于表层语法的例子。
</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>
				<i>
						<b>注意：</b>本文在
2005 年 12 月经过修正，结合了 XQuery 规范的最新变动情况：其中八个工作草案已进入 “W3C 候选推荐标准”
状态，整个规范距离最终成为 “推荐标准” 更近了一步。主要的全文文档最初发表于 2004 年，最近经过了修改。关于更新设施的
“需求工作草案（Requirements Working Draft）” 和建立 XPath/XQuery
词法分析器（tokenizer）的草案都是 2005 年第一次发布的。XQuery 特性的数量继续增长，XQuery 实现者列表和 Web
上的开发人员资源也在不断增加。</i>
		</p>
		<p>沿着成为 W3C 推荐标准的道路走了漫长的六年之后，XQuery
规范颇具好莱坞大片的神秘和不朽色彩，就像 “星球大战” 和 “指环王” 系列一样。XQuery 起源于 1998 年由 W3C
发起的查询语言研讨会，来自工业界、学术界和研究团体的代表聚集到波士顿，提出了 XML 查询语言中他们认为重要的特性和需求。</p>
		<p>
				<a name="h10539">
						<span class="atitle">两个不同的阵营</span>
				</a>
		</p>
		<p>那些对历史感兴趣的人可以在线获取这 66 篇演讲稿（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#resources">参考资料</a>），它们主要来自两大不同的阵营：那些将 XML 主要<i>作为文档</i> 使用的人（在很大程度上反映了 XML 起源于 SGML）和将 XML <i>作为数据</i> 使用的人 —— 后者很大程度上反映了 XML 在中间件领域、前端传统关系数据库领域中不断增长的现状。</p>
		<p>尤
其是俄勒冈州研究生院的 David Maier的演讲稿 “Database Desiderata for an XML Query
Language”，它非常简明扼要，非常有助于了解 Query Language Working
Group（查询语言工作组）的思想，后者是在波士顿讨论会之后不久特许成立的。</p>
		<p>虽然成员时增时减，但按照 W3C
的标准，这个工作组很庞大（据说只有 Protocol Working Group（协议工作组）的成员比它多）。它由 30
多个成员公司构成，反映了数据和文档这两大阵营各自的观点。现在合并而成的最终形式（经过了漫长的时间）是一种 XML 查询语言标准，
能够代表这两个团体的需求和观点。</p>
		<p>对于 XML 用户来说，最熟悉的 XQuery 关键组件是
XPath，它本身也是一个 W3C 规范。单独的 XPath 位置路径本身（“//book/editor” 意味着
“在当前数据集中查找所有图书编辑”）就是完全有效的 XQuery。在数据方面，XQuery 具有类似于 SQL
的外观和能力，这是来自关系数据库世界的用户所欢迎和熟悉的。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h12275">
						<span class="atitle">卑微的出身</span>
				</a>
		</p>
		<p>XQuery
最初称为 Quilt。Quilt 最初作为用户级语法的测试工具，是工作组中三个勤奋而又眼光远大的成员创立的：Jonathan
Robie、Don Chamberlin 和 Daniela Florescu。在定义需求、用例以及底层数据模型和代数方面，Quilt
都建立在整个工作组的协同努力的基础上。</p>
		<p>Robie、Chamberlin 和 Florescu 指出了一些语言对
Quilt 设计的影响，包括 XQL、XML-QL 和 SQL。如果对计算机语言的演化感兴趣，请阅读 “XML Query Language:
Experiences and Exemplars”（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#resources">参考资料</a>），这篇意义重大的论文对前两种语言以及另外两种语言 YaTL 和 Lorel 进行了很好的比较。作者 Mary Fernandez、Jerome Simeon 和 Phil Wadler 本身都是该工作组的成员。</p>
		<p>既然数据和文档团体持有如此不同的的观点，以及工作组所建立的基础的可靠性，这个庞大的规范需要如此长的时间才向大众公布也就不足为奇了。W3C 工作组的内部进展是严格保密的，并且在 2001 年 2 月中旬以前，查询语言工作组的大多数工作都是秘密进行的。</p>
		<p>很
早就发布了 Requirements 文档和 Data Model 工作草案，但是直到 2001 年 2
月，工作组的发布工作才得以进入高潮，那时大量的文档开始出现。此后在 2001 年进行了两次重要更新，以后每年都有三四次更新，只有 2004
年例外，工作组只发布了一次更新。</p>
		<p>今年新增加了更新机制的需求文档，再加上为 XQuery
语言实现者提供的关于建立词法分析器的简短说明，文档总数达到了 16 个（包括由于某种我不清楚的原因也放在 XML Query 网站上的
XSLT 规范），不用很长时间就会组成一套完整的文档集。肯定会在某个时候出现一种更新语言文档。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h14408">
						<span class="atitle">新生的发布王国</span>
				</a>
		</p>
		<p>完全用于描述和定义 XQuery 的文档目前包括：</p>
		<dl>
				<dt>
						<b>
								<b>XML Query Requirements</b>
						</b>
				</dt>
				<dd>工作组的主要规划文档。XQuery 需求列表。</dd>
				<dt>
						<b>
								<b>XML Query Use Cases</b>
						</b>
				</dt>
				<dd>一些实际场景和解决特定问题的 XQuery 片段。</dd>
				<dt>
						<b>
								<b>XQuery 1.0: An XML Query Language</b>
						</b>
				</dt>
				<dd>核心文档，介绍语言本身，以及对大多数其他内容的概述。</dd>
				<dt>
						<b>
								<b>XQuery 1.0 and XPath 2.0 Data Model</b>
						</b>
				</dt>
				<dd>XML 信息集的扩展。描述查询实现必须理解的数据项和形式语义的基础。</dd>
				<dt>
						<b>
								<b>XQuery 1.0 and XPath 2.0 Formal Semantics</b>
						</b>
				</dt>
				<dd>从形式上定义语言的底层代数。</dd>
				<dt>
						<b>
								<b>XML Syntax for XQuery 1.0 (XQueryX)</b>
						</b>
				</dt>
				<dd>为喜欢使用 XML 的人（主要是计算机）提供的另一种语法。</dd>
				<dt>
						<b>
								<b>XQuery 1.0 and XPath 2.0 Functions and Operators Version 1.0</b>
						</b>
				</dt>
				<dd>XML Schema 数据类型、 XML 节点及其序列的大约 225 个函数和操作符。</dd>
				<dt>
						<b>
								<b>XML Path Language (XPath) 2.0</b>
						</b>
				</dt>
				<dd>单独分离出来的 XPath 文档。</dd>
				<dt>
						<b>
								<b>XPath Requirements Version 2.0</b>
						</b>
				</dt>
				<dd>XPath 的需求文档。</dd>
				<dt>
						<b>
								<b>XSLT 2.0 and XQuery 1.0 Serialization</b>
						</b>
				</dt>
				<dd>对从 XQuery 1.0 和 XPath 2.0 Data Model 输出序列化<i>尖括号</i> 有关的 XML 问题的考察。序列化<i>本质上</i> 不是主语言规范的一部分。</dd>
				<dt>
						<b>
								<b>XML Query and XPath Full-Text Requirements</b>
						</b>
				</dt>
				<dd>描述 Full-Text Recommendation 需要达到的功能需求。</dd>
				<dt>
						<b>
								<b>XML Query and XPath Full-Text Use Cases</b>
						</b>
				</dt>
				<dd>Full-Text 规范应该能够处理的实际场景。</dd>
				<dt>
						<b>
								<b>XQuery 1.0 and XPath 2.0 Full-Text</b>
						</b>
				</dt>
				<dd>主 full-text 文档，详细描述严格意义上的 XQuery 的全文扩展语言。</dd>
				<dt>
						<b>
								<b>XQuery Update Facility Requirements</b>
						</b>
				</dt>
				<dd>XQuery 要求的能够对已有文档写入新数据以及对文档进行查询的功能。</dd>
				<dt>
						<b>
								<b>Building a Tokenizer for XPath or XQuery </b>
						</b>
				</dt>
				<dd>工作草案注释文件，选择了主 XQuery 1.0 文档中的一些语法资料进行解释。只对语言的实现者有意义。</dd>
		</dl>
		<p>这些文档（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#resources">参考资料</a>）
代表了大量工作。“XQuery 1.0: An XML Query Language” 是其中的关键，但其他文档也为 XQuery
成为良好的规范和全面支持的语言作出了贡献。据我所知，这是出自 W3C 的最复杂的一套规范（虽然 XML Schema
或许可与之相比，但那又是另一回事了）。 </p>
		<p>如果您对如此之多的文档感到惊讶和不知道从何处着手，我可以推荐两种方法。可以从核心的 XQuery 1.0
文档开始。它有一个很好的介绍性概述，详细介绍了该语言的很多特性。另一种方法是从选择一个 Use Cases 工作草案开始。该文档列举了
XQuery 能够发挥作用的一些实际场景。每个用例都针对特定的应用领域，并列出了用于该领域示例数据的一些 XQuery
代码。如果希望看到实际语法的具体例子，这些代码片段是非常有价值的。第三种方法是研究 Functions and Operators
工作草案中列出的很多内置函数，但采用这种方法最好对语言要有基本的理解。</p>
		<p>最近几年关于这个领域出现了两本很好的图书，阐释
了该规范的各种细节，都是 Addison-Wesley 出版的：“XQuery from the Experts”
收集了来自该工作组成员的一些关于 XQuery 的技术文章，而 “XQuery: The XML Query Language” 则是
Microsoft 的 Michael Brundage 撰写的必读参考书（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#resources">参考资料</a>）。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h16788">
						<span class="atitle">BabelFish，您在哪儿？</span>
				</a>
		</p>
		<p>XQuery 实际上是三种语言合为一体：</p>
		<ul>
				<li>
						<b>表层语法</b>是其中最容易看到的语言，也是用户最可能接触到的。从很多方面来说，这个语言版本<i>就是</i> XQuery。（参阅侧栏 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#sidebar">语法：一个简单的例子</a> 中关于表层语法的例子。） </li>
				<li>
						<b>一种基于 XML 的替代语法</b>用另一种更便于机器处理的语言代替了表层语言。（参阅本文后面的 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#h21862">XQueryX</a>。）</li>
				<li>
						<b>形式代数语言</b>详细描述了 XQuery 处理程序的内部工作机制。</li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h17538">
						<span class="atitle">底层的形式主义</span>
				</a>
		</p>
		<p>Data Model and Formal Semantics（数据模型和形式语义）工作草案共同为 XQuery 提供了精确的理论基础。这两个文档详细介绍了查询<i>代数</i>，这是用形式术语定义的一组精确定义，它定义了 XQuery 查询期望操作的核心实体以及各种语言操作符怎样使用那些操作数的公式。除非是查询引擎的实现者、有充足的经费保障或者单纯喜欢复杂的形式系统，否则不会对它感兴趣。</p>
		<p>提供了一个让实现者能够将表面语法特性直接重新造型为底层代数的映射。正如一些厂商在 XML 商业展示会上所展示的那样，可以实现实际上与代数直接沟通的查询处理程序（虽然我认为这更多的是概念证明性的）。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#resources">参考资料</a> 中有一个链接指向其中一个基于代数的引擎的在线演示版本。</p>
		<p>代数还提供了详细描述如何将复杂表达式优化及转变成更简单的等价形式的规则。我只能说（我不是语言学家，并且形式语义文档读起来并不轻松），它们都是好东西。特别是大型数据库供应商会赞赏一种从头开始设计并且经过优化而高效的查询语言结构。</p>
		<p>代数还提供了附加类型信息的位置。XQuery 是强类型的：如果数据有相关的 XML Schema，处理程序就可以按照模式进行验证、并为查询引擎提供文档中节点数据类型的<i>后模式验证信息集（PSVI）</i>信
息，同时利用 “XML Schema Part 2: Datatypes”
中声明的类型和自定义的用户定义类型。代数同时具有静态和动态类型检查能力。比方说，引擎可以使用 PSVI
派生的类型信息在编译时静态地检查查询表达式的数据类型（分析查询的语法正确性时）。在这个周期中尽早地确定类型无效的查询，这样能够大大减少对大型数据
集进行很可能是昂贵的（和无结果的）搜索的需要。XQuery 规范中涉及到语言的语法和语义的大部分工作都与类型有关。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h19963">
						<span class="atitle">迁移到 XPath 2.0</span>
				</a>
		</p>
		<p>XQuery
和 XPath 2.0 具有同样的公共数据模型，有点奇怪的数据模型文档标题也反映了这一点：“XQuery 1.0 and XPath 2.0
Data Model”（这也是工作组开始使用缩写词 XDM 表示数据模型的原因）。XPath 2.0 现在已经完全成熟。该数据模型描述了
XPath 处理程序所关心的 XML 文档中的核心信息，XPath step 操作的最终语法和语义基本上已经完成。全部规范为 Query
Language 工作组和 XSL 工作组共同所有，这两个工作组需要对 XPath 2.0
的未来达成一致。不论在政治上还是在技术上，这常常会带来挑战。不过，即便取得一致意见的道路崎岖不平，这两个工作组看来并没有表现出有多么不协调（至少
在外人眼里如此）。</p>
		<p>为了说明从 XPath 1.0 转移到 2.0 的意义，仅仅举一个例子：XPath 1.0
是基于集合的表达式语言。XPath 1.0 的 4
种数据类型之一，节点集，仅仅是集合而已。按照定义，集合是无序的并且不含重复成员。另一方面，XPath 2.0
却是以序列为基础的。相比而言，XPath 2.0 中节点的序列（毫不奇怪，相应地被称为<i>节点序列</i>）是有序的，并且允许重复。用行话来说，这些差异的分歧存在于许多问题中，工作组需要独立和协作找出这些问题来，以便使他们都能够与 XPath 2.0 协调一致。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10187">
						<span class="atitle">我们现在在何处？</span>
				</a>
		</p>
		<p>所有实质性的遗留问题都已经解决。组成 XQuery 的七个关键文档按 W3C 的说法成为了 “候选推荐标准”，这意味着，用正式的术语来说，XQuery 现在被认为 “是稳定的且合适于实现”。</p>
		<p>按
照正式的 W3C 推荐标准工作流程，以上 Last Call 阶段中提出的所有问题都已得到响应，工作组现在正寻找工业厂商去实际验证
XQuery
的主要特性是可实现的。为此，实现者必须对工作组提供的测试套件运行其实现。那些在候选推荐标准阶段没有被两个或更多厂商实现的特性，就有可能被从规范中
删除。当前有风险的特性包括：</p>
		<ul>
				<li>静态类型化</li>
				<li>模块</li>
				<li>集合</li>
				<li>静态类型化</li>
				<li>普通的 XML 嵌入</li>
				<li>复制名称空间（Copy-namespace）声明</li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h21862">
						<span class="atitle">XQueryX</span>
				</a>
		</p>
		<p>XQueryX 是一种替代表层语言的基于 XML 语法的规范，也是较早加入 XQuery 文档家族的文件之一。XQuery 需求中有一条指出多种语法是<i>允许的</i>，看来工作组似乎是在两面下注：一种格式必须方便人类读写，另一种则要求能够用 XML 表达。XQueryX 是工作组对后一种需求的答案。</p>
		<p>基于 XML 的查询表是具备 XML 所有显而易见、众所周知的优点：很容易使用标准工具解析、生成和询问查询的内容。这样做可能很有用，比方说，如果正在进行源代码级的优化或转换，就可能需要方便地检查查询中是否具有特定语法结构的能力。XML 非常适合这类工作。</p>
		<p>XQueryX 基本上是该语言的形式语法到 XML 的一对一映射。由于语法的复杂性，使得 XQueryX <i>非常</i> 冗长，基本上无法阅读。所幸的是，该语言的目标受众 —— 机器 —— 不会对此抱怨。清单 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing1">1</a> 和 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing2">2</a> 提供了分别用标准 XQuery 语法和 XQueryX 语法表示的简单查询表达式。要注意像类固醇一样的膨胀因子。</p>
		<br />
		<a name="listing1">
				<b>清单 1. 标准语法表示的简单查询</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />				&lt;bib&gt;<br /> {<br />  for $b in doc("http://bstore1.example.com/bib.xml")/bib/book<br />  where $b/publisher = "Addison-Wesley" and $b/@year &gt; 1991<br />  return<br />    &lt;book year="{ $b/@year }"&gt;<br />     { $b/title }<br />    &lt;/book&gt;<br /> }<br />&lt;/bib&gt;</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing2">清单 2</a> 显示了等价的 XQueryX 查询。因为太长，省略了大约四分之三的篇幅。XQueryX 工作草案中的完整清单有 132 行之多：</p>
		<br />
		<a name="listing2">
				<b>清单 2. XQueryX 格式的查询（片段）</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />				&lt;?xml version="1.0"?&gt;<br />&lt;xqx:module xmlns:xqx="http://www.w3.org/2005/XQueryX" ... &gt;<br />  &lt;xqx:mainModule&gt;<br />    &lt;xqx:queryBody&gt;<br />      &lt;xqx:elementConstructor&gt;<br />        &lt;xqx:tagName&gt;bib&lt;/xqx:tagName&gt;<br />        &lt;xqx:elementContent&gt;<br />          &lt;xqx:flworExpr&gt;<br />            &lt;xqx:forClause&gt;<br />              &lt;xqx:forClauseItem&gt;<br />                &lt;xqx:typedVariableBinding&gt;<br />                  &lt;xqx:varName&gt;b&lt;/xqx:varName&gt;<br />                &lt;/xqx:typedVariableBinding&gt;<br />                &lt;xqx:forExpr&gt;<br />                  &lt;xqx:pathExpr&gt;<br />                    &lt;xqx:argExpr&gt;<br />                      &lt;xqx:functionCallExpr&gt;<br />                        &lt;xqx:functionName&gt;doc&lt;/xqx:functionName&gt;<br />                        &lt;xqx:arguments&gt;<br />                          &lt;xqx:stringConstantExpr&gt;<br />                            &lt;xqx:value&gt;http://bstore1.example.com/bib.xml&lt;/xqx:value&gt;<br />                          &lt;/xqx:stringConstantExpr&gt;<br />                        &lt;/xqx:arguments&gt;<br />                      &lt;/xqx:functionCallExpr&gt;<br />                    &lt;/xqx:argExpr&gt;<br />                    &lt;xqx:stepExpr&gt;<br />                      &lt;xqx:xpathAxis&gt;child&lt;/xqx:xpathAxis&gt;<br />                      &lt;xqx:nameTest&gt;bib&lt;/xqx:nameTest&gt;<br />                    &lt;/xqx:stepExpr&gt;<br />                    &lt;xqx:stepExpr&gt;<br />                      &lt;xqx:xpathAxis&gt;child&lt;/xqx:xpathAxis&gt;<br />                      &lt;xqx:nameTest&gt;book&lt;/xqx:nameTest&gt;<br />                    &lt;/xqx:stepExpr&gt;<br />                  &lt;/xqx:pathExpr&gt;<br />                &lt;/xqx:forExpr&gt;<br />              &lt;/xqx:forClauseItem&gt;<br />            &lt;/xqx:forClause&gt;<br />			...</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="h25664">
						<span class="atitle">准备就绪，然后该何去何从？</span>
				</a>
		</p>
		<p>2001
年 6 月，就在第一次重要的发布迭代之后，在我第一次撰写关于已有 XQuery 实现的总结文章时，当时还只有两种实现：我自己很早的一种实现和
Microsoft
的实现。于是我给自己找了点乐子，开玩笑说比尔盖茨和我成了市场竞争中的赛马师。那个时代已经过去了，经过四年和发布了更多工作草案之后，那个玩笑已经过
时了。现在差不多有四五十种实现了，还有大量的相关产品和工具。</p>
		<p>如果要寻找一个实现，最好的地方就是 XML Query 主页（参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#resources">参考资料</a>）。这个列表更新很快，随着兴趣和动机不断增强，随着规范越来越接近推荐标准状态，我预料将会不断出现新的实现。</p>
		<br />
		<a name="sidebar">
				<b>语法：一个简单的例子</b>
		</a>
		<br />
		<table border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<p>让我们通过实际的例子快速看一下 XQuery 的一些特性。下面是一个非常简单的查询，操作 Use Cases 文档中的规范示例文件。该查询展示了 XQuery <i>投影</i>（在数据集中选择与所定标准匹配的节点子集）和<i>转换</i>（生成与正被查询的文档不同的输出文档）的能力。XQuery 允许在一个查询中同时指定要搜寻的内容和输出格式。</p>
										<p>
												<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing3">清单 3</a> 显示了查询操作的文档的片段：</p>
										<br />
										<a name="listing3">
												<b>清单 3. 查询操作的文档片段</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />       &lt;bib&gt;<br />          &lt;book year="1994"&gt;<br />             &lt;title&gt;TCP/IP Illustrated&lt;/title&gt;<br />             &lt;author&gt;&lt;last&gt;Stevens&lt;/last&gt;&lt;first&gt;W.&lt;/first&gt;&lt;/author&gt;<br />             &lt;publisher&gt;Addison-Wesley&lt;/publisher&gt;<br />             &lt;price&gt;65.95&lt;/price&gt;<br />          &lt;/book&gt;<br />          &lt;book year="1992"&gt;<br />             &lt;title&gt;Advanced Programming in the Unix environment&lt;/title&gt;<br />             &lt;author&gt;&lt;last&gt;Stevens&lt;/last&gt;&lt;first&gt;W.&lt;/first&gt;&lt;/author&gt;<br />             &lt;publisher&gt;Addison-Wesley&lt;/publisher&gt;<br />             &lt;price&gt;65.95&lt;/price&gt;<br />          &lt;/book&gt;<br />          &lt;book year="2000"&gt;<br />             &lt;title&gt;Data on the Web&lt;/title&gt;<br />             &lt;author&gt;&lt;last&gt;Abiteboul&lt;/last&gt;&lt;first&gt;Serge&lt;/first&gt;&lt;/author&gt;<br />             &lt;author&gt;&lt;last&gt;Buneman&lt;/last&gt;&lt;first&gt;Peter&lt;/first&gt;&lt;/author&gt;<br />             &lt;author&gt;&lt;last&gt;Suciu&lt;/last&gt;&lt;first&gt;Dan&lt;/first&gt;&lt;/author&gt;<br />          &lt;/book&gt;<br />              ...<br />       &lt;/bib&gt;</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
										<p>现在希望得到 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing4">清单 4</a> 所示的输出文档（经过一点美化）：</p>
										<br />
										<a name="listing4">
												<b>清单 4. 输出文档</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />       &lt;results&gt;<br />          &lt;book authorCount="1"&gt;<br />             &lt;author&gt;Stevens&lt;/author&gt;<br />          &lt;/book&gt;<br />          &lt;book authorCount="1"&gt;<br />             &lt;author&gt;Stevens&lt;/author&gt;<br />          &lt;/book&gt;<br />          &lt;book authorCount="3"&gt;<br />             &lt;author&gt;Abiteboul&lt;/author&gt;<br />             &lt;author&gt;Buneman&lt;/author&gt;<br />             &lt;author&gt;Suciu&lt;/author&gt;<br />          &lt;/book&gt; <br />              ...<br />       &lt;/results&gt;</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
										<p>下面就是查询本身。它的任务是扫描查询文档中的所有图书，生成上面所显示的结果文档：在输出的每个新建 <code>&lt;book&gt;</code> 标记中包含计算出的 <code>authorCount</code> 属性；并丢弃原始文档中其他大部分信息，只保留每位作者的姓。</p>
										<p>（注意，我在这里使用了术语 “查询文档”（单数）。这是一种简化，XQuery 数据模型也能处理文档集合以及文档片段。）</p>
										<br />
										<a name="listing5">
												<b>清单 5. 扫描查询文档中所有图书的查询</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />   &lt;results&gt;<br />   {<br />      for $book in doc( "http://uri-for-book-dataset" )//book<br />      let $authors := $book/author<br />      return<br />         &lt;book authorCount="{ count($authors) }"&gt;<br />         {<br />            for $author in $authors<br />            return<br />               &lt;author&gt;{ $author/last/text() }&lt;/author&gt;<br />         }<br />         &lt;/book&gt;<br />   }<br />   &lt;/results&gt;</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
										<p>
												<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing5">清单 5</a> 中，使用 <code>doc()</code> 函数使查询指向要查找的 XML 文档。它返回 XQuery 和 XPath 数据模型（XDM）词汇表中的 <code>文档节点</code>。</p>
										<p>
												<b>
														<a name="h35839">剖析查询</a>
												</b>
										</p>
										<p>下面是该查询的一些有趣特性：</p>
										<p>
												<b>
														<a name="h36000">for/let 表达式</a>
												</b>
										</p>
										<p>该示例包含两个嵌套的 <code>for</code> 循环和一个 <code>let</code>。外层的 <code>for</code> 循环遍历扩展路径表达式 <code>doc(...)//book</code> 得到的每个节点，并将每个 <code>&lt;book&gt;</code> 节点分别放到名为 <code>$book</code> 的变量中。<code>let</code> 表达式选择每本书的所有 <code>&lt;author&gt;</code> 子节点，并放到名为 <code>$authors</code> 的变量中。<code>$authors</code> 变量保存节点<i>序列</i>，<code>$book</code> 和 <code>$author</code> 变量都包含一个节点。</p>
										<p>请务必留意，这些变量不是<i>赋值的</i> 而是<i>绑定的</i>。差别细微但很重要：变量一旦绑定，它的值就不可更改。这可以防止在运行中对变量重新赋值而造成糟糕的负面影响。另一个潜在的好处是，（在某种程度上）可以在处理期间重排包含变量的行，从而允许智能引擎优化它们的查询。
</p>
										<p>
												<code>for</code> 和 <code>let</code> 表达式是 <code>FLWOR</code>（读作 <i>flower</i>）表达式的子组件。这个缩写词代表其五个主要的成分子句：<code>for</code>-<code>let</code>-<code>while</code>-<code>order by</code>-<code>return</code>。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing6">清单 6</a> 中，<code>FLWOR</code> 表达式的形式语法为：</p>
										<br />
										<a name="listing6">
												<b>清单 6. 带有 for 和 let 子成分的 FLWOR 表达式</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />FLWORExpr ::= (ForClause | LetClause)+ WhereClause? "return" Expr</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
										<p>表明这是一个变化非常多的表达式类型，能够生成大量可能的查询实例。正如该生成所显示的那样，<code>"return"</code> 关键字后面的 <code>Expr</code> 项本身可以被另一个 <code>FLWOR</code> 表达式替代，因此，可以像不断加长的 LEGO 积木那样，将 <code>FLWOR</code> 表达式首尾相接，<i>无限</i> 地排成一行。能够用任何其他表达式类型替换 <code>Expr</code> 项，使 XQuery 具有<i>可组合性</i> 并给予它丰富的表达能力。XQuery 中有大量表达式类型，每一种可以插入需要更一般的 <code>Expr</code> 的地方。</p>
										<p>一般来说，最终会有一个 <code>return</code> 语句结束 <code>FLWOR</code> 序列。在上面的例子中，增加的内部 <code>return</code> 是为了方便插入要输出的每个 <code>&lt;book&gt;</code> 的元素构造器。
</p>
										<p>
												<b>
														<a name="h38524">元素构造器</a>
												</b>
										</p>
										<p>这个查询包含三个元素构造器。通过将文字尖括号 XML 直接写入查询本身的正文中，在查询过程中动态生成元素 <code>&lt;results&gt;</code>、<code>&lt;book&gt;</code> 和 <code>&lt;author&gt;</code>。</p>
										<p>在需要区分文字文本内容和元素构造器中需要计算的子表达式时，使用花括号（<code>{</code> 和 <code>}</code>）。比方说，如果我们编写 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing7">清单 7</a> 所示的文字表达式则不需要用花括号来分隔内部标记和外部标记。
</p>
										<br />
										<a name="listing7">
												<b>清单 7. 用括号区分内部和外部标记的代码</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />   &lt;authors&gt;<br />       &lt;author&gt;<br />          ...</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
										<p>顺便提一句，花括号是在 2001 年 7 月修订表面语言语法时引入的。更早版本的语法不需要花括号。花括号是语言在成为推荐标准过程中不断修改和演化的一个好例子。</p>
										<p>
												<b>
														<a name="h39444">属性构造器</a>
												</b>
										</p>
										<p>
												<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing8">清单 8</a> 中的代码显示了行内属性构造器的用法。<code>count()</code> 函数返回每本书中包含的 <code>&lt;author&gt;</code> 元素的个数。也要注意这里的花括号，用于将需要计算的表达式和周围的文字 XML 分开。在属性构造器中使用引号分隔属性值是规范演变过程中不断修改的另一个例子。</p>
										<br />
										<a name="listing8">
												<b>清单 8. 使用行内属性构造器</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />&lt;book authorCount="{ count($authors) }" &gt;</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
										<p>
												<b>
														<a name="h39905">内置函数和运算符</a>
												</b>
										</p>
										<p>
												<code>count()</code> 是内置函数的一个例子。“Functions and Operators” 草案列出了大约 12 类 225 种函数和运算符，用于构造和操作各种不同的数据类型，包括数字、字符串、布尔值、日期时间、qname、节点和序列。</p>
										<p>
												<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#listing9">清单 9</a> 中的表达式通过 <code>text()</code> 运算符，使用从包围它的 <code>&lt;last&gt;</code> 元素中提取的姓氏来填充每个 <code>&lt;author&gt;</code> 元素的内容。如果直接使用 <code>$author/last</code>，将同时得到包围的标记，这不是本例所希望的情况。</p>
										<br />
										<a name="listing9">
												<b>清单 9. 使用内置运算符 text()</b>
										</a>
										<br />
										<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td>
																		<pre>
																				<code class="section">
																						<br />
																						<br />&lt;author&gt;{ $author/last/text() }&lt;/author&gt;</code>
																		</pre>
																</td>
														</tr>
												</tbody>
										</table>
										<br />
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/xml/library/x-xquery.html" target="_blank">英文原文</a>。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xmlquery-req">XML Query Requirements</a>：工作组规划文档；XQuery 需求列表。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xmlquery-use-cases">XML Query Use Cases</a>：一些实际场景和解决特定问题的 XQuery 代码片段。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xquery/">XQuery 1.0: An XML Query Language</a>：核心文档，详细介绍了表层语言并对所有其他内容作了概述。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/query-datamodel/">XQuery 1.0 and XPath 2.0 Data Model</a>：XML 信息集的扩展。描述了查询实现需要处理的数据项。现在被称为 XDM。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/query-semantics/">XQuery 1.0 and XPath 2.0 Formal Semantics</a>：形式定义查询引擎行为的底层代数。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xqueryx">XML Syntax for XQuery 1.0 (XQueryX)</a>：另一种查询 XML 语法，主要用于机器。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xpath20/">XML Path Language (XPath) 2.0</a>：从 XQuery 中分离出来的 XPath 2.0 规范。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xquery-operators/">XQuery 1.0 and XPath 2.0 Functions and Operators</a>：大约有 225 个。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xslt-xquery-serialization/">XSLT 2.0 and XQuery 1.0 Serialization</a>：对于如何产生尖括号 XML 的官方说明。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xquery-full-text-requirements/">XQuery and XPath Full-Text Requirements</a>：XQuery 全文子语言的要求。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xmlquery-full-text-use-cases/">XQuery and XPath Full-Text Use Cases</a>：全文的实际场景。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xquery-full-text/">XQuery 1.0 and XPath 2.0 Full-Text</a>：严格 XQuery 的全文语言扩展。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xpath20req/">XPath Requirements Version 2.0</a>：XPath 的需求文档。 <br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/2005/WD-xquery-update-requirements-20050211/">XQuery Update Facility Requirements</a>：XQuery 要求能够向已有文档写入新数据以及查询文档的能力。 <br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/2005/WD-xquery-xpath-parsing-20050404/">Building a Tokenizer for XPath or XQuery</a>：选择主 XQuery 1.0 文档中的一些语法材料加以阐释的工作草案注释文件。只对语言的实现者有意义。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/1999/09/ql/docs/xquery.html">XML Query Languages: Experiences and Exemplars</a>：该文通过分析已有的四种查询语言确定了 XML 查询语言的基本特性：XML-QL、YATL、Lorel 和 XQL。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Part 2: Datatypes</a>：XQuery 能够理解的数据类型。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TandS/QL/QL98/">QL98: Query Languages Workshop</a>：最初有关查询语言的波士顿讨论会的 W3C Web 站点。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TandS/QL/QL98/pp/maier.html">Database Desiderata for an XML Query Language</a>：David Maier 在研讨会上的演讲稿。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/NOTE-xml-ql/">XML-QL: A Query Language for XML</a>，Deutsch、Fernandez、Florescu、Levy 和 Suciu：对 XQuery 的影响。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TandS/QL/QL98/pp/xql.html">XML Query Language: A Proposal</a>，Robie、Lapp 和 Schach：向 W3C 提议 XQL。<br /><br /></li>
				<li>
						<a href="http://www.almaden.ibm.com/cs/people/chamberlin/quilt.html">Quilt</a>：Robie、Florescu 和 Chamberlin 所主持的关于这个 XQuery 前身的网站。<br /><br /></li>
				<li>
						<a href="http://www.amazon.com/gp/product/0321165810/qid=1134399655/sr=2-1/ref=pd_bbs_b_2_1/002-7778900-8319213?s=books&amp;v=glance&amp;n=283155">"XQuery: The XML Query Language"</a> (Addison-Wesley, 2004)：Michael Brundage 撰写的语言参考。<br /><br /></li>
				<li>
						<a href="http://www.amazon.com/gp/product/0321180607/qid=1134399655/sr=2-2/ref=pd_bbs_b_2_2/002-7778900-8319213?s=books&amp;v=glance&amp;n=283155">"XQuery from the Experts"</a> (Addison-Wesley, 2003)：XML Query 工作组成员撰写的有关 XQuery 技术文章的纲要汇编。<br /><br /></li>
				<li>
						<a href="http://www.saxonica.com/products.html">Saxon</a>：Michael Kay 开发的被广泛采用的开放源码 XSLT 处理器，现在增加了 XQuery。有人称之为这种语言的<i>权威</i>考实现。<br /><br /></li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
						<a href="http://www.galaxquery.org/">Galax</a>：Bell 实验室 Jerome Simeon 的基于形式语义的查询引擎演示。“形式语义” 是现在对 2001 年 6 月 7 日之前所说 “代数” 的正式称呼。<br /><br /></li>
				<li>
						<a href="http://sourceforge.net/projects/xqengine">XQEngine</a>：作者自己基于 Java 的开放源码查询引擎。现在有点落后了，因为至少目前作者放弃了跟踪规范的修改。<br /><br /></li>
				<li>
						<a href="http://www.marklogic.com/">Mark Logic Content Server</a>：（部分）领先的图书出版商都使用这个包。可以免费存储和查询 50 MB 的内容。<br /><br /></li>
				<li>
						<a href="http://www.sleepycat.com/products/bdbxml.html">Berkeley DB XML</a>：Sleepycat 的开放源码原生 XML 数据库，以令人尊敬的、高可伸缩性的 Berkeley DB 数据库引擎为基础。<br /><br /></li>
				<li>IBM 的 <a href="http://www.ibm.com/software/data/db2/extenders/xmlext/index.html">DB2 Extender 页面</a> 简要介绍了 DB2 如何处理 XML，包含查询 XML 白皮书的链接，可以查看 PDF 文件，或者去 <a href="http://www.ibm.com/software/data/db2/extenders/xmlext/downloads.html">DB2 Extender 下载</a>。</li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xquery.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Howard
Katz 生活在加拿大BC省的 Roberts Creek，他是 Fatdog Software 公司的所有者，该公司专门开发 XML
文档搜索软件。他是 XQEngine 的作者，这是一种基于 Java 的开放源码 XQuery 引擎。近 35
年来他一直是一位活跃的程序员（一直业绩良好），并长期为计算机行业刊物撰写技术文章。他曾为 Microsoft 撰写一个在线 Java 专栏，为
Apple 每月撰写一期关于面向对象编程的专栏文章。他曾任 “温哥华 XML 开发者协会”
的主持人。他和妻子夏天去海上划船，冬天去边远地区滑雪。您可以通过 <a href="mailto:howardk@fatdog.com">howardk@fatdog.com</a> 与 Howard 联系。</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:11 <a href="http://www.blogjava.net/Vencent/articles/35980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML 标准概览: 第 3 部分：最重要的词汇表</title><link>http://www.blogjava.net/Vencent/articles/35981.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 13:11:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35981.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35981.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35981.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35981.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#author">Uche Ogbuji</a>, 首席顾问, Fourthought, Inc.<br /></p>
		<p>2004 年  3 月  01 日</p>
		<blockquote>XML
世界非常庞大，而且还在不断成长，存在大量不同的标准以复杂的方式互相影响。新手很难确定哪些是 XML
最重要的方面，用户也难以跟踪这个领域出现的新生事物和变化。XML 是一种基本语法，可用于开发本地或全局的词汇表。XML
成功的关键就在于一些非常重要的数据格式定义成了 XML 词汇表。本文中，Uche Ogbuji 将介绍其中最重要的一些词汇表。</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>XML
变得越来越强大，得到了迅速的发展。它已经证明自己是一种非常有价值的技术，但可能也是一种令人害怕的技术，如果考虑到挂在“XML”一词下面不断变化的
各个部分。在这一组文章中，我将简述我认为最重要的 XML 技术，讨论它们如何在 XML
世界中更大的范围内彼此融合。为了进一步研究和学习以使用各种技术，我还推荐了一些教程和其他有用的参考资料。</p>
		<p>这里介绍的所有技术都是
        <b>标准</b>，尽管这个词本身就有点捉摸不定。标准有各种各样的形式，而且在同一个领域中常常有多种标准互相竞争。我按照实践的方法把标准定义为：被不同的供应商大量采用的或者有影响、独立于供应商的组织推荐的规范。
      </p>
		<p>在
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/" target="_new">本系列的第一篇文章</a>中主要讨论了核心 XML 技术。（关于各种标准开发团体的概述以及标准的分类请参阅
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml#sidebar1" target="_new">那篇文章中的侧栏</a>。）

        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/" target="_new">第二篇文章</a>中
探讨了和开发人员处理 XML 有关的标准。本文中我将介绍最重要的一些 XML 应用（也称为词汇表，虽然不很准确）。和原来的 SGML
一样，XML 也是一种元语言，是定义其他语言的语法基础。这些语言（如 SGML 中的 HTML，XML 中的 XHTML）是 <b>应用</b>——不要与程序员编写的应用程序（软件应用）如 IBM DB2 混淆。
      </p>
		<p>在第 4 部分，我将就以前所述的这些信息加以比较，提供一个方便的交叉索引。</p>
		<p>
				<a name="IDAYESRB">
						<span class="atitle">XHTML</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xhtml1/">XHTML 1.0</a>
				</b>[W3C 推荐标准]基本上是对 HTML 4 的改写，使其成为结构良好的 XML。HTML 是一种 SGML 应用，当 XML 作为对 SGML 在 Web 应用上的简化和规范化开发出来的时候，HTML（本身是 Web 上的
        <i>通用语言</i>）
就成为采用 XML 的首选目标。于是出现了 HTML 的一种变体，称为 XHTML。XHTML 研究的目标是一种更容易解析（因为 XML
的语法更加严格）的 HTML 语言。XHTML 很容易用现成的 XML 工具处理，力求更好地分离内容与表示。XHTML 是最古老的 XML
应用之一，有许多利益集团在不同的部分和版本中起过作用。我将尽力对其中的大部分加以概括。 </p>
		<p>与三种HTML 4 DTD——
        <b>Strict</b>、
        <b>Transitional</b>和
        <b>Frameset</b>对应，XHTML 1.0 定义了不同的 DTD 和名称空间。
        <b><a href="http://www.w3.org/TR/xhtml-modularization">Modularization of XHTML</a></b>[W3C
推荐标准]提供了一个框架，把 XHTML 分解成单独的模块，作为不同的 DTD
定义。比如，用于定义列表的所有元素和属性组成一个模块，而和表示有关的元素类型则放在另一个模块中。这样，就可以通过增加、减少和修改通用的独立模块开
发和重新定义 XHTML。沿着这条路线，第一步就是 <b><a href="http://www.w3.org/TR/xhtml-basic/">XHTML Basic</a></b>[W3C 推荐标准]，它定义了任何作为 XHTML 的语言都必须具有的最小 XHTML 模块集。XHTML Basic 本身可以作为 Web 客户的内容语言，如移动电话、PDA、寻呼机和置顶盒。
        <b><a href="http://www.w3.org/TR/xhtml11/">XHTML 1.1</a></b>[W3C 推荐标准]基本上就是使用模块框架分解的 XHTML 1.0 Strict DTD。
      </p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xhtml2/">XHTML 2.0</a>
				</b>[开发中]是对 XHTML 的重写，没有考虑与 HTML 的向后兼容。这种想法差不多就是为 Web 编写一种全新的内容语言，学习过去的经验而又不束缚于过去。其中大的变化有：
      </p>
		<ul>
				<li>取消了 
          <code>&lt;br/&gt;</code> 、 
          <code>&lt;img/&gt;</code> 以及其他认为过于面向表示的元素
        </li>
				<li>取消 HTML 风格的表单，改为支持 XForm（本系列文章
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/index.shtml">前已述及</a>）
        </li>
				<li>取消 HTML 风格的链接改为 HLink（本系列文章中
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml">前已述及</a>）
        </li>
				<li>用 XML Event 代替许多 JavaScript 驱动的动态任务</li>
				<li>用 XFrame 代替 HTML 风格的框架</li>
		</ul>
		<p>更重要的是，XHTML 2.0 做了许多扩展,增强了作者表达内容结构和含义的能力。打破向后兼容性引起了争议。一些评论者认为保持 (X)HTML 的名称只修改版本号会造成混乱。其他人则说这些修改非常必要，而 XHTML 实际上仍然是一种
        <i>可扩展超本文标记语言</i>，因此保留原来的名称非常合适。
      </p>
		<p>XHTML 常常和其他嵌入格式一起使用，如 MathML、RDF、SVG、SMIL 和 VoiceXML（后面都将予以介绍）。这种混合文档称为
        <b>多模的</b>或者
        <b>非单体的</b>。W3C、ISO 以及其他组织正投入巨大的努力鼓励对这种文档的强力支持。
      </p>
		<p>
				<a name="IDAHHSRB">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Sathyan Munirathinam 的 “
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/index.shtml">XHTML：两种语言的力量</a>”（
          <i>developerWorks</i>，2002 年 7 月），以及 Molly Holzschlag 撰写的 “
          <a href="http://www.ibm.com/developerworks/web/library/w-xhtml.html">XHTML 1.0: Marking up a new dawn</a>”（
          <i>developerWorks</i>，2000 年 10 月），提供了 XHTML 1.0 的简要介绍。
        </li>
				<li>Nicholas Chase 的 “
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/index.shtml">Web 的未来：XHTML 2.0</a>”（
          <i>developerWorks</i>，2002 年 9 月）尽管写得比较早，仍然是关于 XHTML 2.0 所作修订的很好介绍。
        </li>
				<li>如果希望理解这种语言的构造块，教程 “
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/95279FA45716812B48256B5400285DDE?OpenDocument">XHTML 的模块化</a>”（Nicholas Chase，
          <i>developerWorks</i>，2001 年 10 月）非常有用。
        </li>
		</ul>
		<p>
				<a name="IDAQITAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>W3Schools 提供了一份
          <a href="http://www.w3schools.com/xhtml/xhtml_reference.asp">XHTML 1.0 Reference</a>，其中包括浏览器兼容性指南。
        </li>
				<li>ZVON 的
          <a href="http://www.zvon.org/xxl/xhtmlReference/Output/">XHTML 1.0 参考</a>包括一些例子和到标准的链接。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAEJTAC">
						<span class="atitle">Docbook</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.oasis-open.org/docbook">Docbook</a>
				</b>原来是一种流行的 SGML 格式，用于编纂书籍和文档，尤其是带有较多技术特性的文档。后来增加了一个 XML 版本，
        <b><a href="http://www.oasis-open.org/docbook/xml/4.2/index.shtml">DocBook XML V4.2</a></b>[OASIS
委员会规范]是最新的成果。Docbook
非常流行，得到了许多工具的支持，其中很多工具非常成熟。它作为避免混合表示问题与内容格式的一个范例而受人尊敬。最近，一些开发人员开始抱怨它从过去的
版本继承了太多的负担，纷纷讨论（甚至包括它的主要开发者 Norm Walsh）为这种格式重新开发一种新的、不向后兼容的版本。 </p>
		<p>
				<b>
						<a href="http://www.tei-c.org/">Text Encoding Initiative (TEI)</a>
				</b>甚
至比 Docbook 更古老，这种文档格式在某种程度上与 Docbook
的应用范围类似，区别在于它通常处理的是人文学科的文本而非技术文本。TEI 本身不是一种 SGML 或 XML
应用，而是一组用于构造语言（DTD）的指导原则。最常用的 TEI 变体是 <b><a href="http://www.tei-c.org/Lite/">TEI Lite</a></b>[社区标准]。TEI 以其复杂性驰名，这在一定程度上限制了它被大量采用，但是它得到了很好的维护，并在一些社区中有狂热的用户。
      </p>
		<p>
				<a name="IDACKTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>David Mertz, Ph.D. 撰写的 “
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters/part3/index.shtml">DocBook XML 方言入门</a>”（
          <i>developerWorks</i>，2000 年 10 月）是一篇高水平的介绍。
        </li>
				<li>Norman Walsh 的 “
          <a href="http://nwalsh.com/docs/tutorials/winwriters2001/index.html">Introducing DocBook</a>”  是一篇非常深入的介绍，采用了演示幻灯片的形式。
        </li>
				<li>“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-matters/part30/index.shtml">XML 问题:   TEI -- 文本编码规范</a>”（David Mertz, Ph.D.，
          <i>developerWorks</i>，2003 年 9 月）对 TEI 做了高水平的介绍。
        </li>
		</ul>
		<p>
				<a name="IDAALTAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>
						<a href="http://www.docbook.org/">DocBook.org</a>基本上是关于 Norman Walsh 所著
          <i>DocBook: The Definitive Guide</i>（O'Reilly &amp; Associates, 1999） 一书的站点。它把全书的内容都放在了网上，并作了很好的链接，这是关于 DocBook 各个方面的很好很详细的参考。
        </li>
				<li>
						<a href="http://docbook.org/wiki">DocBook Wiki</a>是关于这种语言的信息和讨论的协作空间。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAVLTAC">
						<span class="atitle">XSL-FO</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/xsl/">Extensible Stylesheet Language Formatting Objects (XSL-FO)</a>
				</b>[W3C
推荐标准]是一种使用 XML 定义的表示语言。（注意，链接规范的标题是 "Extensible Stylesheet Language
(XSL)"，但内容事实上只包括 XSL 的格式化对象方面。）XSL-FO 是一种 XML
格式，可被任何用户代理用于按照开发人员给定的精确规范呈现内容。它的角色类似于 Web 用户界面中的 XHTML，
但是更加复杂，以便表达适用于打印形式的格式化细节。这些细节和级联样式表（CSS——本系列文章 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/index.shtml">前已述及</a>）中所规定的没有什么不同，但是在 XSL-FO 中，这些细节构成了这种标记语言本身的一个实例，而不是呈现单个标记的指令。
      </p>
		<p>XSL-FO 常用作
        <b>XSLT</b>（本系列文章
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand2/index.shtml">前已述及</a>）的输出格式。事实上，最初 XSLT 和 XSL-FO 是一个系统，称为 XSL，但是工作组明智地将这两个部分分成了两个不同的规范。有多种开放源代码的或者商业化的工具可以将 XSL-FO 转化成
        <b>TeX</b>、Adobe 的
        <b>PDF</b>以及其他适于打印和排版的（非 XML）输出格式。这种应用模式使 XSL-FO 非常流行，但是 XSL-FO 一直希望成为 WYSIWYG 工具或者类似工具的原生呈现格式，它的这种应用也开始受到推动。
        <b><a href="http://www.w3.org/TR/xsl11/">XSL-FO 1.1</a></b>[开发中]是这种语言的升级，增加了注释、索引、书签之类的特性，并增强了图像的处理能力。
      </p>
		<p>
				<a name="IDAXMTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Doug Tidwell 的教程 “
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/3B308072632F949FC8256D320006CA3F?OpenDocument">XSL 格式化对象（XSL-FO）基础知识</a>”（
          <i>developerWorks</i>，2003 年 2 月）是一个非常友好的起点。他的后续文章“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/4FEB9F2ADFF0CEC3C8256D350003C961?OpenDocument">XSL-FO 高级技术</a>”（
          <i>developerWorks</i>，2003 年 2 月）介绍如何使用 XSL-FO 完成更加复杂的任务，如格式化数据、创建复杂的文档、把 HTML 元素转化成格式化对象然后再转化成 PDF 文档。最后，他的“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xslfo2app/index.shtml">HTML 至格式化对象（FO）转换指南</a>”（
          <i>developerWorks</i>，2003 年 2 月）示范了如何使用 XSLT 模板把常用的 HTML 元素转化成格式化对象，以便更容易转换为 PDF。
        </li>
				<li>Rodolfo M. Raya 的“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xslfo/index.shtml">使用 XSL-FO 创建可打印文档</a>”（
          <i>developerWorks</i>，2001 年 1 月）主要讨论将 XSL-FO 用于创建可打印的数据库报表。
        </li>
				<li>J. David Eisenberg 的“
          <a href="http://www.xml.com/pub/a/2001/01/17/xsl-fo/index.html">Using XSL Formatting Objects</a>”是一篇简要的介绍，强调了 XSL-FO 强大的国际化支持。
        </li>
		</ul>
		<p>
				<a name="IDABOTAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 提供了一个
          <a href="http://www.zvon.org/xxl/xslfoReference/Output/">XSL FO 参考</a>，勾勒了元素之间的一些关系，但是没有深入每种元素的语义。
        </li>
				<li>Dave Pawson 的
          <a href="http://www.dpawson.co.uk/xsl/xslfaq.html">XSL FAQ</a>探讨了 XSL-FO 以及 XSLT 和 XPath。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAVOTAC">
						<span class="atitle">SVG</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/SVG/">Scalable Vector Graphics (SVG) 1.1</a>
				</b>[W3C 推荐标准]是一种描述二维图像的语言。它主要是一种
        <b>向量</b>图形语言，尽管也支持一些
        <b>光栅</b>图
形特性。SVG 的非凡雄心是提供一种实用的、灵活的、使用（以冗长闻名的）XML 表示的图像格式，而且在这点上做的很成功。SVG
的特性包括：嵌套转换、剪辑路径、alpha 蒙板、光栅过滤效果、模板对象，当然还有可扩展性。SVG
也支持动画、缩放和移动视图、各种图形原语、分组、脚本、超链接、结构化元数据、CSS、一种专用的 DOM 超集（DOM 和 CSS
前已述及），并且很容易嵌入其他 XML 文档。SVG
的一些设计决策经历了不很激烈的争论，其中包括向量路径在单个属性中使用空格分隔的数字列表表示，但是总体上 SVG
已经成为应用最广泛的并受到热烈欢迎的一种 XML 应用。该规范已经被 <a href="http://www.w3.org/Graphics/SVG/svg-updates/translations.html">翻译成了多种语言</a>。
      </p>
		<p>SVG 1.1 是对
        <b><a href="http://www.w3.org/TR/2001/REC-SVG-20010904/">SVG 1.0</a></b>[W3C 推荐标准]的更新，增加了一些新特性，也包括一些更正。最大的区别是 SVG 1.1 以类似 XHTML 1.1+ 的方式进行了模块化。这种模块化使得 SVG 能够扩展甚至精简，就像
        <b><a href="http://www.w3.org/TR/SVGMobile/">Mobile SVG Profiles: SVG Tiny and SVG Basic</a></b>[W3C 推荐标准]那样。后者定义了 SVG 模块的精简集，适用于移动电话和 PDA。
        <b><a href="http://www.w3.org/TR/SVG12/">SVG 1.2</a></b>[开发中]致力于增加许多新工具，使 SVG 不仅作为一种图像格式，而且成为具有广泛应用前景的平台。
      </p>
		<p>
				<a name="IDA1PTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Nicholas Chase 撰写的教程“
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/409E5759CF4CDA8E48256BBF0035382A?OpenDocument">可伸缩向量图形介绍</a>”（
          <i>developerWorks</i>，2002 年 2月）提供了许多例子。
        </li>
				<li>J. David Eisenberg 的“
          <a href="http://www.xml.com/pub/a/2001/03/21/svg.html">An Introduction to Scalable Vector Graphics</a>”是一篇很好的快速入门文章。
        </li>
				<li>W3Schools
          <a href="http://www.w3schools.com/svg/default.asp">SVG 教程</a>涵盖了最常用的元素。
        </li>
		</ul>
		<p>
				<a name="IDA0QTAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>
						<a href="http://www.protocol7.com/svg-wiki/default.asp">SVG Wiki</a>，一个协作资源索引和讨论网页，是关于这种语言的各种信息的公共消息交换中心。
        </li>
				<li>ZVON 的
          <a href="http://www.zvon.org/xxl/svgReference/Output/introduction.html">SVG Reference</a>提供了元素之间的关系图和一些例子。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDANRTAC">
						<span class="atitle">VoiceXML</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/voicexml20/">Voice Extensible Markup Language (VoiceXML) Version 2.0</a>
				</b>[开发中]是一种创建音频、语音和电话应用程序的语言。它包含的音频对话框具有以下特点：语音合成、数字音频、声音识别和电话音质拨号输入和话音输入录制。它寻求把基于 Web 的开发和内容传递的优势带入
        <b>交互式语音响应</b>应用程序中。VoiceXML 是
        <b><a href="http://www.w3.org/TR/voice-intro/">W3C Speech Interface Framework</a></b>[开发中]的一部分，后者还包括其他的标准，由于这些标准与电话行业的界限非常模糊，这里就不讨论了。VoiceXML 2.0 标志着 VoiceXML 规范从
        <a href="http://www.voicexml.org/">VoiceXML Forum</a>转向 W3C，前者仍然在努力改进这种技术。关于 VoiceXML 已经有了
        <a href="http://www.w3.org/2001/09/voice-disclosures.html">一些专利声明</a>，其中一些意味着 VoiceXML 用户将面临版权和许可费的问题。
      </p>
		<p>
				<a name="IDAJSTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>W3C 职员 Dave Raggett 撰写了一篇很好的介绍文章，“
          <a href="http://www.w3.org/Voice/Guide/">Getting started with VoiceXML 2.0</a>”。
        </li>
				<li>稍微深一点的教程，请参阅 Vivek Malhotra 的“
          <a href="http://www.ibm.com/developerworks/edu/wi-dw-wivoice-i.html?S_TACT=104AHW06&amp;S_CMP=TUT">Introduction to Voice XML</a>”（
          <i>developerWorks</i>，2001 年 11 月）。
        </li>
				<li>VoiceXML Forum 提供了一个
          <a href="http://www.voicexml.org/tutorials/intro1.html">交互式系列教程</a>。
        </li>
		</ul>
		<p>
				<a name="IDAFTTAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 的
          <a href="http://www.zvon.org/xxl/VoiceXMLReference/Output/">VoiceXML Reference</a>突出了例子。
        </li>
				<li>FreeSpeech Developer Network 也提供了一份
          <a href="http://freespeech.heyanita.com/reference/vxml/vxmlref.asp">VoiceXML Reference</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAZTTAC">
						<span class="atitle">MathML</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/MathML/">Mathematical Markup Language (MathML) 2.0</a>
				</b>[W3C
推荐标准]是一种 XML 语言，按照该规范的说法，其目的是“促进数学和科学内容在 Web
上，以及其他应用程序如计算机代数系统、打印排版及语音合成中的使用和重用。MathML
可用于对能够高质量显示的数学符号表示编码，也可用于为语义起着更重要作用的应用程序对数学内容编码，如科学软件或语音合成。”MathML
常用于在教育、科学论文、工业规范、规章内容等领域中表示等式、公式或者类似的信息。这个版本对 <b><a href="http://www.w3.org/TR/REC-MathML/">MathML 1.01</a></b>[W3C 推荐标准]增加了一些相对较新的特性。MathML 经常和 XHTML、SVG 以及其他应用一起使用。
      </p>
		<p>
				<a name="IDALUTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Robert Miner 与 Jeff Schaeffer 合作的“
          <a href="http://www.dessci.com/en/support/tutorials/mathml/default.htm">A Gentle Introduction to MathML</a>”是一篇很好的入门文章。
        </li>
				<li>Michael Kohlhase 的“
          <a href="http://www.w3.org/Math/Documents/mathml-tutorial.pdf">MathML: Presenting and Capturing Mathematics for the Web (PDF)</a>”更长内容也更深。
        </li>
		</ul>
		<p>
				<a name="IDA5UTAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>ZVON 的
          <a href="http://www.zvon.org/xxl/MathML/Output/">MathML 2 参考</a>更类似一个索引，反映了元素之间的关系。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDANVTAC">
						<span class="atitle">Synchronized Multimedia Integration Language (SMIL)</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.w3.org/TR/smil20/">SMIL 2.0</a>
				</b>[W3C
规范]，按照 W3C 的说法，“支持简单地编辑交互式[音频/视频]演示文稿。SMIL
通常用于[‘丰富媒体’或多媒体]演示文稿，其中集成了流式音频和视频、图像、文本或者任何其他媒体类型。SMIL是一种简单易学的类 HTML
语言，许多 SMIL 演示文稿都是使用简单的[文本编辑器]编写的。”SMIL 是 <b><a href="http://www.w3.org/AudioVideo/">W3C Synchronized Multimedia activity</a></b>的一个产品，已经升级到了
        <b><a href="http://www.w3.org/TR/REC-smil/">SMIL 1.0</a></b>[W3C 推荐标准]，增加了和动画、元数据、内容控制、链接、定时与同步、事件处理、过渡效果等有关的特性。
      </p>
		<p>
				<a name="IDAEWTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>Anne Zieger 的“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-smil/index.shtml">熟悉 SMIL 2.0</a>”（
          <i>developerWorks</i>，2002 年 9 月）从高层次上概述了这种技术及其实现。
        </li>
				<li>Lynda Hardman 与 Lloyd Rutledge 的“
          <a href="http://www.cwi.nl/%7Elynda/tue-2R480/SMILTut.pdf">SMIL 2.0 -- Interactive Multimedia on the Web</a>”[PDF] 是一篇深入的教程。
        </li>
				<li>W3Schools 提供了一个
          <a href="http://www.w3schools.com/smil/default.asp">SMIL 2.0 教程</a>。
        </li>
		</ul>
		<p>
				<a name="IDAAXTAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>荷兰的 CWI (Centrum voor Wiskunde en Informatica) 提供了一个
          <a href="http://homepages.cwi.nl/%7Emedia/symm/validator/">Experimental SMIL validator</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAOXTAC">
						<span class="atitle">RDF</span>
				</a>
		</p>
		<p>
差不多在 W3C 致力于以 XML 为代表的下一代标记技术的同时，它也开始了下一代 Web 资源形式化描述技术的研究。
        <b><a href="http://www.w3.org/TR/rdf-concepts">Resource Description Framework (RDF)</a></b>[W3C 推荐标准]是一种模型，用于描述一组 Web 资源声明。这些声明被概念化为
        <b>三元组</b>，每一个都包含
        <b>主语</b>（一个 URI——本系列文章
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml">前已述及</a>）、
        <b>谓词</b>（也是一个 URI）和
        <b>对象</b>（一个 URI 或字面数据值）。要理解这种声明的意义，可以想一想描述 Web 页面的 HTML 
        <code>meta</code>
标签。如果套用在 RDF 上，主语就是 Web 页面本身的 URI，谓词是一个标准 URI
表示一般的描述，而对象就是描述的实际文本。通过大量使用 URI，RDF
希望尽量减少这些声明成分标识的歧义，从而更加形式化以便于机器处理。RDF 能否实现这一目标还存在争议，但是 RDF
以其非常活跃的社区和范围广泛的工具而知名。 </p>
		<p>RDF 是 W3C
        <b><a href="http://www.w3.org/2001/sw/">Semantic Web activity</a></b>的支柱；
        <b>Semantic Web</b>是
Web 的一种视像，不仅仅是内容的表示，还包括内容的注释以帮助表达它的含义。比如，在 Semantic Web 中描述 Web
资源时，可以区分 "python"（一种蛇）和 "python"（一种计算机编程语言）这样的概念。RDF 标准化由大量规范组成，包括： </p>
		<ul>
				<li>
						<b>
								<a href="http://www.w3.org/TR/rdf-concepts/">Resource Description Framework (RDF): Concepts and Abstract Syntax</a>
						</b>[W3C 推荐标准]提出了目标、核心概念、基本数据模型以及 RDF 的抽象语法。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/rdf-syntax-grammar/">RDF/XML Syntax Specification</a>
						</b>[W3C 推荐标准]定义了 RDF 的一种通用 XML 表示。许多观察者包括我自己，都抱怨 RDF/XML 语法可怜的标记设计。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/rdf-schema/">RDF Vocabulary Description Language 1.0: RDF Schema</a>
						</b>[W3C 推荐标准]定义了一个 RDF 词汇表，可用于定义其他 RDF 词汇表。
        </li>
				<li>
						<b>
								<a href="http://www.w3.org/TR/rdf-mt/">RDF Semantics</a>
						</b>[W3C 推荐标准]不是供内心缺乏勇气的人看的，它探讨了 RDF 数据模型底层的形式数学理论。
        </li>
		</ul>
		<p>
				<b>
						<a href="http://www.w3.org/TR/owl-features/">Web Ontology Language (OWL)</a>
				</b>[W3C 推荐标准]是 RDF 的一个应用，通常用 RDF/XML 编码，增加了丰富的词汇表可用于对 RDF 资源进行正式分类和归纳。
      </p>
		<p>
				<a name="IDAXZTAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>我的文章“
          <a href="http://www.newarchitectmag.com/documents/s=2453/new1020218556549/index.html">The Languages of the Semantic Web</a>”讨论了 RDF 与 Semantic Web 技术的动机和基础，主要针对 Web 开发人员。
        </li>
				<li>W3C 的
          <a href="http://www.w3.org/TR/rdf-primer/">RDF Primer</a>是非常适当的入门文章。
        </li>
		</ul>
		<p>
				<a name="IDAL0TAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>
						<a href="http://www.ilrt.bris.ac.uk/discovery/rdf/resources/">Dave Beckett's RDF Resource Guide</a>是关于 RDF、OWL 和 Semantic Web 更多信息的权威资源。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDAY0TAC">
						<span class="atitle">XML Topic Maps</span>
				</a>
		</p>
		<p>
				<b>
						<a href="http://www.y12.doe.gov/sgml/sc34/document/0323.htm">Topic Maps</a>
				</b>[ISO 国际标准，编号 13250]提供了组织信息的一个系统，在某些方面是与 RDF 竞争的一种 Semantic Web 技术。具体而言，
        <b><a href="http://www.topicmaps.org/xtm/index.html">XML Topic Maps</a></b>[ISO
13250 的一部分]是 Topic Maps 一种 Web 友好的版本，使用 XML 语法，并以 URI 作为标识符。与 RDF
相似，Topic Maps 定义了一种类似图的模型，但更细微的差别和这样一个事实有关，即 Topic Maps
的一个重要规定是实际概念与其计算机表示的区分。Topic Maps 的这种做法是 Semantic Web
的一种基本工具，还是增加了不必要的复杂性，在 Topic Maps 与 RDF 支持者之间的这种争论永远不会划上句号。XML Topic
Maps 使用了一种非常清晰的 XML 语法，这种语法基于 XLink（本系列文章 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand1/index.shtml">前已述及</a>）。
      </p>
		<p>
				<a name="IDAO1TAC">
						<span class="smalltitle">推荐的入门参考和教程</span>
				</a>
		</p>
		<ul>
				<li>我的文章“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/rdf/part19/index.shtml">Think XML：从书本学习 XML Topic Maps</a>”（
          <i>developerWorks</i>，2003 年 7 月）做了相当简要的介绍。
        </li>
				<li>Lars Marius Garshol 的“
          <a href="http://www.xml.com/pub/a/2002/09/11/topicmaps.html">What Are Topic Maps?</a>”做了很具体的介绍。
        </li>
		</ul>
		<p>
				<a name="IDAE2TAC">
						<span class="smalltitle">参考资料和其他资源</span>
				</a>
		</p>
		<ul>
				<li>关于 Topic Maps 信息的主要资源站点有
          <a href="http://www.topicmaps.net/">Topicmaps.net</a>、
          <a href="http://www.topicmaps.org/">TopicMaps.org</a>和
          <a href="http://www.topicmap.com/">topicmap.com</a>。
        </li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="IDA02TAC">
						<span class="atitle">只是浅尝辄止</span>
				</a>
		</p>
		<p>
在本系列文章中，在有限的空间中选择哪些内容进行讨论让我煞费苦心。很多信息不可能包含进来，尤其是关于 XML 应用的这篇文章。XML
的一个优点同时也是祸根，它让每个人都可以很容易地定义自己的语言。目前存在的难以计数的词汇表都可以称为这种或那种形式的标准。在形形色色的目标之间，
我主要把目光放在那些最流行、采用最广泛的那些标准上。</p>
		<p>您还可以找到关于正式商业文档交换的许多标准，要了解这些数不清的选择，您可以看看下面列出的
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#resources">参考资料</a>，既有私有的也有标准的。在我的
        <a href="http://www-128.ibm.com/developerworks/cn/xml/rdf/index.shtml"><i>Thinking XML</i>专栏
        </a>中也讨论了许多这样的标准。
      </p>
		<p>下一篇文章是本系列的最后一篇文章，我将对讲述过的内容进行比较，并一一列出以便交叉参考。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的
          <a href="http://www.ibm.com/developerworks/library/x-stand3.html">英文原文</a>.
        <br /><br /></li>
				<li>如果希望就 XML 获得坚实的基础，请阅读
          <a href="http://www.ibiblio.org/xml/books/bible2/"><i>The XML Bible, 2nd Edition</i></a>，Elliotte Rusty Harold 著（John Wiley &amp; Sons, 2001），前提是您愿意买下这本书。关于 XSLT、XSL-FO、XLink、XPointer 和 WXS 的五章可以免费从网上获得。
          <br /><br /><br /><br /></li>
				<li>访问开发 XML 标准的最重要组织的网站：

          <ul><li><a href="http://www.w3.org/">W3C （万维网联盟）</a></li><li><a href="http://www.oasis-open.org/">OASIS （结构化信息标准推进组织）</a></li><li>ISO （国际标准化组织），尤其是它的项目
              <a href="http://dsdl.org/">ISO/IEC 19757 - Document Schema Definition Languages （文档模式定义语言，DSDL）</a></li></ul><br /><br /></li>
				<li>Simon St. Laurent 所写的
          <a href="http://simonstl.com/articles/civilw3c.htm">Outsider's Guide to the W3C</a>是一个 FAQ，对这个为您带来 HTML 和 XML 的组织进行了多方面的介绍。
          <br /><br /><br /><br /></li>
				<li>Robin Cover 的
          <a href="http://xml.coverpages.org/">The Cover Pages</a>基本上涉及到了 XML 的每个方面，这是一个令人瞠目的、包罗万象的 XML 资源指南。
          <br /><br /><br /><br /></li>
				<li>访问
          <a href="http://xmlhack.com/">xmlhack</a>，XML 开发人员的新闻站点，Uche 帮助编辑。
          <br /><br /><br /><br /></li>
				<li>在
          <a href="http://www.ibm.com/developerworks/xml/"><i>developerWorks</i>XML 专区
          </a>可以找到更多的 XML 资源，包括 Uche Ogbuji 的
          <a href="http://www-128.ibm.com/developerworks/cn/xml/rdf/index.shtml"><i>Thinking XML</i>专栏
          </a>。
          <br /><br /><br /><br /></li>
				<li>在
          <i>developerWorks</i><a href="http://devworks.krcinfo.com/">Developer Bookstore</a>上可以找到大量与 XML 有关的书籍。
          <br /><br /><br /><br /></li>
				<li>了解如何才能成为一名
          <a href="http://www-1.ibm.com/certify/certs/adcdxmlrt.shtml">IBM 认证的 XML 及相关技术开发人员</a>。
          <br /><br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-stand3/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="Uche Ogbuji 的照片" src="http://www-128.ibm.com/developerworks/cn/i/p-uche.jpg" align="left" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Uche Ogbuji 是
        <a href="http://fourthought.com/">Fourthought Inc.</a>的顾问兼创始人，该公司是专为企业知识管理提供 XML 解决方案的软件供应商和咨询公司。 Fourthought 开发了
        <a href="http://4suite.org/">4Suite</a>，这是一个用于 XML、RDF 和知识管理应用程序的开放源代码平台。Ogbuji 先生是
        <a href="http://uche.ogbuji.net/tech/rdf/versa/">Versa</a>RDF 查询语言的首席开发人员。他是一位出生于尼日利亚的计算机工程师和作家，在美国科罗拉多的博耳德生活和工作。可以通过
        <a href="mailto:uche.ogbuji@fourthought.com">uche.ogbuji@fourthought.com</a> 和 Ogbuji 先生联系。

      </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 21:11 <a href="http://www.blogjava.net/Vencent/articles/35981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web 的未来：XHTML 2.0 变更概述</title><link>http://www.blogjava.net/Vencent/articles/35976.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:52:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35976.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35976.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35976.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#author">Nicholas Chase</a>, 总裁, Chase and Chase, Inc.<br /></p>
		<p>2003 年  1 月  01 日</p>
		<blockquote>多
年以来，HTML 只是在不断变大，却从未变小，因为新版本必须维护向后兼容性。这一情况将得以改变。XHTML 2.0 的第一个工作草案于
2002 年 8 月 5
日发布，一大新闻就是取消了向后兼容性；该语言终于得以继续发展。那么，作为一名开发人员您将得到什么回报呢？健壮的表单和事件表现如何呢？它们是研究不
需要大量 JavaScript 的框架以及甚至层次结构菜单的更佳方法。</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>本文概述了 XHTML 2.0 中的新增功能以及将来可能会如何使用它。读者应该熟悉 HTML 和／或 XHTML 1.0。熟悉级联样式表（Cascading Style Sheet (CSS)）是有帮助的，但不是必需的。</p>
		<p>
				<a name="1">
						<span class="atitle">告别向后兼容性，引入结构</span>
				</a>
		</p>
		<p>


当万维网联盟（World Wide Web Consortium (W3C)）于 2002 年 8 月 5 日发布 XHTML 2.0 的第一个工作草案时，
最让人吃惊的是：与其先前的版本不同，它不是向后兼容的。
对于先前的发行版，如从 HTML 4.01 转到 XHTML 1.0 以及后来从 XHTML 1.0 到 XTHML 1.1，变化都是添加一些内容；
可以读取 XHTML 1.0（过渡的）文档的浏览器也可以理解 HTML 4.01 文档。而 XHTML 2.0 不是那样的。</p>
		<p>如果您在两年前宣布我们今天将研究不带 
        <code>img</code> 标记或 
        <code>bold</code> 标记的 HTML 版本，那么大多数 Web 开发人员都会用怀疑的眼光看着您。然而，现在就是这样。除了彻底替换表单和框架外，XHTML 2.0 还除去了 
        <code>b</code> 、 
        <code>i</code> 和 
        <code>img</code> 标记（以及 
        <code>big</code> 、 
        <code>small</code> 和 
        <code>tt</code> ），
甚至不赞成使用 
        <code>br</code> ，以准备从将来的发行版中除去它。但这是为什么呢？
      </p>
		<p>原因在于大多数标记都是
        <i>表示性的</i> 。它们的唯一目的就是给予浏览器指令，规定有关其内容应该如何显示，
但却完全未提供有关其内容是什么的信息。例如，请考虑下面两个句子：
      </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />Presentational elements are, &lt;i&gt;for the most part&lt;/i&gt;, &lt;b&gt;gone&lt;/b&gt;.<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>和</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />Presentational elements are, &lt;em&gt;for the most part&lt;/em&gt;, &lt;strong&gt;gone&lt;/strong&gt;.<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在没有样式表的情况下，这两个句子在浏览器中看起来是一样的，但只有第二个句子提供了有关原因的信息。
事实上，从一开始 
        <code>em</code> （强调）和 
        <code>strong</code> 标记就出现在 HTML 中了，
但多年以来作者们基本上已经忽略了它们，而专注于表现形式，这是以牺牲内容为代价的。
      </p>
		<p>但这并不意味着只要您想使某些内容变成粗体或斜体，就应该将它们硬塞进这两个标记中。
相反，除去表示性元素的整个目的是设法完成 CSS 的发明者的初衷，
即应该根据内容所表示的东西来标记内容，而样式表应该用于美化内容。例如， 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code1">清单 1</a>使用类别（class）来指出内容类型。
      </p>
		<br />
		<a name="code1">
				<b>清单 1. 使用类别指定内容类型</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;html&gt;<br /><br />&lt;head&gt;&lt;title&gt;Employee Notice&lt;/title&gt;<br /><br />&lt;style type="text/css"&gt;<br /><br />    .duedate { color: red;<br /><br />               font-weight: bold; }<br /><br />    .holiday { color: green;<br /><br />               font-style: italic }<br /><br />&lt;/style&gt;<br /><br />&lt;/head&gt;<br /><br />&lt;body&gt;<br /><br />&lt;h1&gt;Notice&lt;/h1&gt;<br /><br />&lt;p&gt;Employees should take note of the following important dates:&lt;/p&gt;<br /><br />&lt;ul&gt;<br /><br />    &lt;li class="duedate"&gt;8/28/2002 (Progress reports due)&lt;/li&gt;<br /><br />    &lt;li class="holiday"&gt;9/1/2002 (Labor Day)&lt;/li&gt;<br /><br />    &lt;li class="duedate"&gt;10/28/2002 (Final reports due)&lt;/li&gt;<br /><br />&lt;/ul&gt;<br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在该页面中，日期类型可以由内容本身来确认，浏览器可以使用类别信息来决定如何为其设计样式，
如 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#figure1">图 1</a>中所示。
      </p>
		<br />
		<a name="N100AB">
				<b>图 1. 类别可以确定显示哪一类内容，样式表可以对它进行适当的格式化</b>
		</a>
		<br />
		<img alt="" src="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/figure1.jpg" height="337" width="454" />
		<br />
		<p>用这种观点研究它：断开（ 
        <code>br</code> ）标记的目的无外乎是为了显示，因为实际上它并无任何内容。XHTML 2.0
不赞成使用 
        <code>br</code> 标记，而提倡使用 
        <code>line</code> 标记。 
        <code>line</code> 标记指定一种特殊的内容：
通常是以后跟换行和回车这种方式呈现的一行文本或其它内容。例如，文本：
      </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;p&gt;<br /><br />public class HelloWorld {&lt;br /&gt;<br /><br />public static void main (String[] args){&lt;br /&gt;<br /><br />System.out.println("Hello world!");&lt;br /&gt;<br /><br />}&lt;br /&gt;<br /><br />}<br /><br />&lt;/p&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>变成</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;p&gt;<br /><br />&lt;line&gt;public class HelloWorld {&lt;/line&gt;<br /><br />&lt;line&gt;public static void main (String[] args){ &lt;/line&gt;<br /><br />&lt;line&gt;System.out.println("Hello world!"); &lt;/line&gt;<br /><br />&lt;line&gt;}&lt;/line&gt;<br /><br />&lt;line&gt;}&lt;/line&gt;<br /><br />&lt;/p&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这样，文档就有了一个表示行的实际对象，同样，段（ 
        <code>p</code> ）标记表示一段内容。
      </p>
		<p>为什么所有这些都很重要呢？因为 Web 不仅正日益成为人与人之间通信的场所，
而且还日益成为软件应用程序（如服务器和搜索引擎索引器）之间进行通信的场所。
而且，每个人（或者说几乎每个人）都使用相同浏览器的时代已经一去不复返了。
开发人员正不断为不同设备（如 PDA 和移动电话）重新设计内容。语音触发的（voice-activated）系统已经离我们不远了。内容的结构意义正变得几乎与内容本身一样重要。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">节</span>
				</a>
		</p>
		<p>
因此，XHTML 2.0 添加了节（section）和标题（heading）。HTML 一直都包含编号的标题 ― 
        <code>h1</code> 到 
        <code>h6</code> ，
直到 2002 年 8 月 5 日的工作草案，还未将其撤消，但这只是一个时间问题。
而 XHTML 2.0 使用通用标题和节。例如，可以嵌套节，从而赋予标题含义。
以前用编号标题呈现的文档（ 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code2">清单 2</a>）：
      </p>
		<br />
		<a name="code2">
				<b>清单 2. 文档中的编号标题</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />
														<br />
														<br />&lt;html&gt;<br /><br />&lt;head&gt;&lt;title&gt;Adding sections&lt;/title&gt;&lt;/head&gt;<br /><br />&lt;body&gt;<br /><br />   &lt;h1&gt;The Web's future: XHTML 2.0&lt;/h1&gt;<br /><br />   &lt;p&gt;by Nicholas Chase&lt;/p&gt;<br /><br />   &lt;h2&gt;Good-bye backward compatibility, hello structure&lt;/h2&gt;<br /><br />   &lt;p&gt;Why backward compatibility is over.&lt;/p&gt;<br /><br />   &lt;h3&gt;Presentation versus Structure&lt;/h3&gt;<br /><br />   &lt;p&gt;Using style sheets rather than presentational elements.&lt;/p&gt;<br /><br />   &lt;h3&gt;Lines&lt;/h3&gt;<br /><br />   &lt;p&gt;Line breaks are deprecated.&lt;/p&gt;<br /><br />   &lt;h2&gt;Sections&lt;/h2&gt;<br /><br />   &lt;p&gt;Creating more reasonable sections.&lt;/p&gt;<br /><br />   &lt;h2&gt;Navigation lists and menus&lt;/h2&gt;<br /><br />   &lt;p&gt;Hierarchical menus.&lt;/p&gt;<br /><br />   &lt;h2&gt;Links, links, everywhere&lt;/h2&gt;<br /><br />   &lt;p&gt;Adding links.&lt;/p&gt;<br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>可以用通用标题和节替换（
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code3">清单 3</a>）：
      </p>
		<br />
		<a name="code3">
				<b>清单 3. 通用标题和节</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />
														<br />
														<br />&lt;html&gt;<br /><br />&lt;head&gt;&lt;title&gt;Adding sections&lt;/title&gt;&lt;/head&gt;<br /><br />&lt;body&gt;<br /><br />   &lt;section&gt;<br /><br />      &lt;h&gt;The Web's future: XHTML 2.0&lt;/h&gt; <br /><br />      &lt;p&gt;by Nicholas Chase&lt;/p&gt;<br /><br />      &lt;section&gt;<br /><br />         &lt;h&gt;Good-bye backward compatibility, hello structure&lt;/h&gt;<br /><br />         &lt;p&gt;Why backward compatibility is over.&lt;/p&gt;<br /><br />         &lt;section&gt;<br /><br />            &lt;h&gt;Presentation vs. Structure&lt;/h&gt;<br /><br />            &lt;p&gt;Using style sheets rather than presentational elements.&lt;/p&gt;<br /><br />         &lt;/section&gt;<br /><br />         &lt;section&gt;<br /><br />             &lt;h&gt;Lines&lt;/h&gt;<br /><br />             &lt;p&gt;Line breaks are deprecated.&lt;/p&gt;<br /><br />         &lt;/section&gt;<br /><br />      &lt;/section&gt;<br /><br />      &lt;section&gt;<br /><br />         &lt;h&gt;Sections&lt;/h&gt; <br /><br />         &lt;p&gt;Creating more reasonable sections.&lt;/p&gt;<br /><br />      &lt;/section&gt;<br /><br />      &lt;section&gt;<br /><br />          &lt;h&gt;Navigation lists and menus&lt;/h&gt;<br /><br />          &lt;p&gt;Hierarchical menus.&lt;/p&gt;<br /><br />      &lt;/section&gt;<br /><br />      &lt;section&gt;<br /><br />          &lt;h&gt;Links, links, everywhere&lt;/h&gt;<br /><br />          &lt;p&gt;Adding links.&lt;/p&gt;<br /><br />      &lt;/section&gt;<br /><br />   &lt;/section&gt;<br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这种结构有两个优点。首先，应用程序（如搜索引擎 crawler）能够更容易地了解内容的相对重要性，
其次，节是自包含的。在 HTML 中，节以其标题开始，所以在标题的前面不会出现内容（如介绍性内容）。 
        <code>section</code> 
元素取消了这种约束，因为其内部的任何内容都是节的一部分。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="3">
						<span class="atitle">导航列表和菜单</span>
				</a>
		</p>
		<p>
增加了一个会让 Web 开发人员大大受益的结构，那就是导航列表。由 
        <code>nl</code> 标记指定的导航列表的工作原理与其“表亲”有序列表（ 
        <code>ol</code> ）和无序列表（ 
        <code>ul</code> ）非常相似，但有一点不一样：导航列表的项仅在列表激活时才出现。
因此，导航列表与层次结构的弹出菜单十分相似，这种弹出菜单很受欢迎，因为它们提供了许多导航信息，而且不会占据太多的屏幕空间。
例如，肥皂剧站点可能有以下菜单（ 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code4">清单 4</a>）：
      </p>
		<br />
		<a name="code4">
				<b>清单 4. 使用导航列表</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;nl&gt;<br /><br />   &lt;name&gt;Character Options&lt;/name&gt;<br /><br />   &lt;li href="stay.html"&gt;Stay&lt;/li&gt;<br /><br />   &lt;nl&gt;<br /><br />      &lt;name&gt;Leave&lt;/name&gt;<br /><br />      &lt;li href="newjob.html"&gt;Job transfer&lt;/li&gt;<br /><br />      &lt;li href="divorce.html"&gt;Divorce&lt;/li&gt;<br /><br />      &lt;li href="fataldisease.html"&gt;Fatal disease&lt;/li&gt;<br /><br />   &lt;/nl&gt;<br /><br />   &lt;li href="backburner.html"&gt;Back Burner&lt;/li&gt;<br /><br />&lt;/nl&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当用户激活名称（ 
        <code>Character Options</code> ）时，出现列表项。
关于当用户激活主列表时子列表（如 
        <code>Leave</code> 菜单）是否会出现，还是用户必须激活子列表项本身以使其出现，工作草案并未说清楚。
最终作者可能通过样式或事件来控制这一行为。在任何情况下，当输入焦点从主元素移开时，列表项就会消失。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="4">
						<span class="atitle">链接，链接无处不在</span>
				</a>
		</p>
		<p>您可能已经注意到：即使打算将前一个示例作为菜单，
但它没有锚（ 
        <code>a</code> ）标记。而 
        <code>href</code> 属性已经被正确放在了 
        <code>li</code> 元素上。这不是导航列表的特性，而是 XHTML 2.0 的新特性。与超文本相关的属性（如 
        <code>href</code> 、 
        <code>target</code> 和 
        <code>accesskey</code> ）现在是公共属性集合（Common Attribute Collection）的一部分，它包括核心属性（ 
        <code>class</code> 、 
        <code>id</code> 和 
        <code>title</code> ）、国际化属性（ 
        <code>xml:lang</code> ，
它替换了 XHTML 1.1 中的 
        <code>lang</code> ）和事件属性，事件属性来自 XML Events 建议书，正如您将在下面看到的。
      </p>
		<p>这意味只要将 
        <code>href</code> 属性添加到任何元素，就可以将它转换成链接，而不一定要用锚标记包围单个元素。
      </p>
		<p>这是否表示经过四年的努力，XLink 已经被 XHTML 2.0 采用了吗？总而言之，没有。
事实上，XLink 和 XHTML 2.0 中规定的链接之间的差异是那些正从事各自建议书的开发人员之间争论的根源，
所以在这个最初的公开工作草案和最后的建议书之间可能会做些更改。
同时，可以组合使用该功能、导航列表、 
        <code>link</code> 元素，以及资源描述框架（Resource Description Framework (RDF)）来复制 XLink 的大多数功能。
      </p>
		<p>XForms 是一个与 XML 相关的建议书，并确实已经成为 XHTML 2.0 的一部分。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="5">
						<span class="atitle">XForms</span>
				</a>
		</p>
		<p>XML 表单语言（XML Forms Language (XForms)）
是研究表单的一种全新方法 ― 它象 XHTML 的其余部分一样 ― 内容、结构和表现是完全独立的。XForms 页面指定一个模型，
该模型拥有有关表单自身的信息，然后，可以在页面周围散布表单元素，而不是被局限于单个表单元素。
这意味着，您甚至可以在页面的同一区域中合并不同表单的元素。
可以通过实例文档填充表单，实例文档是从表单元素上的 XPath 表达式引用的。
表单元素自身也代表了特殊类型的对象，而不是描述在页面上它们是如何显示的。
当更新表单元素中的数据时，会更新实例文档。
当用户提交表单时，实际发送的是实例文档。例如，采用下面的简单表单（ 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code5">清单 5</a>）：
      </p>
		<br />
		<a name="code5">
				<b>清单 5. 简单的 HTML 表单</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />
														<br />
														<br />&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;<br /><br />&lt;head&gt;<br /><br />    &lt;title&gt;Preference Form&lt;/title&gt;<br /><br />&lt;/head&gt;<br /><br />&lt;body&gt;<br /><br /><br /><br />&lt;h1&gt;Preferences Form&lt;/h1&gt;<br /><br />&lt;form action="myformprocessor.jsp"&gt;<br /><br />&lt;p&gt; <br /><br />    Username: &lt;input type="text" name="userid" /&gt;<br /><br />    &lt;br /&gt;<br /><br />    Password: &lt;input type="password" name="pass"/&gt;<br /><br />&lt;/p&gt;<br /><br /><br /><br />&lt;p&gt;<br /><br />    Area preference:<br /><br />        &lt;select name="seatingpreference"&gt;<br /><br />             &lt;option value="1"&gt;One&lt;/option&gt;<br /><br />             &lt;option value="2"&gt;Two&lt;/option&gt;<br /><br />             &lt;option value="3"&gt;Three&lt;/option&gt;<br /><br />        &lt;/select&gt;<br /><br />&lt;/p&gt;<br /><br />&lt;p&gt;<br /><br />    &lt;input type="submit" /&gt;<br /><br />&lt;/p&gt;<br /><br />&lt;/form&gt;<br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code6">清单 6</a>显示了 XForms 版本的表单：
      </p>
		<br />
		<a name="code6">
				<b>清单 6. XForms 版本的表单</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />
														<br />
														<br />&lt;html xmlns="http://www.w3.org/1999/xhtml" <br /><br />      xmlns:xforms="http://www.w3.org/2002/01/xforms"&gt;<br /><br />&lt;head&gt;<br /><br />    &lt;title&gt;Preference Form&lt;/title&gt;<br /><br /><br /><br />    &lt;xforms:model&gt;<br /><br /><br /><br />        &lt;xforms:submitInfo method="postxml"/&gt;<br /><br /><br /><br />        &lt;xforms:instance xmlns=""&gt;<br /><br />            &lt;preferences&gt;<br /><br />                &lt;person userid=""&gt;<br /><br />                    &lt;password&gt;&lt;/password&gt;<br /><br />                &lt;/person&gt;<br /><br />                &lt;seatingpreference&gt;&lt;/seatingpreference&gt;<br /><br />            &lt;/preferences&gt;<br /><br />        &lt;/xforms:instance&gt;<br /><br />    &lt;/xforms:model&gt;<br /><br /><br /><br />&lt;/head&gt;<br /><br />&lt;body&gt;<br /><br /><br /><br />&lt;h1&gt;Preferences Form&lt;/h1&gt;<br /><br /><br /><br />&lt;p&gt; <br /><br />    &lt;xforms:input ref="preferences/person@userid"&gt;<br /><br />        &lt;xforms:caption&gt;Username: &lt;/xforms:caption&gt;<br /><br />    &lt;/xforms:input&gt;<br /><br /><br /><br />    &lt;br /&gt;<br /><br /><br /><br />    &lt;xforms:secret ref="preferences/person/password"&gt;<br /><br />        &lt;xforms:caption&gt;Password: &lt;/xforms:caption&gt;<br /><br />    &lt;/xforms:secret&gt;<br /><br />&lt;/p&gt;<br /><br /><br /><br />&lt;p&gt;<br /><br /><br /><br />    &lt;xforms:selectOne ref="preferences/seatingpreference" selectUI="listbox"&gt;<br /><br />        &lt;xforms:caption&gt;Area preference:   &lt;/xforms:caption&gt;<br /><br />        &lt;xforms:item&gt;<br /><br />            &lt;xforms:value&gt;1&lt;/xforms:value&gt;<br /><br />            &lt;xforms:caption&gt;One&lt;/xforms:caption&gt;<br /><br />        &lt;/xforms:item&gt;<br /><br />        &lt;xforms:item&gt;<br /><br />            &lt;xforms:value&gt;2&lt;/xforms:value&gt;<br /><br />            &lt;xforms:caption&gt;Two&lt;/xforms:caption&gt;<br /><br />        &lt;/xforms:item&gt;<br /><br />        &lt;xforms:item&gt;<br /><br />            &lt;xforms:value&gt;3&lt;/xforms:value&gt;<br /><br />            &lt;xforms:caption&gt;Three&lt;/xforms:caption&gt;<br /><br />        &lt;/xforms:item&gt;<br /><br />    &lt;/xforms:selectOne&gt;<br /><br /><br /><br />&lt;/p&gt;<br /><br />&lt;p&gt;<br /><br />    &lt;xforms:submit&gt;<br /><br />        &lt;xforms:caption&gt;Submit Report&lt;/xforms:caption&gt;<br /><br />    &lt;/xforms:submit&gt;<br /><br />&lt;/p&gt;<br /><br /><br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /><br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<b>术语说明</b>：XForms 建议书特别说明了不存在单个表单的 XForms。它是多个 XForms 页面，不再是单个 XForm 页面。
      </p>
		<p>表单一般需要进行验证。换句话说，数据字段必须包含有效数据等。XForms
使用 XML 模式来约束所提交的数据。另外，可以通过添加 XML Events（它也包括在 XHTML 2.0 中）来进一步增强 XForms 页面的功能。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="6">
						<span class="atitle">XML Events</span>
				</a>
		</p>
		<p>您可能已经熟悉了通过添加如 
        <code>onclick</code> 和 
        <code>onmouseover</code> 之类的事件在 Web 页面上使用事件。不会再有了。这些熟悉的属性已经被集成到
XHTML 2.0 中的 XML Events 模块所替代。XML Events 提供了一种通用的方法来指定事件发生时应该采取的操作。
它的优点是您不受限于如鼠标单击之类的预定义事件。
相反，可以定义您自己的事件以及触发它们时会发生什么。
      </p>
		<p>XML Events 包含下列组件。如鼠标单击之类的事件可以作为目标。例如，在
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code7">清单 7</a>所示的页面中：
      </p>
		<br />
		<a name="code7">
				<b>清单 7. 要单击的页面</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />
														<br />
														<br />&lt;html&gt;<br /><br />  &lt;head&gt;&lt;title&gt;Rides&lt;/title&gt;&lt;/head&gt;<br /><br />  &lt;body&gt;<br /><br />     &lt;ul id="ridelist"&gt;<br /><br />        &lt;li href="monorail.html"&gt;Monorail&lt;/li&gt;<br /><br />        &lt;li href="Matterhorn.html"&gt;Matterhorn&lt;/li&gt;<br /><br />        &lt;li href="coaster.html"&gt;Roller coaster&lt;/li&gt;<br /><br />     &lt;/ul&gt;<br /><br />  &lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>用户可能单击第二个 
        <code>li</code> 元素 Matterhorn。当这发生时，鼠标单击事件从文档根行进到目标（ 
        <code>li</code> ）并再次返回。顺序是：
      </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />(root) -- html -- body -- ul -- li -- ul -- body -- html -- (root)<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>向下行进到目标称为捕捉
（capture）阶段，而再次向上行进称为冒泡（bubbling）阶段（并不是所有的事件都会冒泡）。在行进期间的任何时候，事件都可以传递已经被注
册为观察器的对象（这表示它正在观察特定的事件），如果它看到事件，则执行特定操作。侦听器创建观察器。例如，在下面的序列中：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;ev:listener observer="ridelist" event="mousedown" handler="#myscript"/&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>侦听器使 
        <code>ul</code> 元素（或者更准确一点说，是整个列表）成为观察器，
因而，当用户单击任何列表项目时，观察器（ 
        <code>ridelist</code> ）执行 
        <code>myscript</code> （但仍必须确定调用任意脚本的机制）。
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="7">
						<span class="atitle">XFrames</span>
				</a>
		</p>
		<p>

广受指责的框架也在 XHTML 2.0 中被替换了。XFrames
的第一个工作草案于 2002 年 8 月 6 日初次登场，此前一天 XHTML 2.0 宣布它将使用 XFrames 并试图解决传统 HTML 框架出现的问题。
大多数问题是有关难于创建书签和刷新页面，以及不支持框架的搜索引擎无法索引适当内容。</p>
		<p>在 XFrames 文档中，所包含内容的 URI 成为整个文档 URI 的一部分。
例如，下面 
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#code8">清单 8</a>中的页面可能表示带三个框架的 HTML 页面：
      </p>
		<br />
		<a name="code8">
				<b>清单 8. XFrames 页面</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;html&gt;<br /><br />&lt;head&gt;&lt;title&gt;XFrames&lt;/title&gt;&lt;/head&gt;<br /><br />&lt;body&gt;<br /><br />&lt;row&gt;<br /><br />    &lt;frame id="header" /&gt;<br /><br />    &lt;column&gt;<br /><br />        &lt;frame id="menu"/&gt;<br /><br />        &lt;frame id="content"/&gt;<br /><br />    &lt;/column&gt;<br /><br /><br /><br />&lt;/row&gt;<br /><br />&lt;/body&gt;<br /><br />&lt;/html&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>请注意，没有指定每个框架的 URI，但每个框架都有其自己唯一的标识符。
因此，这个文档的 URI 可能是：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />site.xfm#frames(header=header.xhtml,menu=menu.xhtml,content=main.xhtml)<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>然后，理解 XFrames 的浏览器将每个框架的内容与适当的 URI 相关联。当用户单击链接并更改个别框架的内容时，页面的整个 URI 都会更改，
所以它始终显示用户正在查看的实际内容，“收藏”和“后退”按钮提供了准确的内容。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="8">
						<span class="atitle">图像作为对象</span>
				</a>
		</p>
		<p>
2002 年 8 月 5 日工作草案的最后一个主要的更改包括
除去了 
        <code>img</code> 标记并用 
        <code>object</code> 标记替代它。 
        <code>object</code> 标记实际上在 HTML 4.01 中就已经出现，
但开发人员主要将它用于嵌入多媒体和 Java applet。
然而，它一直都能支持图像。使用 object 标记的主要优点在于，它被设计成向下级联。
换句话说，如果浏览器不能显示一个特定对象，那么它将显示该对象的内容。
例如，遇到下列代码片断的浏览器首先试图装入电影。如果装入电影失败，则装入图像。如果装入图像失败，那么它只显示文本。
      </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;object data="rides.mpeg" type="application/mpeg"&gt;<br /><br />    &lt;object data="rollercoaster.jpg" type="image/jpg"&gt;<br /><br />        Jack tries to expand his horizons on the racing coasters.<br /><br />    &lt;/object&gt;<br /><br />&lt;/object&gt;<br /><br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="9">
						<span class="atitle">后续步骤</span>
				</a>
		</p>
		<p>

2002 年 8 月 5 日的 XHTML 2.0 工作草案中唯一可以确定的事就是不能确定任何事情。
在现在的草案和被作为建议书采纳的过程中，几乎可以肯定它将在某些方面发生变化，
但强调结构和语义的目标不可能变化。出于这个原因，
最好研究您现在构建的页面，并开始养成适当使用结构和样式的习惯。
使用标记来指定某些事物是什么，而不是如何显示它们，并使用 CSS 来完成其余工作。
总的来说，更多地考虑文档的结构以及您想要它们干什么，而不必太多地考虑它们将如何显示。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的
          <a href="http://www.ibm.com/developerworks/library/wa-xhtml/index.html">英文原文</a>.
        <br /><br /></li>
				<li>请参阅
          <a href="http://www.w3.org/TR/xhtml2">XHTML 2.0</a>的最新版本，以了解它目前包含哪些内容。
        <br /><br /></li>
				<li>请查找有关如何用
          <a href="http://www.w3.org/TR/xml-events">XML Events</a>控制页面和任何 XML 文档中事件的信息。
        <br /><br /></li>
				<li>请阅读使用
          <a href="http://www.w3.org/TR/xforms/">XForms</a>的下一代 Web 表单。
        <br /><br /></li>
				<li>请阅读文章“
          <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xforms/index.shtml">Get ready for XForms</a>”（
          <i>developerWorks</i>，2002 年 9 月），
学习有关 XForms 的更多知识。
        <br /><br /></li>
				<li>请快速阅读
          <a href="http://www.w3.org/TR/xframes/">XFrames</a>。
        <br /><br /></li>
				<li>请阅读
          <a href="http://www.w3.org/TR/xhtml-modularization">Modularization of XHTML</a> 或阅读

          <i>developerWorks</i>Web 体系结构专区上的
          <a href="http://www.ibm.com/developerworks/cn/cnedu.nsf/xml-onlinecourse-bytitle/95279FA45716812B48256B5400285DDE?OpenDocument">XHTML的模块化</a>教程（2001 年 10 月），了解 XHTML 2.0 是如何构造的。
        <br /><br /></li>
				<li>请在
          <a href="http://www.xml.com/pub/a/2002/08/07/deviant.html">XHTML 2.0 The Latest Trick</a>
中参考 Kendall Grant Clark 有关 XHTML 2.0 以及 Semantic Web 的注释。
        <br /><br /></li>
				<li>请在
          <a href="http://www.xml.com/pub/a/2002/03/13/xlink.html">XLink: Who Cares?</a> 中阅读
Bob DuCharme 有关 XLink 及其前景的想法。

        <br /><br /></li>
				<li>下载
          <a href="http://www.x-smiles.org/">X-Smiles</a>，它是一种 XForms 浏览器。
        <br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-wa-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Nicholas
Chase 曾参与过很多公司（如 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa
Bay Buccaneers 等）的网站开发。Nick 曾是一名高中物理教师、低辐射废物设备管理人员、在线科幻杂志编辑、多媒体工程师和
Oracle 讲师。
最近，他成为 Site Dynamics Interactive Communications（位于佛罗里达州的 Clearwater）的
CTO，
而且还是三本有关 Web 开发书籍的作者，包括 <i>Java and XML from Scratch</i>(Que) 和即将出版的
        <i>Primer Plus XML Programming</i>(Sams)。他乐意听取读者意见，可以通过
        <a href="mailto:nicholas@nicholaschase.com">nicholas@nicholaschase.com</a>与他联系。
      </p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:52 <a href="http://www.blogjava.net/Vencent/articles/35976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web 的未来是语义的:存在论形成了理解在线数据的整套全新方式的核心</title><link>http://www.blogjava.net/Vencent/articles/35977.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:52:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35977.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35977.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35977.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35977.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35977.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#author">Naveen Balani</a>, 技术架构师, Webify Solutions<br /></p>
		<p>2005 年  12 月  12 日</p>
		<blockquote>Naveen Balani 在向您介绍组织如何利用基于存在论开发的同时，还探索了语义 Web 技术的基础。语义 Web 有助于有效的知识管理和有成本效益的产品生命周期自动化，实现更快的开发和集成过程。</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>一般来说，<i>语义学（semantics）</i> 研究的是意义。（“semantic”这个词来自希腊语 <i>semantikos</i>，或者说“显著意义”，派生于 <i>sema </i>，或者说“标记（sign）”）。语义 Web 技术有助于利用基于开放标准的技术，从数据、文档内容或应用程序代码中分离出意义。如果计算机理解文档的<i>语义</i>，那么它就不仅仅是解释构成文档的一系列字符：它能够理解文档的<i>意义</i>。
			</p>
		<p>语义 Web 提供了公共的框架，允许在应用程序之间、企业之间和社区边界之间共享和重用数据。可以把语义 Web 想像成在万维网世界中表示数据的有效途径，或者把它当成一种数据库，用某种能够由机器理解的方式，链接到全球 Web 文档中的内容。语义技术用<i>存在论（ontology）</i> 表示意义，并通过这些存在论中表示的关系、规则、逻辑和条件来提供推理。</p>
		<p>
				<a name="1">
						<span class="atitle">构成语义 Web 的技术</span>
				</a>
		</p>
		<p>要表示语义 Web，需要使用以下技术：</p>
		<ul>
				<li>全球性的命名方案（URI）</li>
				<li>描述数据的标准语法（RDF）</li>
				<li>描述数据属性的标准机制（RDF Schema）</li>
				<li>描述数据条目间关系的标准机制（用 OWL Web 存在论语言定义的存在论）</li>
		</ul>
		<p>我们来深入研究这些技术。</p>
		<p>
				<a name="1.1">
						<span class="smalltitle">全球性的命名方案：URI </span>
				</a>
		</p>
		<p>
				<i>URI</i> 就是 Web 标识符，就像在万维网上经常看到的用 <code>http</code> 或 <code>ftp</code>
开始的字符串。任何人都可以创建 URI，而且 URI 的所有权委托得很清晰，所以它们构成了理想的技术基础，可以在其上构建全球性的
Web。实际上，万维网就是这样的：任何拥有 URI 的事物都被认为是“在 Web 上”。语义 Web
中的每个数据对象和每个数据模式/模型都必须拥有惟一的 URI。</p>
		<p>
				<i>统一资源定位符（URL）</i> 是一种 URI，除了标识资源外，通过描述资源的主要访问机制或网络位置，URL 还提供了对资源的表示进行操作或获取的方式。例如，URL <code>http://www.webifysolutions.com</code> 是一个 URI，标识了一个资源（Webify Solutions 的主页），还代表这个资源的表示形式（例如主页目前的 HTML 代码，作为编码字符）是可以从名为 <code>www.webifysolutions.com</code> 的网络主机通过 HTTP 得到的。</p>
		<p>
				<i>统一资源名称（URN）</i> 也是一种 URI，根据特定名称空间中的名称来标识资源。可以用 URN 表示资源，而不用指明资源的位置或者如何取消对它的引用。例如，URN <code>urn:ISBN:1-0-7666-98-0</code> 是一个 URI，像 ISBN 图书编号一样，它允许您谈到一本书，但是并未指明在哪里能实际得到它的拷贝和如何得到。</p>
		<p>
				<a name="1.2">
						<span class="smalltitle">描述数据的标准语法：RDF</span>
				</a>
		</p>
		<p>
				<i>RDF</i>
是一个规范，它定义了表达世界的模型，定义了序列化和交换这个模型的语法。W3C 已经开发了 RDF 的 XML 序列化。RDF XML 是语义
Web 上 RDF 的标准交换格式，虽然它并不是惟一的格式。例如，Notation3 是可以替代 RDF XML 的一种优秀的纯文本序列化方式。</p>
		<p>RDF
提供了一致的、标准化的方式来描述和查询 Internet
资源，资源从文本页面和图片一直到音频文件和视频剪辑。它提供了句法的互操作性，还提供了构建语义 Web 的基础层。RDF
定义了关系的导向图。这些是由对象-属性-值三元组表示的 —— 即对象 O 拥有属性 A，属性 A 的值是 V。</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#code1">清单 1</a> 提供了 RDF XML 的示例。</p>
		<br />
		<a name="code1">
				<b>清单 1. RDF XML 示例</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />				&lt;?xml version="1.0"?&gt; <br />&lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" <br />             xmlns:contact="http://www.w3.org/2000/05/contact#"&gt;<br /><br />  &lt;contact:Company rdf:about="http://www.w3.org/Organization/contact#WebifySolutions"&gt;<br />    &lt;contact:name&gt;Webify Solutions&lt;/contact:name&gt;<br />    &lt;contact:mailbox rdf:resource="mailto:info@webifysolutions.com"/&gt;<br />    &lt;contact:phone&gt;1-800-4WEBIFY&lt;/contact:phone&gt;<br />   &lt;/contact:Company&gt;<br /><br />&lt;/rdf:RDF&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>清单 1 中的这段 RDF 基本上构成了关于一个资源的陈述，在这个示例中是公司 <code>http://www.w3.org/Organization/contact#WebifySolutions</code>。公司可以用 URI <code>http://www.w3.org/Organization/contact#WebifySolutions</code> 来标识；公司名称是 Webify Solutions，公司的电子邮件地址是 info@webifysolutions.com，公司的电话号码是 1-800-4WEBIFY。</p>
		<p>关系导向图如 <a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#figure1">图 1</a> 所示。</p>
		<br />
		<a name="figure1">
				<b>图 1. 描述 Webify Solutions 联系人细节的 RDF 图</b>
		</a>
		<br />
		<img alt="描述 Webify Solutions 联系人细节的 RDF 图" src="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/ontology_org.jpg" height="342" width="572" />
		<br />
		<p>
				<a name="1.3">
						<span class="smalltitle">描述数据属性的标准机制：RDF Schema</span>
				</a>
		</p>
		<p>
				<i>RDF Schema</i> 是 RDF 的语义扩展。它提供了描述相关资源以及这些资源之间关系的机制。</p>
		<p>RDF Schema 的类和属性系统与面向对象编程语言（比如 Java 语言）的类型系统类似。RDF 与许多这样的系统不同。RDF 词汇描述语言不是用实例的属性来定义类，而是用属性要在其上应用的资源类来描述属性。</p>
		<p>RDF 和 RDF Schema 都基于 XML 和 XML Schema。描述数据的标准（RDF）和描述数据属性的标准（RDF Schema）的存在，促进了从多个源读取和利用数据的工具集的开发。不同应用程序能够共享和利用数据的程度，有时叫做<i>句法互操作性（syntactic interoperability）</i>。这些数据操纵工具越标准化、越广泛，句法互操作性的程度就越高，那么使用语义 Web 方式取代点对点集成解决方案就越容易，也越有吸引力。</p>
		<p>要获取全套 W3C RDF Schema 数据模型和规范，请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#resources">参考资料</a>。</p>
		<p>
				<a name="1.4">
						<span class="smalltitle">
			描述数据项目间关系的标准机制：使用 OWL Web 存在论语言的存在论</span>
				</a>
		</p>
		<p>在多个应用程序可以真正理解数据并把它当作信息之前，语义的互操作性是必需的。语义互操作性就是正确地解析数据。它要求术语间的映射，映射又要求内容分析。</p>
		<p>这个内容分析要求正式和明确的域模型规范，规范定义了使用的术语和它们的关系。这类正式的域模型有时叫做<i>存在论</i>。存在论用类、子类和属性来定义数据模型。</p>
		<p>使
用 W3C 推荐的 OWL Web 存在论语言，可以表示存在论。OWL（存在论工作语言）添加了比 RDF 或 RDF Schema
更多的词汇来描述属性和类：除了其他东西之外，它还能描述类之间的关系（比如剥离）、
基数（例如“确切的一”）、等价、更丰富的属性类型化，以及属性的特征（比如对称性）。</p>
		<p>OWL Web
存在论语言设计用于的应用程序，不仅仅是向人类呈现信息，更需要处理信息的内容。OWL 既提供了正式的语义，又提供了附加的词汇，所以比起
XML、RDF 和 RDF Schema，对 Web 内容实现了更好的机器互操作性。OWL 有三个子语言：按表现能力降序排列，分别是 <i>OWL Full、OWL DL、</i> 和 <i>OWL Lite。</i></p>
		<ul>
				<li>
						<p>
OWL Web 存在论语言的总和叫做 <b>OWL Full</b>。OWL
Full 使用 OWL 语言的所有原始材料，并允许这些原生材料按任意方式与 RDF 和 RDF RDF Schema 组合。OWL Full
完全向上兼容 RDF，从句法上和语义上都兼容：任何合法的 RDF 文档也都是合法的 OWL Full 文档。要让推理软件支持 OWL Full
的每个特性是不太可能的，因为它提供了最大的表现力和 RDF 的句法自由，但是在计算上没有保证。
</p>
				</li>
				<li>
						<p>
								<b>OWL DL</b> 支持的用户需要在不损失计算完整性的前提下得到最大表现力。OWL DL 是 OWL Full 语言构造的子语言，但是有一些限制，比如<i>类型分离</i> （例如，类不能还是个体或属性，而属性不能还是个体或类）。</p>
				</li>
				<li>
						<p>
								<b>OWL Lite</b> 支持的用户需要分类层次结构和简单的约束特性。这个语言的优势在于理解和实现起来比前两个语言都容易；但是，它限制了表现力。例如，虽然 OWL Lite 支持基数约束，但是只支持基数值 0 或 1。</p>
				</li>
		</ul>
		<p>存在论的例子包括：Amazon.com 这样的在线购物站点的目录，UNSPSC （用于产品和服务的术语体系）这类特定域的标准术语体系，或者 Web 上各种各样的分类，比如“My Yahoo”分类。</p>
		<p>接下来，我将进一步研究 OWL 的组成部分。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">OWL Web 存在论语言的组成部分</span>
				</a>
		</p>
		<p>OWL 基本组成部分包括<i>类、属性</i> 和<i>个体</i>，下面将依次介绍它们。</p>
		<p>
				<a name="2.1">
						<span class="smalltitle">类</span>
				</a>
		</p>
		<p>
				<i>类</i> 是 OWL 存在论的基本构建块。类是域中的概念。类通常构成分类的层次结构（子类-超类的层次结构）。</p>
		<p>类是用 <code>owl:Class</code> 元素定义的。OWL 自带了两个预定义的类：<code>owl:Thing</code> 和 <code>owl:Nothing</code>。<code>owl:Thing</code> 是最通用的类，它包含任何东西；<code>owl:Nothing</code> 是一个空类。所有自定义的类都是 <code>owl:Thing</code> 的子类，是 <code>owl:Nothing</code> 的超类。银行领域的类的例子可能包括 <code>Account</code> 或 <code>Customer</code>。</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#listing2">清单 2</a> 展示了 OWL 类的一个示例。</p>
		<br />
		<a name="listing2">
				<b>清单 2. OWL 类示例</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;owl:Class rdf:ID="SavingsAccount"&gt;<br /> &lt;rdfs:subclassOf rdf:resource="#Account"/&gt;<br />&lt;/owl:Class&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#listing2">清单 2</a> 中的代码指定 <code>SavingAccount</code> 是一个类，而且是 <code>Account</code> 的子类。</p>
		<p>OWL 支持 6 种主要的描述类的方式。最简单的一种是<i>命名</i> 类。其他方式是<i>交叉</i> 类、<i>联合</i> 类、<i>补充</i> 类、<i>限制</i> 类和 <i>枚举</i> 类。清单 2 演示了两种描述类的方式：限制把 <code>SavingAccount</code> 定义为命名类 <code>Account</code> 的子类。要获得全套 W3C OWL 类规范，请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#resources">参考资料</a>。
</p>
		<p>
				<a name="2.2">
						<span class="smalltitle">属性</span>
				</a>
		</p>
		<p>属性有两大类：</p>
		<ul>
				<li>
						<i>对象属性</i>，它把个体关联到其他个体。</li>
				<li>
						<i>数据类型属性</i>，它把个体关联到数据类型的值，比如 integer、float 和 string 类型。Owl 利用 XML Schema 定义数据类型。</li>
		</ul>
		<p>属性可以有关联的域和范围。每个属性可以属于以下一个类别：</p>
		<ul>
				<li>
						<b>功能的：</b> 对于给定对象，属性只能有一个值。例子包括人的年龄、身高或体重。</li>
				<li>
						<b>反转功能的：</b> 两个不同个体不能拥有相同的值。例如，<code>bankNumber</code> 或 <code>SSN</code> 属性对每个人来说都是惟一的。</li>
				<li>
						<b>对称的：</b>如果某个属性把 A 链接到 B，那么就可以推断 B 链接到了 A。对称属性的例子包括：“兄弟”或“相同”。</li>
				<li>
						<b>传递的：</b>如果某个属性把 A 链接到 B，而 B 链接到 C，那么可以推断它也把 A 链接到了 C。例如，如果 A 比 B 高，B 比 C 高， 那么 A 比 C 高。</li>
		</ul>
		<p>可以对类和属性应用不同的限制。例如，基数限制指定某类个体可以参与的关系的数量。</p>
		<p>要获得全套 W3C OWL 规范，请参阅 <a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#resources">参考资料</a>。</p>
		<p>
				<a name="2.3">
						<span class="smalltitle">个体</span>
				</a>
		</p>
		<p>
				<i>个体</i> 是类的实例，属性可以把一个个体关联到其他个体。例如，可以把名为 <code>Smith</code> 的个体描述为 <code>Person</code> 类的实例，而且可能用 <code>hasEmployer</code> 属性把 <code>Smith</code> 关联到个体 <code>Webify Solutions</code>，表明 Smith 是 Webify Solutions 的员工。</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#code3">清单 3</a> 提供了 OWL 个体的一个示例。</p>
		<br />
		<a name="code3">
				<b>清单 3.  OWL 个体</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;owl:Thing rdf:about="SmithAccount"&gt;<br /> &lt;rdfs:type="#Account"/&gt;<br />&lt;/owl:Class&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<code>rdf:type</code> 是一个 RDF 属性，它把个体绑定到一个数字类。清单 3 表明 <code>SmithAccount</code> 是类型 <code>Account</code> 的一个实例。
</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#Figure2">图 2</a> 表示了 OWL 存在论的基本构造块。</p>
		<br />
		<a name="Figure2">
				<b>图 2. 描述 Webify Solutions 组织的 OWL 存在论</b>
		</a>
		<br />
		<img alt="描述 Webify Solutions 组织的 OWL 存在论" src="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/ontology_comp.jpg" height="479" width="538" />
		<br />
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="3">
						<span class="atitle">存在论的商业价值</span>
				</a>
		</p>
		<p>IT 系统用关系数据模型、扁平文件、面向对象模型或专用的数据模型来组织意义。变化的业务需求不断地要求向关系数据模型或面向对象模型中添加新实体和关系。</p>
		<p>而
且，如果组织采用了许多由不同开发商提供的应用程序，那么可能要在应用程序的数据库之间重复相同的模型。例如，银行公司提供了不同的产品，以服务不同类型
的客户。企业客户可能需要欺诈检测功能，而普通客户可能只使用在线银行功能。一般会有多个开发商为银行提供应用程序，但是每个应用程序都会在应用程序特定
的数据库中重复同样的公共信息 —— 帐户、客户，等等。当组织增加产品以满日益增长的业务需求时，相同的冗余信息就散落在整个企业中。</p>
		<p>对于所有这些正在开发的应用程序来说，绝对有许多服务是公共的 —— 例如查看银行交易和电汇。每个服务都要用每种应用程序特定的方式重复，从而导致点对点的集成。</p>
		<p>如
果银行采用了存在论驱动的方式，那么银行就可以用一种语言中立的形式来捕捉并表示它整体的产品知识，并把知识部署到中央仓库。使用这种共享的、适应性的存
在论，组织可以跨越应用程序，提供单一而统一的数据视图。这种统一的视图支持信息的精确检索和无缝的企业集成，同时业务过程和不同的数据源可以通过一个公
共的元模型彼此相互映射。这样，共享的存在论就消除了点对点集成，并简化了应用程序的集成，减少了数据冗余，在应用程序之间提供了相同的语义，从而方便了
银行的维护与升级。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="4">
						<span class="atitle">语义 Web 对万维网的好处</span>
				</a>
		</p>
		<p>
万维网是有史以来创建的最大的信息仓库，而且各种语言和各个知识领域的内容还在不断增长。但是，从长远看，让这种内容有意义是极端困难的。搜索引擎可能会
帮助找到包含特定词语的内容，但是内容可能并不是您确切想要的。那么缺少什么呢？搜索是基于页面内容的，而不是基于页面内容或页面信息的<i>语义</i>。</p>
		<p>一
旦语义 Web 存在，它就能够提供为 Web
内容做标记的能力，可以描述各部分内容是关于什么的，并给内容的项目提供语义。这样，搜索引擎会变得比现在更有效率，用户也会精确地找到所要寻找的信息。
提供不同的服务的组织可以给这些服务标记上意义；使用基于 Web 的软件代理，就可以动态地发现这些服务，并利用它们或让它们与其他服务协作。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="5">
						<span class="atitle">语义技术在 SOA 中的角色和价值</span>
				</a>
		</p>
		<p>要
想正确地建模和管理面向服务的架构（SOA），企业架构师必须维护企业可用服务的活动表示。具体来说，要发现和组织他们的服务，架构师就必须采用最佳实
践，用元数据来建模和组织他们的服务，把业务逻辑封装在元数据中进行动态绑定，并用元数据进行管理。存在论提供了非常强大和灵活的方式，可以聚合、可视化
和规范化这个服务元数据层。</p>
		<p>存在论就是概念、关系和约束的网络，为数据、信息以及过程提供了上下文。存在论增强了服务发现、建
模、汇集、协调和语义互操作性。它们改善了人们浏览、探索复杂的元数据空间以及和它们交互的方式。业务存在论是业务概念和它们之间关系的正式规范，促进了
机器的推理和判断。业务存在论用元数据把系统捆绑在一起，非常像数据库把离散的数据片断绑在一起。这一抽象提供了敏捷性和灵活性，因为接口可以改变，新的
资源和订阅者可以容易地加入，即使系统正在运行也可以。</p>
		<p>语义是面向服务集成的未来。语义技术提供了超越现有 IT
技术的抽象层，它支持跨越业务和 IT
领域之上的数据、内容和过程的沟通与互联。最后，从人类交互的角度来说，语义技术添加了新一级语义门户，比起目前使用的传统的点对点集成方式的基于门户的
信息发布，提供了更加智能、更加相关、上下文更敏感的交互。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="6">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>在
这篇文章中，您了解了构成语义 Web 技术的核心标准，以及为什么企业可能要采用这些技术。利用语义 Web
技术，组织可以跨越应用程序提供单一而统一的数据视图，这可以支持信息的精确检索，简化企业和 SOA
集成，减少数据冗余，并在应用程序之间提供一致的语义。所有这些会简化整个企业的开发、维护和升级。 </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 
          <a href="http://www.ibm.com/developerworks/web/library/wa-semweb/" target="_blank">英文原文</a><br /><br /></li>
				<li>“<a href="http://researchweb.watson.ibm.com/journal/sj/433/stojanovic.html">The role of ontologies in autonomic computing systems</a>”，作者 L. Stojanovic、J. Schneider、A. Maedche、S. Libischer、R. Studer、Th. Lumpp、A. Abecker、G. Breiter 和 J. Dinger （<i>IBM Research Journal</i>， 2004 年）：发现使用存在论描述与自主计算系统有关的知识和构造时的好处。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/cn/java/j-jena/">Jena 简介</a>”，作者 Philip McCarthy（developerWorks，2004 年 6 月）：在 Java 应用程序中，利用 Jena 语义 Web 框架使用 RDF 模型。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/xml/library/x-think9.html">Basic XML and RDF techniques for knowledge management</a>”，作者 Uche Ogbuji （developerWorks，2002 年 3 月）：查看知识管理技术的实用情况。<br /><br /></li>
				<li>“<a href="http://www-128.ibm.com/developerworks/cn/webservices/ws-designsoa/">使用 J2EE 技术设计面向服务的体系结构框架</a>”，作者 Naveen Balani （developerWorks，2004 年 1 月）：发现关于 SOA 编程的更多文章。<br /><br /></li>
				<li>“<a href="http://www-128.ibm.com/developerworks/cn/xml/x-dita10/">用 DITA 和 SKOS 进行主题分类</a>”（developerWorks，2005 年 10 月）：学习 SKOS（简单知识组织系统），管理主题问题的最新语义 Web 标准，以及如何用 SKOS 把正式的语义与文档内容集成。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java">developerWorks Java 技术专区</a>：发现更多针对 Web 架构开发人员的资源。<br /><br /></li>
				<li>参与 <a href="http://www.ibm.com/developerworks/blogs/">developerWorks
blogs</a>：加入 developerWorks 社区。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/owl-features/">OWL specification</a>, <a href="http://www.w3.org/TR/2002/WD-rdf-concepts-20021108/">RDF specification</a> 和 <a href="http://www.w3.org/TR/2002/WD-rdf-schema-20021112/">RDF Schema specification</a>：从 W3C 得到所有三个规范。<br /><br /></li>
				<li>
						<a href="http://logicerror.com/notation3">Notation3</a>：研究这个简单的语言，它可以把 RDF 陈述放在 ASICII 会话中，例如电子邮件中。</li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
						<a href="http://www.webifysolutions.com/">Webify Solutions</a>：IBM 按需优化合作伙伴。Webify 提供了存在论驱动的集成服务环境，能够达到和维护跨企业、跨应用程序和跨合作伙伴域的语义集成，从而帮助公司解决治理和敏捷性方面的挑战。<br /><br /></li>
				<li>
						<a href="http://www.alphaworks.ibm.com/tech/semanticstk">IBM Integrated Ontology Development Toolkit</a>：请购买这个工具包，它用于 IBM alphaWorks 上存在论驱动的开发。<br /><br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/java/wa-semweb/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Naveen
Balani 把自己的大部分时间花在设计和开发基于 J2EE 的框架和产品上。他为 IBM developerWorks
撰写了各种不同的文章，涉及的主题包括：ESB、SOA、JMS、Web 服务架构、CICS、AXIS、DB2、XML
Extender、WebSphere Studio、MQSeries、Java Wireless Devices and DB2
Everyplace for Palm、J2ME、MIDP、Java-Nokia、Visual Studio
.Net，以及无线数据同步。可以通过他的电子邮件 <a href="mailto:naveenbalani@rediffmail.com?cc=htc@us.ibm.com">naveenbalani@rediffmail.com</a> 与他联系。</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:52 <a href="http://www.blogjava.net/Vencent/articles/35977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XHTML：两种语言的力量:可扩展超文本标记语言是用 XML 对 HTML 4 的改良</title><link>http://www.blogjava.net/Vencent/articles/35973.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:51:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35973.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35973.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35973.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#author">Sathyan Munirathinam</a>, 软件工程师, Aztec Software<br /></p>
		<p>2002 年  7 月  01 日</p>
		<blockquote>本文从实际角度对 XHTML 进行了研究，它是有效地结合 HTML 的简单性和 XML 的可扩展性的一种标记语言。本文还涵盖了 XHTML 各种风格的基本特性并包括对语言和大量实际应用程序的讨论。</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>作为一
名 Web
开发人员是项很艰苦的工作。您不仅必须每天避开流行浏览器引起的陷阱和缺陷，还必须至少留意可能（或不可能）对您的工作产生影响的众多技术上的新发展。您
可能刚刚掌握了样式表和
DHTML，而新的技术又要求您关注。您需要立刻学哪一个呢？现在可以放弃哪一个呢？随着可扩展超文本标记语言（Extensible
Hypertext Markup Language，简称 XHTML）的出现，最终可能让传统的 HTML 马放南山了。</p>
		<p>
				<a name="N10046">
						<span class="atitle">XHTML 概述</span>
				</a>
		</p>
		<p>
XHTML 是 HTML 和 XML 的混合物，它是为网络设备显示（包括 Web 浏览器、PDA 设备和移动电话）而特别设计的。2002 年
1 月 26 日标志了 XHTML 1.0 作为 Web 标记的正式 W3C 推荐的第二个生日。但是，XHTML
仍然要蹒跚学步，学着用微笑和大喊大叫来引起大多数 Web 设计人员的注意。</p>
		<p>W3C
主管 Tim Berners-Lee 这样评价 XHTML：“XHTML 1.0 连接了现在的 Web 和将来的 Web ……
它为页面和网站作者提供了进入结构化数据 XML 世界的桥梁，同时仍然能够保持与支持 HTML 4 的用户代理的可操作性。"</p>
		<p>XHTML
是非常严格的标记语言。它的规则很简单，并且事实上，它的可扩展性很小 ―
即，不能编写您自己的定义来表示语言如何动作；您必须遵循其规则。XHTML 1.0 采用 HTML 4.0
中引入的概念，这些概念在其生效之前，需要按结构化的和方法论的行为进行处理。</p>
		<p>XHTML
可以与级联样式表（CSS）一起使用以完成显示目的。XHTML 还允许您将可扩展样式表（Extensible Stylesheet
Language (XSL)）用于转换。通过使用这个基于 XML 的样式技术，您实际上可以将一个文档从一种类型转换成另一种类型 ― 例如，从
HTML 文档转换成 PDF 文档。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10058">
						<span class="atitle">为什么要使用 XHTML？</span>
				</a>
		</p>
		<p>
通常，您可能为新增功能或者因为已经修正了以前版本的问题而将技术更新到新的版本。但就标记功能而言，XHTML 是非常类似于 HTML 4 的副本，所以不要期望存在任何新奇的标记。</p>
		<p>W3C 声称 XHTML 的主要优点是
        
        <i>可扩展性</i>和
        
        <i>可移植性</i>：
      
      </p>
		<p>
				<a name="N1006A">
						<span class="smalltitle">可扩展性</span>
				</a>
		</p>
		<p>
XML 文档要求格式良好（元素嵌套正确）。使用 HTML，添加新的元素组需要更改整个 DTD。在基于 XML 的 DTD 中，新的元素组只需要内部一致并且格式良好，就可以添加到现有的 DTD 中。这极大地简化了新元素集合的开发和集成。</p>
		<p>
				<a name="N10073">
						<span class="smalltitle">可移植性</span>
				</a>
		</p>
		<p>
越来越频繁地使用非台式设备来访问因特网文档。在大多数情况下，这些设备不具备台式计算机的计算能力，并且不象标准桌面浏览器那样可适用于格式差的
HTML。实际上，如果这些非桌面浏览器没有接收到格式良好的标记（HTML 或 XHTML），它们可能根本无法显示文档。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1007C">
						<span class="atitle">XHTML 文档结构</span>
				</a>
		</p>
		<p>
XHTML 文档由三个主要部分构成：</p>
		<ul>
				<li>DOCTYPE</li>
				<li>Head</li>
				<li>Body</li>
		</ul>
		<p>基本文档结构是：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;!DOCTYPE ...&gt;<br />&lt;html  ... &gt;<br />&lt;head&gt; ... &lt;/head&gt;<br />&lt;body&gt; ... &lt;/body&gt;<br />&lt;/html&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<code>&lt;head&gt;</code> 区域包含关于文档的信息，如所有权、版权和关键字；而 
        
        <code>&lt;body&gt;</code> 区域包含要显示的文档内容。
      
      </p>
		<p>清单 1 向您显示实际中如何使用这个结构：</p>
		<br />
		<a name="code1">
				<b>清单 1. XHTML 示例</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />1.  &lt;?xml version="1.0"?&gt;<br />2.  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0   <br />    Transitional//EN"  "DTD/xhtml1-transitional.dtd"&gt;<br />3.  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"  <br />                     lang="en"&gt;<br />4.  &lt;head&gt;<br />    &lt;title&gt;My XHTML Sample Page&lt;/title&gt;<br />    &lt;/head&gt;<br />5.  &lt;body bgcolor="white"&gt;<br />    &lt;center&gt;&lt;h1&gt;Welcome to XHTML !&lt;/h1&gt;&lt;/center&gt;<br />    &lt;/body&gt;<br />6.  &lt;/html&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<b>第 1 行：</b>由于 XHTML 是以 XML 文档表示的 HTML，所以它必须在文档的顶部包括初始 XML 声明 
        
        <code>&lt;?xml version="1.0"?&gt;</code> 。
      
      </p>
		<p>
				<b>第 2 行：</b>XHTML
文档必须由三组标准规则的其中一组来标识。这些规则存储在一个称为“文档类型声明（Document Type Declaration
(DTD)）”的单独文档中，并且使用这些规则验证 XHTML 文档结构的准确性。准确地说，DTD 的目的是描述 XHTML
中允许的语言和语法。 </p>
		<p>
				<b>第 3 行：</b>XHTML 文档中的第二个标记必须包括带有由 
        
        <code>xmlns=http://www.w3.org/1999/xhtml</code> 属性标识的 XML 名称空间的开始 &lt;html&gt; 标记。XML 名称空间标识 XHTML 文档使用的标记的范围。它用来确保一个 DTD 使用的名称不与用户定义的标记或其它 DTD 中定义的标记冲突。
      
      </p>
		<p>
				<b>第 4 行：</b>XHTML 文档必须包括完整的头部区域。这个区域包含开始 
        
        <code>&lt;head&gt;</code> 标记和标题标记（ 
        
        <code>&lt;title&gt;&lt;/title&gt;</code> ），然后以结尾 
        
        <code>&lt;/head&gt;</code> 标记结束。
      
      </p>
		<p>
				<b>第 5 行：</b>XHTML 文档必须包含开始和结尾 
        
        <code>&lt;body&gt;&lt;/body&gt;</code> 标记。在这些标记中，您可以放置传统的 HTML 编码标记。要与 XHTML 符合，这些标记的编码必须是格式良好的。
      
      </p>
		<p>
				<b>第 6 行：</b>最后，使用结尾 
        
        <code>&lt;/html&gt;</code> 标记结束 XHTML 文档。
      
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100F0">
						<span class="atitle">XHTML DTD</span>
				</a>
		</p>
		<p>
在创建 XHTML 文档时，在该文档的顶部声明了它应符合的 DTD。每个 DTD 可能由一个称为
        
        <i>正式公共标识（Formal Public Identifier</i>，简称 FPI）的唯一标号识别。字 
        
        <code>PUBLIC</code> 后面的文字文本或引用文本是表示 W3C 的 XHTML 1.0 DTD 的 FPI。
      
      </p>
		<p>目前，有三种 XHTML 文档类型：</p>
		<ul>
				<li>Strict</li>
				<li>Transitional</li>
				<li>Frameset</li>
		</ul>
		<p>
				<a name="N1010F">
						<span class="smalltitle">Strict DTD</span>
				</a>
		</p>
		<p>
		</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" <br />		"DTD/xhtml1-strict.dtd"&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当您想要真正清晰的标记、避免表示上的混乱时，将此与 CSS 一起使用。已经从该语言中除去了几个标记（如 
        
        <code>&lt;center&gt;</code> ），甚至还除去了其它标记的某些属性（如 H1 标记的 
        
        <code>align</code> 属性）。
      
      </p>
		<p>
				<a name="N10126">
						<span class="smalltitle">Transitional DTD</span>
				</a>
		</p>
		<p>
		</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"<br />		"DTD/xhtml1-transitional.dtd"&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当您需要利用 HTML 的表示特性时，使用它；您的许多读者都没有能理解 CSS 的最新浏览器。过渡的 DTD 支持大部分标准的 HTML 4 标记和属性。</p>
		<p>
				<a name="N10135">
						<span class="smalltitle">Frameset DTD</span>
				</a>
		</p>
		<p>
		</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;! DOCTYPE html PUBLIC 	"-//W3C//DTD XHTML 1.0 Frameset//EN"<br />		"DTD/xhtml1-frameset.dtd"&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这使您能够使用 HTML 框架将浏览器窗口分成两个或更多框架。这个 DTD 保存框架集定义。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10144">
						<span class="atitle">XHTML 验证规则</span>
				</a>
		</p>
		<p>
XHTML 文档
        
        <i>必须</i>是格式良好的 XML。它必须符合基本 XML 语法：
      
      </p>
		<p>
				<b>必须用小写书写标记和属性名称。</b>
		</p>
		<table border="1" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="top">
								<td>
										<b>HTML</b>
								</td>
								<td>
										<b>XHTML</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;TD BGCOLOR="#ffcc33"&gt;</code>
								</td>
								<td>
										<code>&lt;
              
              <span class="boldcode">td bgcolor</span>="#ffcc33"&gt;
            
            </code>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<b>元素必须嵌套；而不能交错。</b>对于 XML 和 XHTML，您需要以逆序关闭标记 ― 换言之：后开先关。
      
      </p>
		<table border="1" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="top">
								<td>
										<b>HTML</b>
								</td>
								<td>
										<b>XHTML</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;p&gt;Be &lt;b&gt;bold!&lt;/p&gt;&lt;/b&gt;</code>
								</td>
								<td>
										<code>&lt;p&gt;Be &lt;b&gt;bold!
              
              <span class="boldcode">&lt;/b&gt;&lt;/p&gt;</span></code>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<b>所有非空元素必须是关闭的。</b>例如，对于 HTML，许多人使用 
        
        <code>&lt;p&gt;</code> 标记分段。这个标记设计用于标记一段的开始和结尾（使用结尾 
        
        <code>&lt;/p&gt;</code> 标记）。这使它成为
        
        <i>非空</i>标记，因为它包含段文本。
      
      </p>
		<table border="1" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="top">
								<td>
										<b>HTML</b>
								</td>
								<td>
										<b>XHTML</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>First paragraph&lt;p&gt;
Second paragraph&lt;p&gt;</code>
								</td>
								<td>
										<code> &lt;p&gt;First paragraph&lt;/p&gt;
&lt;p&gt;Second paragraph
              
              <span class="boldcode">&lt;/p&gt;</span></code>
								</td>
						</tr>
				</tbody>
		</table>
		<p>受
影响的元素：&lt;basefont&gt;、&lt;body&gt;、&lt;colgroup&gt;、&lt;dd&gt;、&lt;
dt&gt;、&lt;head&gt;、&lt;html&gt;、&lt;li&gt;、&lt;p&gt;、&lt;tbody&gt;、&lt;
thead&gt;、&lt;tfoot&gt;、&lt;th&gt;、&lt;td&gt; 和 &lt;tr&gt;。</p>
		<p>
				<b>必须终止空元素。</b>所有空元素必须使用 XML
        
        <i>空标记</i>语法，在右括号前有一个结尾的正斜杠（例如， 
        
        <code>&lt;br&gt;</code> becomes 
        
        <code>&lt;br /&gt;</code> ）。请注意元素文本后面的空格和结束定界符 
        
        <code>/&gt;</code> 。这是为了与当前浏览器兼容。

      
      </p>
		<table border="1" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="top">
								<td>
										<b>HTML</b>
								</td>
								<td>
										<b>XHTML</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;hr&gt;</code>
								</td>
								<td>
										<code>&lt;hr /&gt;</code>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;br&gt;</code>
								</td>
								<td>
										<code>&lt;br /&gt;</code>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;input ... &gt;</code>
								</td>
								<td>
										<code>&lt;input ... /&gt;</code>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;param ... &gt;</code>
								</td>
								<td>
										<code>&lt;param ... /&gt;</code>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;img src="valid.gif"&gt;</code>
								</td>
								<td>
										<code>&lt;img src="valid.gif" /&gt;</code>
								</td>
						</tr>
				</tbody>
		</table>
		<p>受
影响的元素：&lt;area&gt;、&lt;base&gt;、&lt;br&gt;、&lt;col&gt;、&lt;frame&gt;、
&lt;hr&gt;、&lt;img&gt;、&lt;input&gt;、&lt;isindex&gt;、&lt;link&gt;、&lt;
meta&gt;、&lt;option&gt; 和 &lt;param&gt;。</p>
		<p>
				<b>属性值必须加引号。</b>不再有 
        
        <code>&lt;img ... border=0&gt;</code> 了。现在，您需要给每个属性加引号，即使它是数字。
      
      </p>
		<table border="1" cellpadding="3" cellspacing="0" width="100%">
				<tbody>
						<tr valign="top">
								<td>
										<b>HTML</b>
								</td>
								<td>
										<b>XHTML</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<code>&lt;img ... border=0&gt;</code>
								</td>
								<td>
										<code>&lt;img ... border=
              
              <span class="boldcode">"0"</span> /&gt;
            
            </code>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<b>不能最小化属性值对。</b>不允许单独属性（也称为最小化的属性）。例如， 
        
        <code>&lt;option selected&gt;</code> 不再有效了。而您必须使用 
        
        <code>&lt;option selected="selected"&gt;</code> 。
      
      </p>
		<p>
				<b>内联标记不能包含块级别标记。</b>例如，锚点标记不能括起表。
      
      </p>
		<p>
				<b>脚本编制元素引起了 XHTML 兼容性问题。</b>XML 解析器将脚本解析成 XML 文档，除非您将脚本封装入 CDATA 块中。因此，JavaScript 元素现在将类似于：
      
      </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;script type="text/javascript"&gt;<br />&lt;![CDATA[ alert("hello"); ]]&gt;<br />&lt;/script&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这对于大多数的当前浏览器来说，可能都有问题，因为它们不喜欢 CDATA 块。目前，唯一的解决方案是从外部文件调用 JavaScript。例如：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;script language="JavaScript" type="text/javascript" src="main.js"&gt;&lt;/script&gt; <br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>对于服务器端程
序员，当动态修改 JavaScript 时，这会产生问题。对您的 JavaScript 使用独立的文件源会阻止您动态地更改
JavaScript。因为 JavaScript 包括在客户机端，所以服务器端不能接触到它。当使用 ASP、JSP 或 PHP 脚本编制修改
JavaScript 时使用脚本声明的标准 HTML 方法。这正是在使 JSP 或 ASP 100% 与 XHTML
兼容时最可能产生问题的地方。不过，请记住，目的并不是与 XHTML 100% 兼容，而是在可行的情况下开始结合
XHTML，使得需要时允许快速和简单的过渡。那时，应该可以使用新的兼容浏览器，您将开始跨越到 100% 兼容性。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N102DB">
						<span class="atitle">代替 CHTML 和 WML 的 XHTML Basic</span>
				</a>
		</p>
		<p>
对于想创建网站移动版本的开发人员来说，根本问题是他们当前必须用 HTML 将页面格式化以便进行桌面浏览，对于 WAP
设备，可以用无线标记语言（Wireless Markup Language (WML)）；对于 iMode 设备可以用压缩
HTML（Compact HTML (CHTML)）。这已经产生了一个新的行业，致力于将现有的网站转换成 WML 或 CHTML。WML 基于
XML，并且取代了快过时的手持设备标记语言（Handheld Device Markup Language (HDML)），而 CHTML
是基于 HTML 的。虽然这些标记语言很相似，但它们之间的区别使得 WAP 和 iMode 设备都不能看见 Web 页面。而所有设备都将理解
XHTML Basic，并且它将成为一种通用标记语言。</p>
		<p>可以获取多种格式的完整 XHTML Basic 英文规范（请参阅
        
        <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#resources">参考资料</a>），这些格式包括 HTML、纯文本、PostScript 和 PDF。可以预见 XHTML Basic 代替诸如 HDML 和 WML 的语言将是不可避免的。但是，重要的是记住 WML 和 HDML 还定义
        
        <i>操作</i>和内容。目前，这些在 XHTML 中还没有等价定义。因此，至少在短期内，WML 和 HDML 将不会消失。看谁会最终胜出将很有意思。在某种程度上计划支持所有这三种标记语言。
      
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N102EE">
						<span class="atitle">XHTML 中的未来工作</span>
				</a>
		</p>
		<p>
XHTML 中仍在开发的一方面是
        
        <i>设备概要</i>，
也称为复合能力首选项概要文件（Composite Capability Preference Profiles (CCPP)）。CCPP
允许诸如移动电话之类的设备向 Web 服务器标识自己、描述其限制并只下载其能够显示的信息。因为可以将 XHTML
文档分割成能够被单独下载的多个模块，所以 CCPP 能起作用。 </p>
		<p>W3C 正在与 WAP Forum 等合作开发 CCPP。2001
年夏季，开始 XHTML 2.0 开发，它是结合 HTML 和 XML 的最后一步。XHTML 2.0 是前瞻性的，因为它是几种 XML
技术的结合体，例如 XLink、XPointer、XPath 和 XInclude ― 所有这些技术当前处于开发过程中或者最近由 W3C
发布（请 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#resources">参考资料</a>中的路标）。
      
      </p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10301">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>
XHTML 开辟了 Web 的新领域，为作者提供了在其 Web 页面上混合和匹配各种基于 XML 的语言和文档的方法。它还为非传统 Web
访问设备（从烤箱到电视机）提供了框架以向 Web 服务器标识它们自己及其能力，只要下载那些设备能显示的信息。多亏有了
XHTML，您可以继续使用您已经熟悉和喜爱的 HTML 编写。可能只需要稍微整理一下。我猜测 XHTML 2.0（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#resources">参考资料</a>）将具体地整理 HTML 标记及其用法。
      
      </p>
		<p>总之，XHTML 简化了可以让各种新设备浏览的文档的创建。另外，经过少许学习，您可以创建比以往功能强大得多的页面。最后，XHTML 是通向 XML ― 因特网的未来语言的桥梁。
</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的
          
          <a href="http://www.ibm.com/developerworks/library/x-xhtml.html">英文原文</a>.
        
        <br /><br /></li>
				<li>请通过单击本文顶部或底部的
          
          <b>讨论</b>来参与本文的
          
          <a href="javascript:void forumWindow()">论坛</a>。
          
          <br /><br /><br /></li>
				<li>查看
          
          <a href="http://www.w3.org/TR/xhtml1/">W3C XHTML 1.0 规范</a>，它将 HTML 4 的改造定义成一种 XML 1.0 应用程序，并且定义了三个与 HTML 4 定义的 DID 相应的 DTD。
          
          <br /><br /><br /></li>
				<li>查看
          
          <a href="http://www.xhtml.org/">XHTML.org</a>以获取关于 XHTML 的新闻和信息。
          
          <br /><br /><br /></li>
				<li>请阅读
          
          <a href="http://www.wdvl.com/Authoring/Languages/XML/XHTML/">XHTML 的简介和概述</a>，它包括对 XHMTL 和 HTML 4 之间区别的说明。
          
          <br /><br /><br /></li>
				<li>查找关于
          
          <a href="http://www.w3.org/TR/xhtml-basic/">XHTML Basic</a>的更多信息。
          
          <br /><br /><br /></li>
				<li>查看
          
          <a href="http://www.w3.org/MarkUp/xhtml-roadmap/">HTML Working Group Roadmap</a>，它描绘了 XHTML 未来发展的清晰蓝图，包括关于 XHTML 2.0 的信息。
          
          <br /><br /><br /></li>
				<li>查看
          
          <a href="http://encyclozine.com/Directory/map.shtml">Encyclozine.com</a>，它是用 XHTML 构建的站点示例。
          
          <br /><br /><br /></li>
				<li>要验证 XHTML 页面，请尝试
          
          <a href="http://validator.w3.org/">W3C HTML 验证服务</a>。
          
          <br /><br /><br /></li>
				<li>在
          
          <a href="http://www-128.ibm.com/developerworks/cn/xml/index.shtml">developerWorks XML 技术专区</a>中查找更多 XML 参考资料。
          
          <br /><br /><br /></li>
				<li>在
          
          <a href="http://www.ibm.com/developerworks/web/">developerWorks 网站架构主题</a>中查找更多 Web 参考资料。
          
          <br /><br /><br /></li>
				<li>获取
          
          <a href="http://www-4.ibm.com/software/ad/studioappdev/&amp;origin=x&amp;origin=x">IBM WebSphere Studio Application Developer</a>，它是一个易于使用的集成开发环境，用于构建、测试和部署 J2EE 应用程序，包括从 DID 和模式生成 XML 文档。
          
          <br /><br /><br /></li>
				<li>查看如何成为
          
          <a href="http://www-1.ibm.com/certify/certs/adcdxmlrt.shtml&amp;origin=x">XML 和相关技术的 IBM 认证开发人员</a>。
        
        <br /></li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xhtml/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="author" src="http://www-128.ibm.com/developerworks/cn/i/p-sathyan.jpg" align="left" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Sathyan
Munirathinam 拥有 Madurai Kamaraj 大学计算机科学学士学位和计算机应用硕士学位。作为 Aztec Software
的一名软件工程师，他有两年多的信息技术工作经验。他的专业兴趣是数据库系统和联网，他的个人兴趣是阅读技术期刊，入侵网络系统和打板球。可以通过 <a href="mailto:sat_hyan@yahoo.com">sat_hyan@yahoo.com</a>与他联系。
      
      </p>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
<img src ="http://www.blogjava.net/Vencent/aggbug/35973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:51 <a href="http://www.blogjava.net/Vencent/articles/35973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实用数据绑定: 使用 XPath 作为数据绑定工具，第 1 部分：使用 XPath 选择 XML 文档部分</title><link>http://www.blogjava.net/Vencent/articles/35972.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:47:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35972.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35972.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35972.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35972.html</trackback:ping><description><![CDATA[
		<p>级别: 中级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#author">Brett McLaughlin</a>, 作家，编辑, O'Reilly Media, Inc.<br /></p>
		<p>2005 年  12 月  22 日</p>
		<blockquote>通
常人们不把 XPath 看作是一种数据绑定 API。除了作为其他规范的一部分以外，XPath 甚至还没有引起 XML
世界的过多关注。但是只要真正理解了 XPath 是什么以及如何使用它，特别是在 Java™
编程环境中，它就会成为一种强大的数据绑定工具，常常优于传统的数据绑定 API 如 JAXB 或 JaxMe。Brett McLaughlin
的 “<i>实用数据绑定</i>” 专栏首先用两期文章探讨了作为数据绑定工具的 XPath。</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>到目前为止，本专栏一直专注于数据绑定的传统定义和用法：将 XML 文档转换成 Java 表示并用于通常的 Java 方法中（比如 <code>getName()</code> 和 <code>setAddress()</code>）。
然后将 Java 对象再转换成 XML 表示，通常序列化（保存）到磁盘。我还讨论过另一种方向的转换，即把 Java 对象转换成 XML，
然后使用转换的 XML（可以通过网络连接发送出去，或者作为应用程序中另一个消费 XML
的组件的输入）。这都是非常有效和实用的数据绑定的用例，但是还没有包括所有的可能性。本文和下一期文章将介绍另一种方法，即使用 XPath
技术进行数据绑定。 </p>
		<p>如果您使用数据绑定很长时间了，通常会提供一个约束集（比如 XML 模式或 DTD），用 API
生成表示该约束集的类。然后使用这些类加载 XML 数据，将其中的数据序列化为 XML。这是一种完善的解决方案，但是并非惟一的不使用 SAX 或
DOM 等底层 API 从 XML 文档中读取数据的方法。XPath，您可能听说过这种规范，就是另一种方法。即使您<i>没有</i> 听说过 XPath，也可能在某些时候已经用到过它。通过本文，您将了解 XPath 是什么，知道如何使用它，看看它为什么像一种数据绑定 API，甚至可以漂亮地完成其他数据绑定任务很难实现的工作。</p>
		<p>
				<a name="N10084">
						<span class="atitle">总是为他人作嫁衣……</span>
				</a>
		</p>
		<p>XPath 是最常用而不为人知的 XML 技术之一。它实际上是<i>最</i> 常用的 XML 技术 —— XML 转换必不可少的组成部分。在将来的 Web 中它也起着重要的作用，因为它对 XLink 和（特别是） XPointer 至关重要。甚至 XForms 也暗中要用到它。</p>
		<p>那么人们为什么不把 XPath 看作一种独立的技术呢？很大程度上是因为其他语言中独立处理 XPath 的 API 还刚刚出现。但是如果使用过 XSLT 或 XPointer，或者处理过更先进的 XML Schema，那么您可能已经走到前面了。</p>
		<p>
				<a name="N10092">
						<span class="smalltitle">XPath 在 XSLT 中的作用</span>
				</a>
		</p>
		<p>如果使用过 XSLT，几乎可以肯定曾经看到过 XPath 而且至少在一定程度上看着面熟，即使您并没有意识到。看一看 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#code1">清单 1</a>，这是一个非常简单的 XSL 样式表的一部分。</p>
		<br />
		<a name="code1">
				<b>清单 1. XSL 样式表中的 XPath</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;xsl:template match="address"&gt;<br /> &lt;h1&gt;Addresses&lt;/h1&gt;<br /> &lt;hr /&gt;<br /> &lt;table&gt;<br />  &lt;tr&gt;&lt;th&gt;Street&lt;/th&gt;&lt;th&gt;City&lt;/th&gt;&lt;th&gt;State&lt;/th&gt;&lt;th&gt;Zip Code&lt;/th&gt;&lt;/tr&gt;<br />  &lt;xsl:apply-templates select="address" /&gt;<br /> &lt;/table&gt;<br />&lt;/xsl:template&gt;<br />&lt;xsl:template match="address" /&gt;<br /> &lt;tr&gt;<br />  &lt;td&gt;&lt;xsl:value-of select="street" /&gt;&lt;/td&gt;<br />  &lt;td&gt;&lt;xsl:value-of select="city" /&gt;&lt;/td&gt;<br />  &lt;td&gt;&lt;xsl:value-of select="state" /&gt;&lt;/td&gt;<br />  &lt;td&gt;&lt;xsl:value-of select="zipCode" /&gt;&lt;/td&gt;<br /> &lt;/tr&gt;<br />&lt;/xsl:template&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>比方说，当您看到 <code>select="address"</code> 或者 <code>select="zipCode"</code> 的时候，您看到的就是应用中的 XPath。包围在引号中的文本就是 XPath 表达式，尽管非常简单，要让样式表工作却是不可或缺的。</p>
		<p>实际上，即使编写最简单的 XML 转换，如果样式表中没有 <code>select</code> 会怎么样？根本不可能！这是因为 XPath 是 XML 转换从而也是 XSLT 的完整的一部分。如果您认为自己是一位 XSL 专家，您可能比自己认为的更熟悉 XPath。</p>
		<p>
				<a name="N100BC">
						<span class="smalltitle">XPointer 中的 XPath</span>
				</a>
		</p>
		<p>XPointer 是另一种大量使用 XPath 的 API，尽管不像 XSL 那么常用，但是也逐渐展露头角。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#code2">清单 2</a> 展示了一篇文档中指向另一篇文档的链接。</p>
		<br />
		<a name="code2">
				<b>清单 2. XPointer 上下文中 XPath 的用法</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;link xmlns:xlink="http://www.w3.org/2000/xlink" <br />      xlink:type="simple" <br />      xlink:href="cd.xml#xpointer(<br />      /cds/cd[@title='August and Everything After'])"&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="50%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N100D9">
																				<b>要考虑的一些问题</b>
																		</a>
																		<br />
																		<p>注意指向 XML 文档的一部分的 XPath 代码例子。XPath 表达式没有涉及到元素或属性，而是直接包含对这些 XML 结构名称的引用。这应该让您想起数据绑定。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>这是一段稍微复杂的 XPath。它选择了根元素 <code>cds</code> 中的 <code>cd</code> 元素，该元素有一个 <code>title</code> 属性等于 <code>August and Everything After</code>，这些内容都在 cd.xml 文档中。讨论这些似乎有点为时过早，但是先不要担心语法。关键是要看到 XPointer 和 XSL 一样大量使用了 XPath，事实上没有它 XPointer 就无法存在。再说一次，XPath 是用于选择数据的重要组件。</p>
		<p>
				<a name="N100F6">
						<span class="smalltitle">在 XForms 中使用 XPath</span>
				</a>
		</p>
		<p>XForms 是一种相对较新的 XML 技术，比不上 XSL 普及，甚至还比不上 XPointer 或 XLink。但是仍然值得提一下，因为它在 <code>input</code> 元素的 <code>ref</code> 属性中使用 XPath 表达式。可以设置一个 input 并将其绑定到 XML 文档中的特定元素（或属性），如 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#code3">清单 3</a> 所示。</p>
		<br />
		<a name="code3">
				<b>清单 3. XForms 组件使用 XPath 引用绑定到表单的 XML 文档</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;input ref="xhtml:html/body/xhtml:p[@id='greentea']/<br />   xhtml:description" /&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#code3">清单 3</a> 中的 XForms 语句将输入控件绑定到 XHTML 文档的特定元素。在这里 XPath 同样是指定具体元素的关键。后面将提到它允许使用一些非常高级的选择条件。</p>
		<p>在很大程度上 XForms 是一种尚未得到支持的技术，但是当使用 XForms 的时候，现在学习的 XPath 是一种很好的工具。将这些关于 XSL、XLink 和 XInclude 的知识结合起来就够了！</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10120">
						<span class="atitle">选择内容：基础</span>
				</a>
		</p>
		<p>现在您已经确信 XPath 非常有用而且无处不在了，下面开始学习语法吧。如果刚接触 XPath，本课程将帮助您开始学习和领会 XPath 的结构。如果是一位 XSL 或 XLink 和 XPointer 老手，也可了解<i>为什么</i> 要构造那些奇怪的路径。您可能已经知道获取感兴趣的数据的其他方法，也许是更好的方法。</p>
		<p>首先要认识到称 XPath 为一种语言有点过于郑重其事。它实际上是选择和处理 XML 文档中的内容的一种语法。即使在 XPath 中使用的函数和运算符也都与选择有关。在 XPath 中不会创建变量，比方说不可能<i>运行</i> 一个 XPath <i>程序</i>。没有这些东西。如果您开始认识到 XPath 是一种巧妙的、有益的选择 XML 元素和属性的方法，然后使用选择的值，您就已经领先于大多数 XML 开发人员了。XPath 不是要对 XML <i>做</i> 什么事情，而是要<i>从</i> XML 中取得一些内容。</p>
		<p>
				<a name="N1013A">
						<span class="smalltitle">选择元素</span>
				</a>
		</p>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="50%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N10143">
																				<b>设置上下文</b>
																		</a>
																		<br />
																		<p>设置上下文不是 XPath 的工作。事实上，根本<i>不能</i> 用 XPath 设置上下文。相反，要用其他使用 XPath 在文档中导航的 API 来设置上下文。比如，XSLT 根据应用的模板设置上下文，XForms（一般来说）每次都从根上下文开始。因此理解上下文更多的是需要了解<i>使用</i> XPath 的 API，而不是 XPath 本身。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>对于 XPath 来说第一步是找到一个引用元素的句柄。可是在选择元素之前需要理解当前<i>上下文</i>。上下文就是在 XML 文档中的位置。比方说，您可能在根元素上，那根元素就是上下文。当然也可能在第一个 <code>person</code> 元素的第二个 <code>address</code> 元素上。在开始移动和选择内容之前，需要知道上下文。</p>
		<p>只要理解了上下文，就可以掌握 XPath 语法了。以 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 中的 XHTML 文档为例。</p>
		<br />
		<a name="listing4">
				<b>清单 4. Head First Lounge 的 XHTML</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" <br />   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;<br />&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en"&gt;<br />  &lt;head&gt;<br />    &lt;meta http-equiv="Content-Type" content="text/html; <br />        charset=ISO-8859-1" /&gt;<br />    &lt;title&gt;Head First Lounge Elixirs&lt;/title&gt;<br />    &lt;link type="text/css" rel="stylesheet" href="../lounge.css" /&gt;<br />  &lt;/head&gt;<br />  &lt;body&gt;<br />    &lt;h1&gt;Our Elixirs&lt;/h1&gt;<br />    &lt;h2&gt;Green Tea Cooler&lt;/h2&gt;<br />    &lt;p class="greentea"&gt;<br />     &lt;img src="../images/green.jpg" alt="Green Tea Cooler" /&gt;<br />     Chock full of vitamins and minerals, this elixir<br />     combines the healthful benefits of green tea with<br />     a twist of chamomile blossoms and ginger root.<br />    &lt;/p&gt;<br />    &lt;h2&gt;Raspberry Ice Concentration&lt;/h2&gt;<br />    &lt;p class="raspberry"&gt;<br />     &lt;img src="../images/lightblue.jpg" <br />         alt="Raspberry Ice Concentration" /&gt;<br />     Combining raspberry juice with lemon grass,<br />     citrus peel and rosehips, this icy drink<br />     will make your mind feel clear and crisp.<br />    &lt;/p&gt;<br /><br />    &lt;h2&gt;Blueberry Bliss Elixir&lt;/h2&gt;<br />    &lt;p class="blueberry"&gt;<br />     &lt;img src="../images/blue.jpg" alt="Blueberry Bliss Elixir" /&gt;<br />     Blueberries and cherry essence mixed into a base<br />     of elderflower herb tea will put you in a relaxed<br />     state of bliss in no time.<br />    &lt;/p&gt;<br />    &lt;h2&gt;Cranberry Antioxidant Blast&lt;/h2&gt;<br />    &lt;p&gt;<br />     &lt;img src="../images/red.jpg" alt="Cranberry Antioxidant Blast" /&gt;<br />     Wake up to the flavors of cranberry and hibiscus<br />     in this vitamin C rich elixir.<br />    &lt;/p&gt;<br />    &lt;p&gt;<br />     &lt;a href="../lounge.html"&gt;Back to the Lounge&lt;/a&gt;<br />    &lt;/p&gt;<br />  &lt;/body&gt;<br />&lt;/html&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>如果在 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 中的上下文是 <code>html</code> 元素，就可以直接使用名称选择一个子元素。比如选择 <code>body</code> 元素可使用 XPath 表达式 <b><code>body</code></b>。如果想访问嵌套在 <code>body</code> 中的 <code>h1</code> 元素则使用 <b><code>body/h1</code></b>。如果认为这有点类似于目录路径，那么就对了。选择元素使用 <code><i>元素名</i>/<i>子元素名</i></code> 这样的形式。 </p>
		<p>不过在前进之前要认识到 XPath 表达式可能返回<i>多个</i> 元素。结果元素集称为<i>节点集</i>。（事实上，用 XPath 选择的所有实体 —— 元素、属性和值 —— 都称为<i>节点</i>。）比如下面的路径：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">body/p</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 中 <code>body</code> 有五个不同的 <code>p</code> 子元素，因此那个表达式返回包含五个节点的节点集（正如您所期望的，<i>不</i> 只是第一个 <code>p</code> 元素）。注意，有时候您得到了预期的结果，但是很可能比您<i>打算</i> 要求的多。</p>
		<p>还有更多需要注意的地方。现在给出的表达式仅仅返回实际的元素。可能还要获得这些节点的值。如果需要元素的值（假设元素包含文本数据），需要使用 <code>text()</code> 函数。要获得第一个 <code>h1</code> 的文本，应使用 <b><code>body/h1/text()</code></b>，对于<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 将返回 <code>Our Elixirs</code>。</p>
		<p>
				<a name="N101E6">
						<span class="smalltitle">选择属性</span>
				</a>
		</p>
		<p>当然可以选择的不仅仅是元素。前面已经提到还可以选择属性。选择属性的时候要在属性名前使用 <code>@</code> 符号，其他方面和元素都一样。</p>
		<p>再回到 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 这个例子，可以使用 <b><code>head/meta/@http-equiv</code></b> 返回 <code>meta</code> 元素 <code>http-equiv</code> 属性的值。类似地，<b><code>head/link/@type</code></b> 返回 <code>link</code> 元素的 <code>type</code> 属性。</p>
		<p>必须知道，选择属性的时候您得到的是它的值，而不像元素那样返回节点。因此对于属性选择器，返回值（虽然不确切但是很有用）是一个值，对于一个元素则是一个节点集（包含一个节点）。</p>
		<p>
				<a name="N1021B">
						<span class="smalltitle">在文档中移动</span>
				</a>
		</p>
		<p>目前为止看到的都是理想的情况，特别是使用文档的根作为上下文比较简单。但是显然情况并非总是如此。这正是目录结构的真正有用的地方。要从当前上下文移动到上一级，只要使用 <code>..</code> 运算符。比方说，假设上下文是 <code>body</code> 元素，现在需要获得网页的标题（包含在文档 <code>head</code> 下的 <code>title</code> 元素中），可以使用 <b><code>../head/title/text()</code></b>。如果您开始感觉到就像是改变 UNIX 或 Mac OS X 终端上的目录，这就对了！</p>
		<p>如果上下文是 <code>body</code> 中第二个 <code>p</code> 的 <code>img</code> 元素，要得到标题该怎么办呢？可以使用 <b><code>../../../head/title/text()</code></b>。但是数这些 <code>../</code> 很快就变得单调乏味了。因此能直接跳到根元素就好了，再想一想 UNIX，使用 <code>/</code> 返回到根元素就毫不奇怪了。同样的选择器更简单的形式为 <b><code>/html/head/title/text()</code></b>。虽然没有缩短，但是更清楚了。有了 <code>../</code> 和 <code>/</code> 之后，基本上就能移动到需要的任何地方了。</p>
		<p>
				<a name="N10268">
						<span class="smalltitle">多重选择</span>
				</a>
		</p>
		<p>考虑到使用一个 XPath 表达式可以选择多个节点，事情就更有趣了。您可以使用对应多个节点的简单表达式，比如 <b><code>/html/body/h2</code></b> 来进行多重选择。但是也可使用<i>通配符</i> 进一步精化这些选择。XPath 中有三个统配符：</p>
		<ul>
				<li>
						<b>
								<code>*</code>
						</b> 与任何元素匹配，无论元素名是什么</li>
				<li>
						<b>
								<code>node()</code>
						</b> 与所有的节点类型匹配（元素、文本节点、注释、属性，等等）</li>
				<li>
						<b>
								<code>@*</code>
						</b> 与所有的属性节点匹配，无论属性名是什么</li>
		</ul>
		<p>比如，可以使用 <b><code>/html/body/*</code></b> 选择 <code>body</code> 元素的所有直接子元素。也可用 <b><code>/html/head/meta/@*</code></b> 选择 <code>meta</code> 标记的所有属性。</p>
		<p>所有这些情况下，要记住您得到的是一个节点集，因此不应该满足于处理某个值就结束（除非您已经选择了一个属性，稍后要讲到）。但是，只要使用方法、函数或模板处理多个节点，这些技术就很重要。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N102B8">
						<span class="atitle">更有趣的东西</span>
				</a>
		</p>
		<p>基本的东西很好，但有时候还需要点特别的让您身边的同事眼花缭乱的东西，或者需要一点<i>特殊的</i> 功能。这种情况下这些基础可能就不够了。虽然很难巨细无遗地介绍 XPath，但下面给出一些高级技巧，可以帮助您在 XPath 应用程序中取得需要的节点（或节点集）。</p>
		<p>
				<a name="N102C3">
						<span class="smalltitle">更大的一般性</span>
				</a>
		</p>
		<p>到目前为止，看到的路径都是选择一个节点，并假设您知道该节点在何处。比方说，您知道 <code>title</code>、<code>img</code> 或 <code>p</code> 在文档中什么位置，只需要导航到这些元素。但有时候可能希望打破这些结构，仅仅撷取某种元素而不管其位置（或者无论给定的起始上下文的位置）。为此可使用<i>后代选择器</i>。</p>
		<p>后代选择器用双斜线 <code>//</code> 表示。使用它告诉 XPath 选择所有指定的节点，<i>无论嵌套得多深</i>。比如这个简单的特定于 XHTML 的 XPath：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">/html/body//table</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>XPath 选择嵌套在 XHTML 的 <code>body</code> 元素中的<i>所有</i><code>table</code> 元素，不论直接嵌套在 <code>body</code> 中（如 <b><code>/html/body/table</code></b>），还是嵌套了多层（如 <b><code>/html/body/table/tr/td/table</code></b>）。这种情况下，嵌套的 <code>table</code> 和顶层 <code>table</code> 同时被选中。</p>
		<table align="right" border="0" cellpadding="0" cellspacing="0" width="50%">
				<tbody>
						<tr>
								<td width="10">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="1" width="10" />
								</td>
								<td>
										<table border="1" cellpadding="5" cellspacing="0" width="100%">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N10315">
																				<b>不是很合 XML 的风格</b>
																		</a>
																		<br />
																		<p>在标准 XML 术语中，属性不<i>属于</i> 元素，而是与元素<i>关联</i>，有时候也说<i>在元素上</i>。但是，XPath 不能处理元素及其属性之间的关系。因此只能尽自己最大的努力：将属性看作是属于它们所在的元素。因此选择 <code>p</code> 的 <code>class</code> 属性要使用 <b><code>p/@class</code></b>。要访问属性所在的元素，可使用 <b><code>@class/..</code></b>。实际上是从属性<i>上移</i> 一层而选择元素。从技术上说这不是很好的 XML，但却是完全正确的 XPath。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>当与属性结合使用的时候就变得很有趣了（使用 <code>@</code>）。比方说，假设要选择具有 <code>id</code> 属性的所有元素。可使用 <b><code>//@id</code></b>，首先跳回根元素然后选择文档中的所有 <code>id</code> 属性。但是实际上要访问的是元素而不是属性，因此需要从属性上移一层到包含这些属性的元素：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="40%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">//@id/..</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>您应该尝试结合这些不同的方法，会看到一些很有意思的结果。</p>
		<p>
				<a name="N1035F">
						<span class="smalltitle">匹配条件</span>
				</a>
		</p>
		<p>假设有一个条件希望作为匹配的基础，比如需要 <code>class</code> 属性值为 <code>greentea</code> 的 <code>p</code> 元素。如果知道如何使用方括号，这一点在 XPath 中很容易做到。下面是一个例子：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />/html/body/p[class="greentea"]<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>方括号用于指定条件，可使用 <code>=</code> 甚至 <code>&lt;</code> 和 <code>&gt;</code>。也许要用一个范围更广的表达式：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />//p[class="greentea"]<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>明白了吗？甚至还能更进一步，选择属于 <code>greentea</code> 类的<i>所有</i> 元素而不论其元素类型是什么：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />//@class[.="greentea"]/..<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这个表达式可能看起来有点奇怪，但很容易解释。首先，<code>//</code> 意味着从根元素开始选择所有的元素（与后面的选择器及条件匹配）而不论其嵌套的位置。然后 <code>@class</code> 选择文档中所有的 <code>class</code> 属性。后面的 <code>[.="greentea"]</code> 有点神秘。<code>="greentea"</code> 部分容易理解，它用 <code>greentea</code> 匹配等式左侧的值。在这里就是 <code>.</code>，这个标志还没有见到过。但是再想一想目录，<code>..</code> 选择父节点（或者父目录），<code>.</code> 则选择当前节点。因此 <code>//@class[.="greentea"]</code> 选择值为 <code>greentea</code> 的所有 <code>class</code> 属性。然后再移动到这些属性所在的元素：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />//@class[.="greentea"]/..<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>现在看起来有点不可思议，但是应该熟悉这类奇怪的表达式。当需要访问特定的元素、属性或节点集时它们很有用。</p>
		<p>
				<a name="N103D7">
						<span class="smalltitle">计算</span>
				</a>
		</p>
		<p>随着越来越多的使用属性选择器，最终将与处理节点一样经常地使用值（来自属性）。如果处理过非常典型的 XML，一定会遇到数字。XML 文档常常把数字值放在属性中（有时候在元素中）。因此这一节讨论 <b><code>/people/person[firstname = "John"]/@born</code></b> 和 <b><code>/people/person/numChildren/text()</code></b> 这类表达式的结果（当然，使用元素表示子女的个数不够典型，不过就用下面的例子吧）。</p>
		<p>这时候您会发现 XPath 的计算能力很有用。可以像其他编程语言中那样使用 <code>+</code>、<code>-</code> 和 <code>*</code>。此外 <code>div</code> 用于除法，<code>mod</code> 则表示求模（两数相除的余数）。比如，假设 XML 文档中包含用四位数表示的出生年份，现在需要改成两位数的形式，首先用下面的表达式取得实际的出生年份：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />/people/person/birthdate/@year<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这样就得到了出生年份（可能是 1976 或者 1945）。然后只需要减去 1900：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />(/people/person/birthdate/@year) - 1900<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>当然这种方法很有限，新千年出生的孩子和那些历史人物都会造成这一公式的失败。因此应该用 <code>mod</code>： </p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />(/people/person/birthdate/@year) mod 100<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>（顺便说一下，应该告诉那些研究 Y2K 的人您省略了年份的前两位数。）</p>
		<p>
				<a name="N10421">
						<span class="smalltitle">字符串技巧</span>
				</a>
		</p>
		<p>最后，XPath 还提供了一些很棒的字符串处理功能。XML 基本上都是文本，属性值和元素中的数据通常是文本，因此不用奇怪 XPath 支持某些字符串操作。下面仅仅是 XPath 提供的处理字符串的少数函数：</p>
		<ul>
				<li>
						<b>
								<code>string()</code>
						</b> 将数据转换成字符串格式，如果还不是字符串的话。</li>
				<li>
						<b>
								<code>starts-with(full-string, start-string)</code>
						</b> 返回一个 Boolean 值，检查 <code>full-string</code> 是否以 <code>start-string</code> 开始。</li>
				<li>
						<b>
								<code>contains(full-string, contains-string)</code>
						</b> 返回一个 boolean 值，检查 <code>full-string</code> 是否包含 <code>contains-string</code>。</li>
				<li>
						<b>
								<code>string-length(string)</code>
						</b> 返回 <code>string</code> 的长度。</li>
				<li>
						<b>
								<code>normalize-space(string)</code>
						</b> 去掉 <code>string</code> 两端和内部的空格。</li>
		</ul>
		<p>大部分函数的功能都很明确。<code>starts-with("McLaughlin", "Mc")</code> 返回 <code>true</code>，<code>contains("McLaughlin", "augh")</code> 同样如此。<code>string-length("Brett")</code> 显然返回 <code>5</code>，<code>normalize-space("      Brett      McLaughlin       ")</code> 则返回 <code>"Brett McLaughlin"</code>。是不是很简单？当然这些可用于所有 XPath 表达式的返回值，比如 <b><code>/html/body/p[class='greentea']</code></b>。因此要获取 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 中 <code>p</code> 的文本可用 <code>normalize-space()</code>：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />normalize-space(/html/body/p[class='greentea'])</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>更妙的是可用 <code>string()</code> 取出多个元素的文本。比如，如果希望取得 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#listing4">清单 4</a> 所示 XHTML 中<i>所有</i><code>p</code> 元素的<i>所有</i> 文本，可用：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">normalize-space(string(//p))</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>分析最后一个例子可以了解很多内容：</p>
		<ol>
				<li>
						<b>
								<code>//p</code>
						</b> 选择文档中所有的 <code>p</code> 元素，无论其位于何处。</li>
				<li>
						<b>
								<code>string(//p)</code>
						</b> 获取这些元素的内容组成一个大字符串。但是字符串中包含很多无用的空白，因此还要进一步处理。</li>
				<li>
						<b>
								<code>normalize-space(string(//p))</code>
						</b> 规范化内容中的空白字符，得到您希望的文本。</li>
		</ol>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N104F0">
						<span class="atitle">这是一篇关于数据绑定的文章吗？</span>
				</a>
		</p>
		<p>现
在您可能已经忘记正在阅读的是一篇关于数据绑定的文章。但是先不要忙于跟过去几年中您读过的其他 X* 文档和 API
比较。您读到的实际上是另一种数据绑定方法。考虑这样一种观点，数据绑定是在 Java 代码中保留 XML
文档逻辑（或者语义，如果您喜欢的话）意义。如果 XML 文档中的 <code>address</code> 元素包含 <code>street</code>、<code>city</code> 和 <code>state</code> 子元素，想要用 <code>getAddress().getStreet()</code> 这样的形式得到这些元素的值，比如：</p>
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />Address address = getAddress();<br />System.out.println(address.getCity() + ", " + address.getState());<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这就是某种基本的数据绑定形式。但是在 XPath 中也能做到同样的事！可以利用 <b><code>address/street/text()</code></b> 或者 <b><code>/person[last-name="Gosling"]/address[@type="work"]/city</code></b> 这样的 XPath 表达式来得到街道名。初看起来与前一个例子不同，但是它仍然合理地使用了 XML 数据，您要的是 <i>person</i>、<i>address</i> 和 <i>street</i> 而不是<i>第一个子元素</i>、<i>第二个文本节点</i> 或者<i>属性</i>。这一点至关重要。<i>XPath 按照逻辑而不是结构来处理 XML。</i>基本上数据绑定也是如此，按照逻辑处理数据，而不用担心其结构。</p>
		<p>为了避免误导，需要指出使用 XPath 仍然需要对结构有所了解。比如，<code>@</code> 运算符只用于属性，因此必须知道 <code>type</code>（地址的一部分）用元素还是属性表示。在传统的数据绑定中，只需要调用 <code>getAddress().getType()</code> 而不需要管结构的层次。但是，这点小小的代价是值得的，因为不需要处理大量的生成类、额外的类路径问题、等待封送和解除封送处理以及传统数据绑定的其他缺点。</p>
		<p>只
剩下这个等式中需要在 Java 语言中增加的部分：接受 XML 文档和 XPath 表达式，以 Java
友好的方式获得表达式的结果。这些内容将在第 2 部分介绍，很快就要把 XPath 与 Java 编程中其他以 XML
为中心的工具一起使用了。很多情况下您会发现，与使用生成类和 JAXB 这样的 API 的工具相比，XPath 是一种<i>更好的</i> 数据绑定工具。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<ul>
				<li>
						<a href="http://www-128.ibm.com/developerworks/forums/dw_forum.jsp?forum=262&amp;cat=11">参与论坛讨论</a>。<br /><br /></li>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/xml/library/x-pracdb8.html" target="_blank">英文原文</a>。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xpath">XML Path Language (XPath)
Version 1.0</a>：阅读 W3C 推荐标准。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xpath20/">XML Path Language (XPath) 2.0</a>：这是 XPath 1.0 的超集，增加了更丰富的数据类型支持，使用 XML Schema 验证文档时可使用这些类型信息。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/cn/xml/x-xdata/part10/">用于数据的 XML: XPath 2.0 有哪些新特性？</a>”（developerWorks，2002 年 9 月）：了解 XPath 1.x 和 2.0 的区别。<br /><br /></li>
				<li>“<a href="http://www.ibm.com/developerworks/cn/views/xml/tutorials.jsp?cv_doc_id=85118">XPath 入门</a>”（developerWorks，2004 年 3 月）：需要了解或复习 XPath，可以阅读 Bertrand Portier 撰写的这篇入门教程。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/Style/XSL/">The Extensible Stylesheet Language Family (XSL)</a>：XPath 是 XSL 和 XSLT 的重要部分。进一步了解 W3C 的 XSL 规范家族，包括 <a href="http://www.w3.org/TR/xslt">XSL Transformations (XSLT) Version 1.0</a>。<br /><br /></li>
				<li>
						<a href="http://www.w3.org/TR/xpath-datamodel/">XQuery 1.0 and XPath 2.0 Data Model (XDM)</a>：伴随着 XPath 2.0，XQuery 希望定义能同时用于两种规范的数据模型。<br /><br /></li>
				<li>“<a href="http://www.xml.com/pub/a/2001/03/07/xpathapi.html">Toward an XPath API</a>”：通过 Leigh Dodds 的这篇文章了解导致最初的 1.0 XPath API 诞生的原因。<br /><br /></li>
				<li>
						<a href="http://www.oreilly.com/catalog/javaxml2/">
								<i>Java and XML</i>
						</a>：Brett McLaughlin 撰写的这本书的第三版（O'Reilly Media, Inc.）专门用一章讨论 XPath。<br /><br /></li>
				<li>
						<a href="http://www.oreilly.com/catalog/xmlnut2/">
								<i>XML in a Nutshell</i>
						</a>：Elliotte Rusty Harold 和 W. Scott Means 撰写的这部 XML 资料大全（O'Reilly Media, Inc.）专门有一章讨论 XPath。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/xml/">developerWorks XML 专区</a>：可以找到更多 XML 资源，包括文章、教程、技巧和标准。
<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/">developerWorks Java 技术专区</a>：数百篇文章、教程和技巧可以帮助您掌握大部分 Java 语言技术和相关应用。
<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/certify/certs/adcdxmlrt.shtml">IBM Certified Solution Developer —— XML 和相关技术</a>：了解如何通过认证。

</li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-pracdb8.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<p>
												<img alt="Brett McLaughlin 的照片" src="http://www.ibm.com/developerworks/i/p-brett.jpg" align="left" height="80" width="64" />
										</p>
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Brett
McLaughlin 从 Logo 时代就开始使用计算机。（还记得那个小三角吗？）近年来他已经成为 Java 技术和 XML
社区最知名的作家和程序员之一。他曾经在 Nextel Communications 实现过复杂的企业系统，在 Lutris
Technologies 编写应用程序服务器，最近在 O'Reilly Media, Inc. 继续撰写和编辑这方面的图书。在他的新书 <a href="http://www.oreilly.com/catalog/headra/index.html"><i>Head Rush Ajax</i></a> 中，Brett 与畅销书作家 Eric 及 Beth Freeman 为 Ajax 带来了获奖的创新方法 <a href="http://www.headfirstlabs.com/">Head First</a>。最近的著作 <a href="http://safari.oreilly.com/?XmlId=0596007388/index"><i>Java 1.5 Tiger: A Developer's Notebook</i></a> 是关于这一 Java 技术新版本的第一本书籍，经典著作 <a href="http://www.oreilly.com/catalog/javaxml2/"><i>Java and XML</i></a> 仍然是在 Java 语言中使用 XML 技术的权威图书。</p>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
<img src ="http://www.blogjava.net/Vencent/aggbug/35972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:47 <a href="http://www.blogjava.net/Vencent/articles/35972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HTML 的未来，第 1 部分: Web Hypertext Application Technology Working Group 改进 HTML 的方法</title><link>http://www.blogjava.net/Vencent/articles/35971.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:46:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35971.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35971.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35971.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35971.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35971.html</trackback:ping><description><![CDATA[
		<p>级别: 初级</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#author">Edd Dumbill</a>, 主席, XTech Conference<br /></p>
		<p>2005 年  12 月  29 日</p>
		<blockquote>本
系列包括两篇文章，Edd Dumbill 分析了 Web 作者、浏览器开发人员和标准组织所期望的 HTML 未来趋势各种方式。介绍了
WHATWG 阐述的渐进式方法和 W3C 所提议的 XHTML 的大清洗式的方法。此外，作者还考察了 W3C 最新的 Rich Client
Activity。本文是第 1 部分，Edd 主要讨论 WHARWG 开发的两种规范：Web Applications 1.0 (HTML5)
和 Web Forms 2.0。</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>HTML 不是一种很好的制作网页的语言。但却是形成 Web 的一种很好的语言。</p>
		<p>HTML 易学易用，再加上浏览器的 <b>查看源代码</b> 功能，引发了 Web 令人瞠目结舌的迅速普及。万维网联盟（W3C）对
HTML 标准化的参与，保证了所有的 Web 浏览器都或多或少地实现了同样的方言。CSS 的出现，作为最佳实践的基于标准的 Web
设计的普及也改变了 HTML 的混乱状态，同时为用户和开发人员带来了更好的 Web 体验。</p>
		<p>您可能已经了解这些。结果是 Web 可能已经对您的生活或生意带来正面的影响。但事实仍然是 HTML 并不是一种很好的语言。比方说，为什么
HTML 要设置 H1 到 H6 这些标题？谁会使用包含六层的标题结构？为什么在这个 3D 图形加速卡和复杂用户界面的时代，Web
页面却要让用户用笨拙的文本框和单选按钮来输入？</p>
		<p>因此毫不奇怪，各种不同的组织再次迫切地要求改进 HTML，使 Web 发布和 Web
应用程序使用现代用户界面提供的更多技术。这些人有谁呢？粗略地说可分为三类。首先是利用现有技术进行改造的那些人。这就是 Asynchronous
JavaScript and XML (Ajax) 所宣扬的：使用 JavaScript 和浏览器 <code>XMLHttpRequest</code> 对象建立动态的用户界面。取得的效果是惊人的，但这不是进步的标准方式。</p>
		<p>另外两类人关注未来的改进。W3C 根据各种供应商（不仅仅是桌面浏览器制造者）的需要，提出了 XHTML 2.0。XHTML 2.0
被看作是革命性的一步。相反，Web Hypertext Application Technology Working Group
(WHATWG) 则提出了一套递增式的规范，改进 HTML 从而为浏览器增加了最迫切需要的功能。一些 WHATWG 特性已经在 Apple 的
Safari 浏览器和 Mozilla Firefox 1.5 中实现了。（关于 W3C 和 WHTAWG 的更多信息请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>。）</p>
		<p>这两期文章将讨论 W3C 和 WHATWG 的工作。Ajax 已经在 developerWorks 的其他文章（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>）中讨论过了。虽然还没有引起最初 HTML 引入 W3C 时所爆发的大规模的标准之争，但这两个组织对 HTML 走向何方并非总是一致的。我将解释和评论这两种方法。</p>
		<p>
				<a name="N1006C">
						<span class="atitle">WHATWG、HTML 5 和 Web Forms 2.0</span>
				</a>
		</p>
		<p>就像其网页上所宣称的那样，WHATWG 是 “Web 浏览器生产厂商和一些相关团体形成的一个松散的、非正式的协作组织，这些团体希望发展一些新的技术，从而开发人员可以在互联网上编写并部署应用。这里有两点特别值得关注：WHATWG 的主要参与者是<i>浏览器</i>（Mozilla、Opera）制造商，他们改进的目标是创建 Web <i>应用程序</i>。</p>
		<p>WHATWG 的标志性规范的代号是 <i>HTML5</i>，但更为人所知的名称是 <i>Web Applications 1.0</i>（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>）。HTML5 的目标是保持和当前 HTML 标准 HTML 4.01 以及 HTML 的 XML 版本 XHTML 1.0 向后兼容。该规范继续了 W3C HTML 所致力的 HTML 和 XHTML 的融合，虽然它提出实现的方法可能不同。</p>
		<p>除了 HTML5，<i>Web Forms 2.0</i> 规范（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>）也寻求解决开发人员对当前 HTML 表单的不满之处。目前的表单省略了普通桌面应用程序的很多基本特性，比如验证和更丰富的小部件。</p>
		<p>那么 HTML5 中有什么呢？一句话，很多。Web Applications 1.0 规范仍然在演化之中，提到的有些特性比另一些开发得更完善。下面是对这些新特性的简要说明：</p>
		<ul>
				<li>新的布局元素，包括日历控件、地址卡、灵活的数据网格、标尺和进度条、拖放、菜单</li>
				<li>对文档对象模型（DOM）的编程扩展，包括服务器发送的 DOM 事件</li>
				<li>事实标准 <code>XMLHttpRequest</code> 对象的正式化，它是 Ajax 通信的核心</li>
				<li>基于 <code>canvas</code> 元素的动态位图图像</li>
		</ul>
		<p>可以看到其中很多源自目前 Web 上用 JavaScript 一次性实现的特性。事实上，最近 Ajax 工具箱的流行已经引起了标尺、日历等控件的泛滥。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100AF">
						<span class="atitle">画布</span>
				</a>
		</p>
		<p>HTML5 特性（即 Web 浏览器的一部分）的传统实现目前还仅限于上述少数技术。其中最知名的是 <code>canvas</code> 元素。Firefox 1.5 和 Apple 的 Safari 浏览器也实现了 <code>canvas</code>。</p>
		<p>虽然 W3C 的 Scalable Vector Graphics (SVG) 语言已经提供了在浏览器中显示图形的一种方式，但 <code>canvas</code>  采用了不同的方法。不是像 SVG 那样实现一种声明性文档，它提供了一个空白面供 JavaScript 在上面绘图。这种命令式的绘图模型更类似于 OpenGL 风格的绘制，而不是声明性的 Web。</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#fig1">图 1</a> 显示了一个简单的 <code>canvas</code> 示例的截屏图。（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>，可用 Apple 的 Safari 浏览器或 Firefox 1.5 的预览版来查看。）当用户把鼠标移到该图形上时，图形慢慢地放大。这个例子表明，实现用户界面需要的所有成分 ——绘制、用户输入事件和定时器 —— 都已经就位。</p>
		<br />
		<a name="fig1">
				<b>图 1. 交互式画布示例的截屏</b>
		</a>
		<br />
		<img alt="交互式画布示例的截屏" src="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/htmlfuture1-canvas.gif" height="173" width="280" />
		<br />
		<p>通过实现一个简单的 3D 迷宫，<code>canvas</code> 应用程序已经离最明显的目标（游戏！）只有一步之遥了，如 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#fig2">图 2</a> 所示。（实际的迷宫请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>。）</p>
		<br />
		<a name="fig2">
				<b>图 2. 简单的迷宫游戏</b>
		</a>
		<br />
		<img alt="简单的迷宫游戏" src="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/htmlfuture1-raycast.gif" height="122" width="280" />
		<br />
		<p>为了了解如何对 <code>canvas</code> 编程，请看一些简单的代码。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#listing1">清单 1</a> 显示了一个很容易理解的例子，它的结果如 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#fig3">图 3</a> 所示。</p>
		<br />
		<a name="listing1">
				<b>清单 1. 简单的 canvas 例子</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />
														<br />&lt;html&gt;<br />  &lt;head&gt;<br />    &lt;title&gt;Canvas demo&lt;/title&gt;<br />    &lt;script type="text/javascript"&gt;<br />      function draw () {<br />        var canvas = document.getElementById ('hello');<br />        if (canvas.getContext) {<br />          var ctx = canvas.getContext('2d');<br />          ctx.fillRect (25, 25, 50, 50);<br />        }<br />      }<br />    &lt;/script&gt;<br />    &lt;style type="text/css"&gt;<br />      canvas { border: 2px solid red; }<br />    &lt;/style&gt;<br />  &lt;/head&gt;<br />  &lt;body onload="draw ();"&gt;<br />    &lt;canvas id="hello" width="100" height="100"&gt;&lt;/canvas&gt;<br />  &lt;/body&gt;<br />&lt;/html&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<a name="fig3">
				<b>图 3. 清单 1 的结果</b>
		</a>
		<br />
		<img alt="清单 1 的结果" src="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/htmlfuture1-squares.gif" height="115" width="114" />
		<br />
		<p>因为 <code>canvas</code> 没有提供任何声明性语义，很可能更多地用于用户界面实现领域而不是其他方面。<code>canvas</code> 令人感兴趣的一点是作为新的浏览器界面元素和特性的原型基础。最好的例子是 Antoine Quint 使用 <code>canvas</code> 部分实现了 SVG（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>）。使用 Quint 的方法，要呈现内嵌 SVG 的 HTML 文件，可以增加两行代码导入其 JavaScript SVG 呈现引擎。<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#fig4">图 4</a> 显示了使用该方法呈现的类似的老虎图像。</p>
		<br />
		<a name="fig4">
				<b>图 4. 使用 JavaScript 和 canvas 元素呈现的 SVG 老虎图像</b>
		</a>
		<br />
		<img alt="使用 JavaScript 和 canvas 元素呈现的 SVG 老虎图像" src="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/htmlfuture1-tiger.gif" height="268" width="280" />
		<br />
		<p>时间将证明 <code>canvas</code> 是否会成为主流的 Web 设置。它的功能和 Java applet 有些类似，但是其 JavaScript 接口更容易使用，也更容易与其他浏览器元素交互。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10157">
						<span class="atitle">Web Forms 2.0</span>
				</a>
		</p>
		<p>WHATWG 表单规范的版本号表明它的目标是以 HTML4 中的表单规范为基础。与 Web Applications (HTML5) 规范不同，这是个成熟的规范。Web Forms 2.0 的范围也更狭窄，仅仅着眼于改进浏览器中提供的表单控件。</p>
		<p>这次对表单的修订增加了什么呢？其中包括：</p>
		<ul>
				<li>验证结构允许浏览器在提交表单前做更多的检查。新的属性，包括 <code>required</code>、<code>min</code> 和 <code>max</code>。
</li>
				<li>验证的 DOM 支持，为表单元素增加了 <code>validity</code> 属性和新的 <code>invalid</code> 事件。
</li>
				<li>对表单元素自动完成的控制，允许文档作者指明是否让浏览器记住字段值并自动填充。预定义的值可通过 <code>list</code> 属性传递。</li>
				<li>
						<code>autofocus</code> 属性指定加载文档时哪一个表单元素拥有输入焦点。
</li>
				<li>
						<code>inputmode</code> 属性允许对存放文本的表单元素提示适当的语言输入模式。</li>
				<li>文件上传控制的改进，可以指定文件类型，限制文件大小。</li>
				<li>模板化表单元素的循环。</li>
				<li>新的输入控件包括：<code>datetime</code>、<code>number</code>、<code>range</code>、<code>email</code> 和 <code>url</code>。增加了限制输入值的模式（pattern）。</li>
		</ul>
		<p>Web Forms 规范比 HTML5 更加一致，已经出现了一些实现：</p>
		<ul>
				<li>Opera 9 的 beta 版包括 Web Forms 2.0 支持</li>
				<li>开放源码 Web Forms 项目为 Internet Explorer 提供了 DHTML+Behaviors 实现</li>
		</ul>
		<p>W3C 为下一代表单提供的答案是 XForms（请参阅 <a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#resources">参考资料</a>）。
XForms 和 Web Forms 2.0 不同，根据传递的 XML 文档开发了一种新的浏览器-服务器交互模型。相反，Web Forms
2.0 是对现有表单模型的改良，目的是使现在的浏览器表单更好用。这两种规范针对不同的需求，虽然存在明显的共同之处。正如 Web Forms
规范所指出的：</p>
		<blockquote>本规范尝试增加 XForms 的一些功能，并尽量减少对现有的、被广泛实现的表单模型的影响。如果需要，向后兼容、易于编辑、易于实现要优先于理论的纯粹性。</blockquote>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101C6">
						<span class="atitle">其他实现</span>
				</a>
		</p>
		<p>
				<code>canvas</code> 是浏览器实现的主要 WHATWG 特性。HTML5 的其他部分仍然处在初级阶段，可能永远不会完全实现。</p>
		<p>但是，Web Applications 和 Web Forms
规范可能显示出最初没有预料到的重要性。近几个月中，出现了一些功能全面的项目，用于为 Web 应用程序开发用户界面工具箱。这些实现使用 HTML
再加上 JavaScript 技术或者 Flash。其中多数可能已经认识到 “重新发明轮子” 是毫无意义的，开始考虑使 WHATWG
规范标准化，比方说其正式实现。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101D5">
						<span class="atitle">结束语</span>
				</a>
		</p>
		<p>由于明显的需求和规范的完整性，Web Forms 2.0 规范很可能被实现并最终成为认可的标准。事实上 Web Forms 2.0 已经提交给 W3C 请求评论，就像是 WHATWG 合作者的资产负债表和构造块。</p>
		<p>但是，仅仅根据 WHATWG 规范很难描绘 HTML 的未来。一些部分仅仅描述了当前的创新，如 <code>XMLHttpRequest</code> 和 <code>canvas</code>，其他部分似乎还很模糊，没有引起实现者的兴趣。此外，HTML5 的主要动机是桌面的、以应用程序为中心的应用。非 PC 设备上还没有大量使用 HTML，这也是需要发展的一个方向。</p>
		<p>随着基于 Ajax 的浏览器界面工具箱的兴起，HTML5 中某些更深刻的想法可能已经过时了。既然有可扩展的工具箱使用，开发人员何必在文档中使用有限的一组控件呢？更丰富的 Web 界面更有可能通过市场而不是委员会而实现标准化。</p>
		<p>我高兴地看到已经通常实现但还没有标准化的技术如 <code>canvas</code> 和 <code>XMLHttpRequest</code> 的进展，希望能够改进这些重要特性的互操作性。要使浏览器技术沿着自己的方向发展，HTML5 必须更加清晰，最好分为三个规范，分别描述<i>目前</i>、<i>近期</i> 和<i>设想</i> 的特性。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library/x-futhtml1/" target="_blank">英文原文</a>。<br /><br /></li>
				<li>
请访问 <a href="http://www.whatwg.org/">Web Hypertext Application Technology Working Group (WHATWG)</a>，进一步了解 <a href="http://www.whatwg.org/specs/web-apps/current-work/">Web Applications 1.0 (HTML5)</a> 和 <a href="http://www.whatwg.org/specs/web-forms/current-work/">Web Forms 2.0</a>。这些规范包含本文所述特性的全部细节。
<br /><br /></li>
				<li>Ajax 到底是什么和不是什么，请阅读 
<a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">Wikipedia entry</a>。<br /><br /></li>
				<li>
进一步了解 <a href="http://www.ibm.com/developerworks/search/searchResults.jsp?searchType=1&amp;searchSite=dWChina&amp;pageLang=zh&amp;langEncoding=UTF8&amp;searchScope=dW&amp;query=ajax&amp;Search.x=29&amp;Search.y=11">异步 JavaScript 和 XML(Ajax)</a>。developerWorks 提供了关于这种流行技术的大量文章，它使用 JavaScript 和浏览器 <code>XMLHttpRequest</code> 对象创建动态用户界面。<br /><br /></li>
				<li>请把 <a href="http://www.w3.org/">World Wide Web Consortium (W3C) 站点</a> 放入收藏夹，这是很多广泛使用的标准的主页，包括本文所提到的技术：
<ul><li><a href="http://www.w3.org/MarkUp/Forms/">XForms</a></li><li><a href="http://www.w3.org/Submission/2005/02/Comment">W3C Team Comment on Web Forms 2.0 Submission</a></li><li><a href="http://www.w3.org/MarkUp/">HTML/XHTML</a></li><li><a href="http://www.w3.org/Graphics/SVG/">Scalable Vector Graphics (SVG)</a></li></ul><br /></li>
				<li>在 
<a href="http://developer.mozilla.org/en/docs/Canvas_tutorial">Mozilla 开发人员站点</a> 上了解如何使用 <code>canvas</code> 元素。 
<br /><br /></li>
				<li>查看图 1 所示的 <a href="http://rig.vlad1.com/%7Evladimir/canvas/cdemo1.html">简单 <code>canvas</code> 示例</a>。需要 Apple 的 Safari 浏览器或者 Firefox 1.5 的预览版。<br /><br /></li>
				<li>这个 <a href="http://developer.mozilla.org/en/docs/A_Basic_RayCaster">简单的 3D 迷宫</a> 使 <code>canvas</code> 更接近游戏世界。
<br /><br /></li>
				<li>看一看 Antoine Quint 如何 <a href="http://fuchsia-design.com/CanvaSVG/">使用 <code>canvas</code> 部分实现 SVG</a>。
<br /><br /></li>
				<li>来自 SourceForge  的开放源码 <a href="https://sourceforge.net/projects/wf2/">Web Forms 项目</a> 为 Internet Explorer 提供了 DHTML+Behaviors 实现。
 <br /><br /></li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
下载 <a href="http://www.opera.com/">Opera 浏览器</a>。Opera 9 的 beta 版包括 <a href="http://snapshot.opera.com/windows/w90p1.html">Web Forms 2.0 支持</a>。
</li>
		</ul>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www-128.ibm.com/developerworks/cn/xml/x-futhtml1/#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="author">
						<span class="atitle">关于作者</span>
				</a>
		</p>
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td colspan="3">
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" />
								</td>
						</tr>
						<tr align="left" valign="top">
								<td>
										<br />
								</td>
								<td>
										<img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" />
								</td>
								<td width="100%">
										<p>Edd Dumbill 是 Web 和 XML 技术 XTech 会议的主席，Web 和 XML 技术的常设评论员和开放源码开发人员。</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/Vencent/aggbug/35971.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:46 <a href="http://www.blogjava.net/Vencent/articles/35971.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>让你的 XSLT 如虎添翼 -- 浅谈 XSLT 扩展</title><link>http://www.blogjava.net/Vencent/articles/35970.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:45:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35970.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35970.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35970.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35970.html</trackback:ping><description><![CDATA[
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xsltext/#author">马晨 </a>, 软件开发专家<br /></p>
		<p>2006 年  1 月  16 日</p>
		<blockquote>其实 XSLT 能够做的事情很多，绝对超乎你的想象。除了格式转换，XSLT 还能完成一些看起来和格式转换完全无关的工作。比如说文件访问或者是数据库查询等等。而这一切都要归功于 XSLT 扩展（XSLT Extension）。</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>XSLT 是一种基于规则的格式转换语言。在许多人眼里,它的功能就是将一种格式的 xml 文件转换成另外一种格式的 xml 文件，仅此而已。不过，事实真是这样吗？</p>
		<p>其实 XSLT 能够做的事情很多，绝对超乎你的想象。除了格式转换，XSLT 还能完成一些看起来和格式转换完全无关的工作。比如说文件访问或者是数据库查询等等。而这一切都要归功于 XSLT 扩展（XSLT Extension）。</p>
		<p>根
据 XSLT 1.0 的规范，符合标准的 XSLT 引擎应该支持 XSLT 扩展。也就是允许用户自定义 XSLT
的扩展元素（extension elements）和函数(extension functions)。今天我们所看到的主流 XSLT
引擎都按照国际标准，提供了自己的扩展方式。而开源软件中的 saxaon 和 xalan，在这方面走得更远。</p>
		<p>Saxon 和 xalan 都是基于 java 开发的 XSLT 引擎，为它们编写扩展自然也基于 java。一般只要以下 3 步就可以完成一个扩展了。</p>
		<p>1.	编写一个 java 类，在这个类里面设计好扩展功能，并以静态方法的形式提供给XSLT 引擎调用。</p>
		<p>2.	在 XSLT 文件中，声明一个自定义的命名空间（namespace）,该命名空间指出了类的位置</p>
		<p>3.	在 XSLT 文件中，在适当的地方，调用扩展即可。</p>
		<p>接下来让我们看个具体的例子。</p>
		<p>foo_txt.xml
是一个待处理的 XML 文件，其中包含了&lt;filename&gt;和&lt;content&gt;两个元素。现在希望通过 XSLT
处理后，能将 &lt;content&gt; 的内容写入名称为 &lt;filename&gt; 的文件中。</p>
		<br />
		<a name="N10058">
				<b>图表 1:foo_txt.xml</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;?xml version="1.0"?&gt;<br />&lt;document&gt;<br />	&lt;filename&gt;foo.txt&lt;/filename&gt;<br />	&lt;content&gt;Hello,World!&lt;/content&gt;<br />&lt;/document&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>由于这里牵涉到针对文件的操作，因此这个任务必须通过功能扩展来完成。让我们对照着前文提到的 3 步法，来看看 saxon 是怎么来做的。</p>
		<br />
		<a name="N10065">
				<b>图表 2:foo_txt_saxon.xsl</b>
		</a>
		<br />
		<table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">
														<br />&lt;?xml version="1.0"?&gt;<br />&lt;xsl:stylesheet version="1.0"<br />	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"	<br />	xmlns:user="java:com.pear.utils.FileUtil"&gt;    <br /><br />  	&lt;xsl:template match="document"&gt;<br />		&lt;xsl:value-of select="user:output(string(filename),string(content))"/&gt;<br />  	&lt;/xsl:template&gt;<br /><br />&lt;/xsl:stylesheet&gt;<br /></code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
图表 2
	<p>第一步，应该是提供用户编写的自定义java类。由于篇幅关系，这里不再给出源码，请看本文的参考部分，在那里提供了源码下载。</p><p>第二步，在XSLT文件开始，通过"xmlns:user='java:com.pear.utils.FileUtil'"命令，我们定义了一个命名空间。</p><p>最后，在处理XML节点的过程中，我们通过"user：output"成功地调用了用户自定义扩展函数。从而在XSLT中实现了文件写入功能。</p><p>看了saxon的做法之后，如果依样画葫芦的对xalan也来一遍，那么就太没意思了。幸亏xalan提供了一套更有趣的方法。</p><p>先直接看看xalan版本的处理文件吧。</p><br /><a name="N1007E"><b>图表 3:foo_txt_xalan.xsl</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><pre><code class="section"><br /><br />&lt;?xml version="1.0"?&gt;<br />&lt;xsl:stylesheet version="1.0"<br />	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"        <br />	xmlns:xalan="http://xml.apache.org/xalan"<br />	xmlns:user="http://www.mac.home"&gt;<br /><br />	&lt;xalan:component prefix="user" functions="output"&gt;<br />	&lt;xalan:script lang="javascript"&gt;      <br /><br />		function output(filename,content)<br />		{<br />			var a=new java.io.PrintWriter(filename);<br />			a.print(content);<br />			a.close();<br />			return "Finished!";<br />      		}<br /><br />    	&lt;/xalan:script&gt;<br />  	&lt;/xalan:component&gt;<br /><br />  	&lt;xsl:template match="document"&gt;<br />		&lt;xsl:value-of select="user:output(string(filename),string(content))"/&gt;<br />  	&lt;/xsl:template&gt;<br /><br />&lt;/xsl:stylesheet&gt;<br /></code></pre></td></tr></tbody></table><br /><p>注意到它和saxon的版本有什么不同吗？对了，很明显，用户自定义的函数直接在处理文件中就实现了。而且是用javascript来完成的。那么好处在哪儿呢？答案很简单，就是开发人员可以抛开java的编译环境，直接设计自己的 XSLT 功能扩展了。</p><p>除了开发语言换成了javascript 外，其它流程和 saxon 的版本还是挺像的。所以就不再详细解释了。</p><p>不
过值得一提的是，光有javascript还是不够的。在 xalan 版本中，细心的人一定会发现，真正起作用的部分，实际上是一个名字为
PrintWriter 的 java 类。也就是说 javascript 实际上只是一个流程控制者，正是依靠着 java sdk
强大的类库，XSLT 才能如虎添翼，去完成不可能的任务。</p><p>那么是不是只有自己写扩展才能解决问题呢？答案当然是否定的。saxon和xalan早就为我们预制了很多公用的扩展功能。我们只要采用拿来主义就可以了。下面我以数据库扩展为例，进一步向你展示XSLT扩展的魅力。 </p><p>采用 saxon 引擎时，我们引入了几个新的 XSLT 扩展元素，例如 sql:connect,sql:query。通过这些扩展元素，我们可以连接数据库，并执行查询。</p><p>比如在下例中，我们可以利用 saxon 提供的 sql 扩展去访问 Informix 数据库。步骤如下：首先我们利用sql:connect建立和数据库的连接，连接使用的参数预先已经定义好了。</p><p>其次，我们用sql:query进行查询。查询的字段和查询的条件，均以参数的形式出现。</p><p>查询成功之后，利用标准的XSLT元素进行格式解析，并生成HTML格式的表格。</p><p>最后，通过sql:close关闭连接。至此整个处理结束。</p><br /><a name="N100A3"><b>foo_sql_query.xml</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><pre><code class="section"><br />&lt;?xml version="1.0"?&gt;<br />&lt;query&gt;<br />	&lt;table&gt;FOO&lt;/table&gt;<br />	&lt;columns&gt;username,birthdate&lt;/columns&gt;<br />	&lt;condition/&gt;<br />&lt;/query&gt;<br /><br /><br />foo_sql_saxon_query.xsl<br />&lt;?xml version="1.0"?&gt;<br />&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />                version="1.0"<br />                xmlns:sql="java:/net.sf.saxon.sql.SQLElementFactory"<br />		xmlns:saxon="http://saxon.sf.net/"<br />                extension-element-prefixes="saxon sql"&gt;  <br /><br />&lt;xsl:param name="driver" select="'com.informix.jdbc.IfxDriver'"/&gt;<br />&lt;xsl:param name="database"<br />select="'jdbc:informix-sqli://192.168.0.1:5000/testDB:<br />INFORMIXSERVER=pcsnet;user=pcs;password=abc'"/&gt;  <br />&lt;xsl:param name="user" select="'pcs'"/&gt;<br />&lt;xsl:param name="password" select="'abc'"/&gt;<br /><br /><br />&lt;xsl:template match="/"&gt;<br />	&lt;xsl:variable name="connection" as="java:java.sql.Connection"<br />	xmlns:java="http://saxon.sf.net/java-type"&gt;<br />	&lt;sql:connect driver="{$driver}" database="{$database}" user="{$user}" <br />	password="{$password}"/&gt;<br />	&lt;/xsl:variable&gt;<br />        &lt;HTML&gt;<br />        &lt;HEAD&gt;<br />		Table of &lt;xsl:value-of select="/query/table"/&gt;<br />        &lt;/HEAD&gt;<br />        &lt;BODY&gt;<br />		&lt;TABLE border="1"&gt;<br />			&lt;xsl:variable name="dbtable"&gt;<br />				&lt;sql:query connection="$connection" table="{/query/table}"<br />				column="{/query/columns}"/&gt;<br />			&lt;/xsl:variable&gt;<br />			&lt;TR&gt;<br />				&lt;xsl:if test="string-length(/query/columns)&gt;0"&gt;<br />	  			&lt;xsl:call-template name="getcolumns"&gt;<br />					&lt;xsl:with-param name="columns" select="/query/columns"/&gt;<br />				&lt;/xsl:call-template&gt;<br />				&lt;/xsl:if&gt;<br />          		&lt;/TR&gt;<br />			&lt;xsl:apply-templates select="$dbtable/row"/&gt;<br />          		&lt;xsl:text&gt;<br />&lt;/xsl:text&gt;<br />        	&lt;/TABLE&gt;<br />      	&lt;/BODY&gt;<br />    	&lt;/HTML&gt;<br />	&lt;sql:close connection="$connection"/&gt; <br />&lt;/xsl:template&gt;<br /><br />  &lt;xsl:template name="getcolumns"&gt;<br />	&lt;xsl:param name="columns"/&gt;<br />		&lt;xsl:if test="string-length($columns)&gt;0"&gt;<br />		&lt;TH&gt;<br />			&lt;xsl:choose&gt;<br />				&lt;xsl:when test="contains($columns,',')"&gt;<br />					&lt;xsl:value-of select="substring-before($columns,',')"/&gt;<br />				&lt;/xsl:when&gt;<br />				&lt;xsl:otherwise&gt;<br />					&lt;xsl:value-of select="$columns"/&gt;<br />				&lt;/xsl:otherwise&gt;<br />			&lt;/xsl:choose&gt;<br />		&lt;/TH&gt;<br />		&lt;xsl:call-template name="getcolumns"&gt;<br />			&lt;xsl:with-param name="columns" select="substring-after($columns,',')"/&gt;<br />		&lt;/xsl:call-template&gt;<br />		&lt;/xsl:if&gt;<br />  &lt;/xsl:template&gt;<br /><br />  &lt;xsl:template match="row-set"&gt;<br />	&lt;xsl:apply-templates select="row"/&gt;<br />  &lt;/xsl:template&gt;<br /><br />  &lt;xsl:template match="row"&gt;<br />        &lt;TR&gt;<br />          &lt;xsl:apply-templates select="col"/&gt;<br />        &lt;/TR&gt;<br />  &lt;/xsl:template&gt;<br /><br />  &lt;xsl:template match="col"&gt;<br />    	&lt;TD&gt;<br />      	 &lt;xsl:value-of select="text()"/&gt;<br />    	&lt;/TD&gt;<br />  &lt;/xsl:template&gt;<br />&lt;/xsl:stylesheet&gt;<br /></code></pre></td></tr></tbody></table><br /><p>采用xalan引擎时，流程和saxon差不多，不过它还是使用扩展函数来完成数据连接和查询的功能。</p><br /><a name="N100B0"><b>foo_sql_xalan_query.xsl</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><pre><code class="section"><br /><br />&lt;?xml version="1.0"?&gt;<br />&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"<br />                version="1.0"<br />                xmlns:sql="org.apache.xalan.lib.sql.XConnection"<br />                extension-element-prefixes="sql"&gt;  <br /><br />&lt;xsl:param name="driver" select="'com.informix.jdbc.IfxDriver'"/&gt;<br />&lt;xsl:param name="database" select=<br />"'jdbc:informix-sqli://192.168.0.1:5000/testDB:INFORMIXSERVER=pcsnet;user=pcs;password=abc'"/&gt;  <br /><br /><br />&lt;xsl:variable name="query"&gt;<br />	select &lt;xsl:value-of select="/query/columns"/&gt; from &lt;xsl:value-of select="/query/table"/&gt;<br />&lt;/xsl:variable&gt;<br /><br />&lt;xsl:template match="/"&gt;<br />  	&lt;xsl:variable name="connection"  select="sql:new($driver,$database)"/&gt;<br />        &lt;HTML&gt;<br />        &lt;HEAD&gt;<br />		Table of &lt;xsl:value-of select="/query/table"/&gt;<br />        &lt;/HEAD&gt;<br />        &lt;BODY&gt;<br />		&lt;TABLE border="1"&gt;<br />			&lt;xsl:variable name="table" select='sql:query($connection, $query)'/&gt;<br />			&lt;TR&gt;<br />		        	&lt;xsl:for-each select="$table/sql/metadata/column-header"&gt;<br />            			&lt;TH&gt;&lt;xsl:value-of select="@column-label"/&gt;&lt;/TH&gt;<br />          			&lt;/xsl:for-each&gt;<br />          		&lt;/TR&gt;<br /><br />  			&lt;xsl:apply-templates select="$table/sql/row-set"/&gt;<br /><br />          		&lt;xsl:text&gt;<br />&lt;/xsl:text&gt;<br />        	&lt;/TABLE&gt;<br />      	&lt;/BODY&gt;<br />    	&lt;/HTML&gt;<br />	&lt;xsl:variable name="close" select="sql:close($connection)"/&gt; <br />&lt;/xsl:template&gt;<br /><br />  &lt;xsl:template match="row-set"&gt;<br />	&lt;xsl:apply-templates select="row"/&gt;<br />  &lt;/xsl:template&gt;<br /><br />  &lt;xsl:template match="row"&gt;<br />        &lt;TR&gt;<br />          &lt;xsl:apply-templates select="col"/&gt;<br />        &lt;/TR&gt;<br />  &lt;/xsl:template&gt;<br /><br />  &lt;xsl:template match="col"&gt;<br />    	&lt;TD&gt;<br />      	 &lt;xsl:value-of select="text()"/&gt;<br />    	&lt;/TD&gt;<br />  &lt;/xsl:template&gt;<br />&lt;/xsl:stylesheet&gt;<br /></code></pre></td></tr></tbody></table><br /><p>saxon和xalan都是通过jdbc连接数据库的，所以读者如果手头没有informix,只要更换不同的数据库驱动，以及对应的数据库连接参数，就可以在自己的机器上检验效果了。</p><p>以上的这些案例只是揭开了XSLT扩展的神秘面纱，至于怎么去发掘它的潜力，就留给富有创造力的读者去完成吧。</p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/xml/x-xsltext/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="resources"><span class="atitle">参考资料 </span></a></p><ol><li>关于saxon 的相关资料，请参阅Saxonic（<a href="http://www.saxonica.com/">http://www.saxonica.com</a>）</li><li>关于xalan 的相关资料，请参阅 Apache.org (<a href="http://xml.apache.org/xalan-j">http://xml.apache.org/xalan-j</a>)</li><li>关于在xalan中增加对于javascript的支持，请参阅Bean Scripting Framework (<a href="http://jakarta.apache.org/bsf/index.html">http://jakarta.apache.org/bsf/index.html</a>) 和 Rhino （<a href="http://www.mozilla.org/rhino">http://www.mozilla.org/rhino</a>）</li><li>关于XSLT的相关资料，请参阅W3C.org(http://www.w3.org/Style/XSL/)</li><li>程序清单下载：<a href="http://www-128.ibm.com/developerworks/cn/xml/x-xsltext/samplecode.rar">samplecode.rar</a></li></ol><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/xml/x-xsltext/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="author"><span class="atitle">关于作者</span></a></p><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td colspan="3"><img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" /></td></tr><tr align="left" valign="top"><td><br /></td><td><img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" /></td><td width="100%"><p>马晨是上海浦东发展银行温州支行的软件开发专家。自 2000 年来已经在多个平台上开发过不同的应用。目前的工作方向主要侧重于基于 xml 和 javascript 的应用开发。在业余时间喜欢各种运动，尤其喜欢和朋友在周末打打羽毛球。你可以通过电子邮件（<a href="mailto:pearma@gmail.com">pearma@gmail.com</a>）和他联系。</p></td></tr></tbody></table><img src ="http://www.blogjava.net/Vencent/aggbug/35970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:45 <a href="http://www.blogjava.net/Vencent/articles/35970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实用数据绑定: 使用 XPath 作为数据绑定工具，第 2 部分：使用 JAXP API 执行 XPath 查询</title><link>http://www.blogjava.net/Vencent/articles/35969.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 12:44:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35969.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35969.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35969.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35969.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35969.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 级别: 中级						Brett McLaughlin, 作家，编辑, O'Reilly Media, Inc.		2006 年  1 月  23 日		一旦理解了 XPath 语法和位置路径，避开 DOM 和 SAX 的开销访问 XML 就是可能的了，而且很容易。对于 Java™开发人员来说，幸运的是 Java API for XML Processing（JAXP）为...&nbsp;&nbsp;<a href='http://www.blogjava.net/Vencent/articles/35969.html'>阅读全文</a><img src ="http://www.blogjava.net/Vencent/aggbug/35969.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 20:44 <a href="http://www.blogjava.net/Vencent/articles/35969.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3、面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序</title><link>http://www.blogjava.net/Vencent/articles/35961.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 10:58:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35961.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35961.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35961.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35961.html</trackback:ping><description><![CDATA[Ajax 为更好的 Web 应用程序铺平了道路
<p>级别: 中级</p><p><a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#author" target="_blank"><font color="#4455aa">Philip McCarthy </font></a>, 软件开发顾问, 独立咨询顾问</p><p><br />2005 年 10 月 20 日</p><p>在 Web 应用程序开发中，页面重载循环是最大的一个使用障碍，对于 Java<i>&amp;#</i>8482; 开发人员来说也是一个严峻的挑战。在这个系列中，作者 Philip McCarthy 介绍了一种创建动态应用程序体验的开创性方式。Ajax（异步 <i>javascript</i> 和 XML）是一种编程技术，它允许为基于 Java 的 Web 应用程序把 Java 技术、XML 和 <i>javascript</i> 组合起来，从而打破页面重载的范式。<br />Ajax（即异步 <i>javascript</i> 
和 XML）是一种 Web 应用程序开发的手段，它采用客户端脚本与 Web 服务器交换数据。所以，不必采用会中断交互的完整页面刷新，就可以动态地
更新 Web 页面。使用 Ajax，可以创建更加丰富、更加动态的 Web 应用程序用户界面，其即时性与可用性甚至能够接近本机桌面应用程序。</p><p>Ajax 不是一项技术，而更像是一个 模式 —— 一种识别和描述有用的设计技术的方式。Ajax 是新颖的，因为许多开发人员才刚刚开始知道
它，但是所有实现 Ajax 应用程序的组件都已经存在若干年了。它目前受到重视是因为在 2004 和 2005 年出现了一些基于 Ajax 技术的
非常棒的动态 Web UI，最著名的就是 Google 的 GMail 和 Maps 应用程序，以及照片共享站点 Flickr。这些用户界面具有
足够的开创性，有些开发人员称之为“Web 2.0”，因此对 Ajax 应用程序的兴趣飞速上升。</p><p>在这个系列中，我将提供使用 Ajax 开发应用程序需要的全部工具 。在第一篇文章中，我将解释 Ajax 背后的概念，演示为基于 Java 
的 Web 应用程序创建 Ajax 界面的基本步骤。我将使用代码示例演示让 Ajax 应用程序如此动态的服务器端 Java 代码和客户端 <i>javascript</i>。最后，我将指出 Ajax 方式的一些不足，以及在创建 Ajax 应用程序时应当考虑的一些更广的可用性和访问性问题。</p><p><font size="4">更好的购物车</font></p><p>可以用 Ajax 增强传统的 Web 应用程序，通过消除页面装入从而简化交互。为了演示这一点，我采用一个简单的购物车示例，在向里面添加项目
时，它会动态更新。这项技术如果整合到在线商店，那么用户可以持续地浏览和向购物车中添加项目，而不必在每次点击之后都等候完整的页面更新。虽然这篇文章
中的有些代码特定于购物车示例，但是演示的技术可以应用于任何 Ajax 应用程序。清单 1 显示了购物车示例使用的有关 HTML 代码，整篇文章中
都会使用这个 HTML。</p><p><br /><b>清单1. 购物车示例的有关片断</b></p><p>&lt;!-- Table of products from store's catalog, one row per item --&gt;<br />&lt;th&gt;Name&lt;/th&gt; &lt;th&gt;Description&lt;/th&gt; &lt;th&gt;Price&lt;/th&gt; &lt;th&gt;&lt;/th&gt;<br />...<br />&lt;tr&gt;<br />  &lt;!-- Item details --&gt;<br />  &lt;td&gt;Hat&lt;/td&gt; &lt;td&gt;Stylish bowler hat&lt;/td&gt; &lt;td&gt;$19.99&lt;/td&gt;<br />  &lt;td&gt;<br />    &lt;!-- Click button to add item to cart via Ajax request --&gt;<br />    &lt;button <i>onclick</i>="addToCart('hat001')"&gt;Add to Cart&lt;/button&gt;<br />  &lt;/td&gt;<br />&lt;/tr&gt;<br />...</p><p>&lt;!-- Representation of shopping cart, updated asynchronously --&gt;<br />&lt;ul id="cart-contents"&gt;</p><p>  &lt;!-- List-items will be added here for each item in the cart --&gt;<br />  <br />&lt;/ul&gt;</p><p>&lt;!-- Total cost of items in cart displayed inside span element --&gt;<br />Total cost: &lt;span id="total"&gt;$0.00&lt;/span&gt;</p><p><br /><font size="4">Ajax 往返过程</font></p><p>Ajax 交互开始于叫作 XMLHttpRequest 的 <i>javascript</i> 对象。顾名思义，它允许客户端脚本执行
 HTTP 请求，并解析 XML 服务器响应。Ajax 往返过程的第一步是创建 XMLHttpRequest 的实例。在
 XMLHttpRequest 对象上设置请求使用的 HTTP 方法（GET 或 POST）以及目标 URL。</p><p>现在，您还记得 Ajax 的第一个 a 是代表 异步（asynchronous） 吗？在发送 HTTP 请求时，不想让浏览器挂着等候服务器
响应。相反，您想让浏览器继续对用户与页面的交互进行响应，并在服务器响应到达时再进行处理。为了实现这个要求，可以在 XMLHttpRequest 
上注册一个回调函数，然后异步地分派 XMLHttpRequest。然后控制就会返回浏览器，当服务器响应到达时，会调用回调函数。</p><p>在 Java Web 服务器上，请求同其他 HttpServletRequest 一样到达。在解析了请求参数之后，servlet 调用必要的应用程序逻辑，把响应序列化成 XML，并把 XML 写入 HttpServletResponse。</p><p>回到客户端时，现在调用注册在 XMLHttpRequest 上的回调函数，处理服务器返回的 XML 文档。最后，根据服务器返回的数据，用 <i>javascript</i> 操纵页面的 HTML DOM，把用户界面更新。图 1 是 Ajax 往返过程的顺序图。</p><p><br /><b>图 1. Ajax 往返过程</b><br /><a class="contentlink" onfocus="this.blur()" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/ajax.gif" target="_blank"><img alt="" src="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/ajax.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" dypop="按此在新窗口浏览图片" border="0" /></a></p><p>现在您对 Ajax 往返过程有了一个高层面的认识。下面我将放大其中的每一步骤，进行更详细的观察。如果过程中迷了路，请回头看图 1 —— 由于 Ajax 方式的异步性质，所以顺序并非十分简单。</p><p><br /><font size="4">分派 XMLHttpRequest</font></p><p>我将从 Ajax 序列的起点开始：创建和分派来自浏览器的 XMLHttpRequest。不幸的是，不同的浏览器创建 XMLHttpRequest 的方法各不相同。清单 2 的 <i>javascript</i> 函数消除了这些依赖于浏览器的技巧，它可以检测当前浏览器要使用的正确方式，并返回一个可以使用的 XMLHttpRequest。最好是把它当作辅助代码：只要把它拷贝到 <i>javascript</i> 库，并在需要 XMLHttpRequest 的时候使用它就可以了。</p><p><br /><b>清单 2. 创建跨浏览器的 XMLHttpRequest</b></p><p>/*<br /> * Returns a new XMLHttpRequest object, or false if this browser<br /> * doesn't support it<br /> */<br />function newXMLHttpRequest() {</p><p>  var xmlreq = false;</p><p>  if (window.XMLHttpRequest) {</p><p>    // Create XMLHttpRequest object in non-Microsoft browsers<br />    xmlreq = new XMLHttpRequest();</p><p>  } else if (window.ActiveXObject) {</p><p>    // Create XMLHttpRequest via MS ActiveX<br />    try {<br />      // Try to create XMLHttpRequest in later versions<br />      // of Internet Explorer</p><p>      xmlreq = new ActiveXObject("Msxml2.XMLHTTP");</p><p>    } catch (e1) {</p><p>      // Failed to create required ActiveXObject</p><p>      try {<br />        // Try version supported by older versions<br />        // of Internet Explorer</p><p>        xmlreq = new ActiveXObject("Microsoft.XMLHTTP");</p><p>      } catch (e2) {</p><p>        // Unable to create an XMLHttpRequest with ActiveX<br />      }<br />    }<br />  }</p><p>  return xmlreq;<br />}<br />  <br /> </p><p><br />稍后我将讨论处理那些不支持 XMLHttpRequest 的浏览器的技术。目前，示例假设清单 2 的 newXMLHttpRequest 函数总能返回 XMLHttpRequest 实例。</p><p>返回示例的购物车场景，我想要当用户在目录项目上点击 Add to Cart 时启动 Ajax 交互。名为 addToCart() 的 <i>onclick</i> 处理函数负责通过 Ajax 调用来更新购物车的状态（请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#listing1" target="_blank"><font color="#4455aa">清单 1</font></a>）。正如清单 3 所示，addToCart() 需要做的第一件事是通过调用清单 2 的 newXMLHttpRequest() 函数得到 XMLHttpRequest 对象。接下来，它注册一个回调函数，用来接收服务器响应（我稍后再详细解释这一步；请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#listing6" target="_blank"><font color="#4455aa">清单 6</font></a>）。</p><p>因为请求会修改服务器上的状态，所以我将用 HTTP POST 做这个工作。通过 POST 发送数据要求三个步骤。第一，需要打开与要通信的服
务器资源的 POST 连接 —— 在这个示例中，服务器资源是一个映射到 URL cart.do 的 servlet。然后，我在
 XMLHttpRequest 上设置一个头，指明请求的内容是表单 编码的数据。最后，我用表单编码的数据作为请求体发送请求。</p><p>清单 3 把这些步骤放在了一起。</p><p><br /><b>清单 3. 分派 Add to Cart XMLHttpRequest</b></p><p>/*<br /> * Adds an item, identified by its product code, to the shopping cart<br /> * itemCode - product code of the item to add.<br /> */<br />function addToCart(itemCode) {</p><p>  // Obtain an XMLHttpRequest instance<br />  var req = newXMLHttpRequest();</p><p>  // Set the handler function to receive callback notifications<br />  // from the request object<br />  var handlerFunction = getReadyStateHandler(req, updateCart);<br />  req.onreadystatechange = handlerFunction;<br />  <br />  // Open an HTTP POST connection to the shopping cart servlet.<br />  // Third parameter specifies request is asynchronous.<br />  req.open("POST", "cart.do", true);</p><p>  // Specify that the body of the request contains form data<br />  req.setRequestHeader("Content-Type", <br />                       "application/x-www-form-urlencoded");</p><p>  // Send form encoded data stating that I want to add the <br />  // specified item to the cart.<br />  req.send("action=add&amp;item="+itemCode);<br />}</p><p><br />这就是建立 Ajax 往返过程的第一部分，即创建和分派来自客户机的 HTTP 请求。接下来是用来处理请求的 Java servlet 代码。</p><p><br /><font size="4">servlet 请求处理</font></p><p>用 servlet 处理 XMLHttpRequest，与处理普通的浏览器 HTTP 请求一样。可以用
 HttpServletRequest.getParameter() 得到在 POST 请求体中发送的表单编码数据。Ajax 请求被放进与来自应
用程序的常规 Web 请求一样的 HttpSession 中。对于示例购物车场景来说，这很有用，因为这让我可以把购物车状态封装在
 JavaBean 中，并在请求之间在会话中维持这个状态。</p><p>清单 4 是处理 Ajax 请求、更新购物车的简单 servlet 的一部分。Cart bean 是从用户会话中获得的，并根据请求参数更新
它的状态。然后 Cart 被序列化成 XML，XML 又被写入 ServletResponse。重要的是把响应的内容类型设置为
 application/xml，否则 XMLHttpRequest 不会把响应内容解析成 XML DOM。</p><p><br /><b>清单 4. 处理 Ajax 请求的 servlet 代码</b></p><p>public void doPost(HttpServletRequest req, HttpServletResponse res)<br />                        throws java.io.IOException {</p><p>  Cart cart = getCartFromSession(req);</p><p>  String action = req.getParameter("action");<br />  String item = req.getParameter("item");<br />  <br />  if ((action != null)&amp;&amp;(item != null)) {</p><p>    // Add or remove items from the Cart<br />    if ("add".equals(action)) {<br />      cart.addItem(item);</p><p>    } else if ("remove".equals(action)) {<br />      cart.removeItems(item);</p><p>    }<br />  }</p><p>  // Serialize the Cart's state to XML<br />  String cartXml = cart.toXml();</p><p>  // Write XML to response.<br />  res.setContentType("application/xml");<br />  res.getWriter().write(cartXml);<br />}</p><p> </p><p><br />清单 5 显示了 Cart.toXml() 方法生成的示例 XML。它很简单。请注意 cart 元素的 generated 属性，它是 System.currentTimeMillis() 生成的一个时间戳。</p><p><br /><b>清单 5. Cart 对象的XML 序列化示例 </b></p><p>&lt;?xml version="1.0"?&gt;<br />&lt;cart generated="1123969988414" total="$171.95"&gt;<br />  &lt;item code="hat001"&gt;<br />    &lt;name&gt;Hat&lt;/name&gt;<br />    &lt;quantity&gt;2&lt;/quantity&gt;<br />  &lt;/item&gt;<br />  &lt;item code="cha001"&gt;<br />    &lt;name&gt;Chair&lt;/name&gt;<br />    &lt;quantity&gt;1&lt;/quantity&gt;<br />  &lt;/item&gt;<br />  &lt;item code="dog001"&gt;<br />    &lt;name&gt;Dog&lt;/name&gt;<br />    &lt;quantity&gt;1&lt;/quantity&gt;<br />  &lt;/item&gt;<br />&lt;/cart&gt;</p><p> </p><p><br />如果查看应用程序源代码（可以从 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#download" target="_blank"><font color="#4455aa">下载</font></a> 一节得到）中的 Cart.java，可以看到生成 XML 的方式只是把字符串添加在一起。虽然对这个示例来说足够了，但是对于从 Java 代码生成 XML 来说则是最差的方式。我将在这个系列的下一期中介绍一些更好的方式。</p><p>现在您已经知道了 CartServlet 响应 XMLHttpRequest 的方式。下一件事就是返回客户端，查看如何用 XML 响应更新页面状态。</p><p><br /><font size="4">用 <i>javascript</i> 进行响应处理</font></p><p>XMLHttpRequest 的 readyState 属性是一个数值，它指出请求生命周期的状态。它从 0（代表“未初始化”）变化到 4
（代表“完成”）。每次 readyState 变化时，readystatechange 事件就触发，由 onreadystatechange 属
性指定的事件处理函数就被调用。</p><p>在 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#listing3" target="_blank"><font color="#4455aa">清单 3</font></a> 中已经看到了如何调用 getReadyStateHandler() 函数创建事件处理函数。然后把这个事件处理函数分配给 onreadystatechange 属性。getReadyStateHandler() 利用了这样一个事实：函数是 <i>javascript</i> 
中的一级对象。这意味着函数可以是其他函数的参数，也可以创建和返回其他函数。getReadyStateHandler() 的工作是返回一个函数，检
查 XMLHttpRequest 是否已经完成，并把 XML 响应传递给调用者指定的事件处理函数。清单 6 是
 getReadyStateHandler() 的代码。</p><p><br /><b>清单 6. getReadyStateHandler() 函数</b></p><p>/*<br /> * Returns a function that waits for the specified XMLHttpRequest<br /> * to complete, then passes its XML response to the given handler function.<br /> * req - The XMLHttpRequest whose state is changing<br /> * responseXmlHandler - Function to pass the XML response to<br /> */<br />function getReadyStateHandler(req, responseXmlHandler) {</p><p>  // Return an anonymous function that listens to the <br />  // XMLHttpRequest instance<br />  return function () {</p><p>    // If the request's status is "complete"<br />    if (req.readyState == 4) {<br />      <br />      // Check that a successful server response was received<br />      if (req.status == 200) {</p><p>        // Pass the XML payload of the response to the <br />        // handler function<br />        responseXmlHandler(req.responseXML);</p><p>      } else {</p><p>        // An HTTP problem has occurred<br />        alert("HTTP error: "+req.status);<br />      }<br />    }<br />  }<br />}</p><p> </p><p><a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/c.gif" target="_blank"><img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/c.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" /></a> <b>HTTP 状态码</b></p><p>在清单 6 中，检查 XMLHttpRequest 的 status 属性以查看请求是否成功完成。status 包含服务器响应的
 HTTP 状态码。在执行简单的 GET 和 POST 请求时，可以假设任何大于 200 （OK）的码都是错误。如果服务器发送重定向响应（例如
 301 或 302），浏览器会透明地进行重定向并从新的位置获取资源；XMLHttpRequest 看不到重定向状态码。而且，浏览器会自动添加
 Cache-Control: no-cache 头到所有 XMLHttpRequest，这样客户代码永远也不用处理 304（未经修改）服务器响
应。<br /> <br /> <br /><b>关于 getReadyStateHandler()</b></p><p>getReadyStateHandler() 是段相对复杂的代码，特别是如果您不习惯阅读 <i>javascript</i> 的话。但是通过把这个函数放在 <i>javascript</i> 库中，就可以处理 Ajax 服务器响应，而不必处理 XMLHttpRequest 的内部细节。重要的是要理解如何在自己的代码中使用 getReadyStateHandler()。</p><p>在 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#listing3" target="_blank"><font color="#4455aa">清单 3</font></a> 
中看到了 getReadyStateHandler() 像这样被调用：handlerFunction =
 getReadyStateHandler(req, updateCart)。在这个示例中，getReadyStateHandler() 返回的
函数将检查在 req 变量中的 XMLHttpRequest 是否已经完成，然后用响应的 XML 调用名为 updateCart 的函数。</p><p><b>提取购物车数据</b></p><p>清单 7 是 updateCart() 本身的代码。函数用 DOM 调用检查购物车的 XML 文档，然后更新 Web 页面（请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#listing1" target="_blank"><font color="#4455aa">清单 1</font></a>），
反映新的购物车内容。这里的重点是用来从 XML DOM 提取数据的调用。cart 元素的 generated 属性是在 Cart 序列化为
 XML 时生成的一个时间戳，检查它可以保证新的购物车数据不会被旧的数据覆盖。Ajax 请求天生是异步的，所以这个检查可以处理服务器响应未按次序
到达的情况。</p><p><br /><b>清单 7. 更新页面，反映购物车的 XML 文档</b></p><p>function updateCart(cartXML) {</p><p> // Get the root "cart" element from the document<br /> var cart = cartXML.getElementsByTagName("cart")[0];</p><p> // Check that a more recent cart document hasn't been processed<br /> // already<br /> var generated = cart.getAttribute("generated");<br /> if (generated &gt; lastCartUpdate) {<br />   lastCartUpdate = generated;</p><p>   // Clear the HTML list used to display the cart contents<br />   var contents = document.getElementById("cart-contents");<br />   contents.innerHTML = "";</p><p>   // Loop over the items in the cart<br />   var items = cart.getElementsByTagName("item");<br />   for (var I = 0 ; I &lt; items.length ; I++) {</p><p>     var item = items[I];</p><p>     // Extract the text nodes from the name and quantity elements<br />     var name = item.getElementsByTagName("name")[0]<br />                                               .firstChild.node<i>value</i>;<br />                                               <br />     var quantity = item.getElementsByTagName("quantity")[0]<br />                                               .firstChild.node<i>value</i>;</p><p>     // Create and add a list item HTML element for this cart item<br />     var li = document.createElement("li");<br />     li.appendChild(document.createTextNode(name+" x "+quantity));<br />     contents.appendChild(li);<br />   }<br /> }</p><p> // Update the cart's total using the <i>value</i> from the cart document<br /> document.getElementById("total").innerHTML = <br />                                          cart.getAttribute("total");<br />}</p><p> </p><p><br />到此，整个 Ajax 往返过程完成了，但是您可能想让 Web 应用程序运行一下查看实际效果（请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#download" target="_blank"><font color="#4455aa">下载</font></a> 一节）。这个示例非常简单，有很多需要改进之处。例如，我包含了从购物车中清除项目的服务器端代码，但是无法从 UI 访问它。作为一个好的练习，请试着在应用程序现有的 <i>javascript</i> 代码之上构建出能够实现这个功能的代码。</p><p><br /><font size="4">使用 Ajax 的挑战</font></p><p>就像任何技术一样，使用 Ajax 也有许多出错的可能性。我目前在这里讨论的问题还缺乏容易的解决方案，但是会随着 Ajax 的成熟而改进。随着开发人员社区增加开发 Ajax 应用程序的经验，将会记录下最佳实践和指南。</p><p><b>XMLHttpRequest 的可用性</b></p><p>Ajax 开发人员面临的一个最大问题是：在没有 XMLHttpRequest 可用时该如何响应？虽然主要的现代浏览器都支持
 XMLHttpRequest，但仍然有少数用户的浏览器不支持，或者浏览器的安全设置阻止使用 XMLHttpRequest。如果开发的 Web 
应用程序要部署在企业内部网，那么可能拥有指定支持哪种浏览器的权力，从而可以认为 XMLHttpRequest 总能使用。但是，如果要部署在公共
 Web 上，那么就必须当心，如果假设 XMLHttpRequest 可用，那么就可能会阻止那些使用旧的浏览器、残疾人专用浏览器和手持设备上的轻
量级浏览器的用户使用您的应用程序。</p><p>所以，您应当努力让应用程序“平稳降级”，在没有 XMLHttpRequest 支持的浏览器中也能够工作。在购物车的示例中，把应用程序降级的
最好方式可能是让 Add to Cart 按钮执行一个常规的表单提交，刷新页面来反映购物车更新后的状态。Ajax 的行为应当在页面装入的时候就通
过 <i>javascript</i> 添加到页面，只有在 XMLHttpRequest 可用时才把 <i>javascript</i> 事件处理函数附加到每个 Add to Cart 按钮。另一种方式是在用户登录时检测 XMLHttpRequest 是否可用，然后相应地提供应用程序的 Ajax 版本或基于表单的普通版本。</p><p><b>可用性考虑</b></p><p>关于 Ajax 应用程序的某些可用性问题比较普遍。例如，让用户知道他们的输入已经注册了可能是重要的，因为沙漏光标和 spinning 浏览
器的常用反馈机制“throbber”对 XMLHttpRequest 不适用。一种技术是用“Now updating...”类型的信息替换
 Submit 按钮，这样用户在等候响应期间就不会反复单击按钮了。</p><p>另一个问题是，用户可能没有注意到他们正在查看的页面的某一部分已经更新了。可以使用不同的可视技术，把用户的眼球带到页面的更新区域，从而缓解这
个问题。由 Ajax 更新页面造成的其他问题还包括：“破坏了”浏览器的后退按钮，地址栏中的 URL 也无法反映页面的整个状态，妨碍了设置书签。请
参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#resources" target="_blank"><font color="#4455aa">参考资料</font></a> 一节，获得专门解决 Ajax 应用程序可用性问题的文章。</p><p><b>服务器负载</b></p><p>用 Ajax 实现代替普通的基于表单的 UI，会大大提高对服务器发出的请求数量。例如，一个普通的 Google Web 搜索对服务器只有一
个请求，是在用户提交搜索表单时出现的。而 Google Suggest 试图自动完成搜索术语，它要在用户输入时向服务器发送多个请求。在开发
 Ajax 应用程序时，要注意将要发送给服务器的请求数量以及由此造成的服务器负荷。降低服务器负载的办法是，在客户机上对请求进行缓冲并且缓存服务器
响应（如果可能的话）。还应该尝试将 Ajax Web 应用程序设计为在客户机上执行尽可能多的逻辑，而不必联络服务器。</p><p><b>处理异步</b></p><p>非常重要的是，要理解无法保证 XMLHttpRequest 会按照分派它们的顺序完成。实际上，应当假设它们不会按顺序完成，并且在设计应用程序时把这一点记在心上。在购物车的示例中，使用最后更新的时间戳来确保新的购物车数据不会被旧的数据覆盖（请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#listing7" target="_blank"><font color="#4455aa">清单 7</font></a>）。这个非常基本的方式可以用于购物车场景，但是可能不适合其他场景。所以在设计时请考虑如何处理异步的服务器响应。</p><p><br /><font size="4">结束语</font></p><p>现在您对 Ajax 的基本原则应当有了很好的理解，对参与 Ajax 交互的客户端和服务器端组件也应当有了初步的知识。这些是基于 Java 
的 Ajax Web 应用程序的构造块。另外，您应当理解了伴随 Ajax 方式的一些高级设计问题。创建成功的 Ajax 应用程序要求整体考虑，从
 UI 设计到 <i>javascript</i> 设计，再到服务器端架构；但是您现在应当已经武装了考虑其他这些方面所需要的核心 Ajax 知识。</p><p>如果使用这里演示的技术编写大型 Ajax 应用程序的复杂性让您觉得恐慌，那么有好消息给您。由于 Struts、Spring 和
 Hibernate 这类框架的发展把 Web 应用程序开发从底层 Servlet API 和 JDBC 的细节中抽象出来，所以正在出现简化
 Ajax 开发的工具包。其中有些只侧重于客户端，提供了向页面添加可视效果的简便方式，或者简化了对 XMLHttpRequest 的使用。有些则
走得更远，提供了从服务器端代码自动生成 Ajax 接口的方式。这些框架替您完成了繁重的任务，所以您可以采用更高级的方式进行 Ajax 开发。我在
这个系列中将研究其中的一些。</p><p>Ajax 社区正在快速前进，所以会有大量有价值的信息涌现。在阅读这个系列的下一期之前，我建议您参考 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/#resources" target="_blank"><font color="#4455aa">参考资料</font></a> 一节中列出的文章，特别是如果您是刚接触 Ajax 或客户端开发的话。您还应当花些时间研究示例源代码并考虑一些增强它的方式。</p><p>在这个系列的下一篇文章中，我将深入讨论 XMLHttpRequest API，并推荐一些从 JavaBean 方便地创建 XML 的方式。我还将介绍替代 XML 进行 Ajax 数据传递的方式，例如 JSON（<i>javascript</i> Object Notation）轻量级数据交换格式。</p><p><font size="4">下载</font></p><p>描述 名字 大小  下载方法 <br />Sample code j-ajax1.zip 8 KB  <b>FTP</b> <br /><a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/c.gif" target="_blank"><img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/c.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" /></a> <br /><a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/v14/icons/fw.gif" target="_blank"><img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/v14/icons/fw.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" /></a> <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/whichmethod.html" target="_blank"><font color="#4455aa">关于下载方法的信息</font></a> <a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/c.gif" target="_blank"><img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/c.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" /></a> <a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/v14/icons/sout.gif" target="_blank"><img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/v14/icons/sout.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" /></a> <a class="contentlink" href="http://www.adobe.com/products/acrobat/readstep2.html" target="_blank"><font color="#4455aa">获取 Adobe® Reader®</font></a> </p>
		
			posted on 2006-02-19 10:51 <a href="../../mlh123caoer/">草儿</a> 阅读(4) <a href="../../mlh123caoer/articles/31443.html#Post">评论(0)</a>  <a href="../../mlh123caoer/admin/EditArticles.aspx?postid=31443">编辑</a> <a href="../../mlh123caoer/AddToFavorite.aspx?id=31443">收藏</a><a href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();" title="功能强大的网络收藏夹，一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐">收藏至365K</a><img src ="http://www.blogjava.net/Vencent/aggbug/35961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 18:58 <a href="http://www.blogjava.net/Vencent/articles/35961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax 简介</title><link>http://www.blogjava.net/Vencent/articles/35960.html</link><dc:creator>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</dc:creator><author>&lt;font color='GREEN'&gt;Vincent Chen&lt;/font&gt;</author><pubDate>Sat, 18 Mar 2006 10:57:00 GMT</pubDate><guid>http://www.blogjava.net/Vencent/articles/35960.html</guid><wfw:comment>http://www.blogjava.net/Vencent/comments/35960.html</wfw:comment><comments>http://www.blogjava.net/Vencent/articles/35960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Vencent/comments/commentRss/35960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Vencent/services/trackbacks/35960.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="../../mlh123caoer/articles/31442.html">1、Ajax 简介</a>
		</h2>
		<p>理解 Ajax 及其工作原理，构建网站的一种有效方法<br /> <br />级别: 初级</p>
		<p>
				<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#author" target="_blank">
						<font color="#4455aa">Brett McLaughlin </font>
				</a>, 作家，编辑, O'Reilly and Associates</p>
		<p>
				<br />2006 年 1 月 04 日</p>
		<p>Ajax 由 HTML、<i>javascript</i><i>&amp;#</i>8482; 技术、DHTML 和 DOM 组成，这一杰
出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。本文的作者是一位 Ajax 专家，他演示了这些技术如何协同工作 —— 从总
体概述到细节的讨论 —— 使高效的 Web 开发成为现实。他还揭开了 Ajax 核心概念的神秘面纱，包括 XMLHttpRequest 对象。<br />五年前，如果不知道 XML，您就是一只无人重视的丑小鸭。十八个月前，Ruby 成了关注的中心，不知道 Ruby 的程序员只能坐冷板凳了。今天，如果想跟上最新的技术时尚，那您的目标就是 Ajax。</p>
		<p>但是，Ajax 不仅仅 是一种时尚，它是一种构建网站的强大方法，而且不像学习一种全新的语言那样困难。</p>
		<p>但在详细探讨 Ajax 是什么之前，先让我们花几分钟了解 Ajax 做 什么。目前，编写应用程序时有两种基本的选择：</p>
		<p>桌面应用程序 <br />Web 应用程序<br />两者是类似的，桌面应用程序通常以 CD 为介质（有时候可从网站下载）并完全安装到您的计算机
上。桌面应用程序可能使用互联网下载更新，但运行这些应用程序的代码在桌面计算机上。Web 应用程序运行在某处的 Web 服务器上 —— 毫不奇怪，
要通过 Web 浏览器访问这种应用程序。</p>
		<p>不过，比这些应用程序的运行代码放在何处更重要的是，应用程序如何运转以及如何与其进行交互。桌面应用程序一般很快（就在您的计算机上运行，不用等
待互联网连接），具有漂亮的用户界面（通常和操作系统有关）和非凡的动态性。可以单击、选择、输入、打开菜单和子菜单、到处巡游，基本上不需要等待。</p>
		<p>另一方面，Web 应用程序是最新的潮流，它们提供了在桌面上不能实现的服务（比如 Amazon.com 和 eBay）。但是，伴随着 Web 的强大而出现的是等待，等待服务器响应，等待屏幕刷新，等待请求返回和生成新的页面。</p>
		<p>显然这样说过于简略了，但基本的概念就是如此。您可能已经猜到，Ajax 尝试建立桌面应用程序的功能和交互性，与不断更新的 Web 应用程序之间的桥梁。可以使用像桌面应用程序中常见的动态用户界面和漂亮的控件，不过是在 Web 应用程序中。</p>
		<p>还等什么呢？我们来看看 Ajax 如何将笨拙的 Web 界面转化成能迅速响应的 Ajax 应用程序吧。</p>
		<p>
				<font size="4">老技术，新技巧</font>
		</p>
		<p>在谈到 Ajax 时，实际上涉及到多种技术，要灵活地运用它必须深入了解这些不同的技术（本系列的头几篇文章将分别讨论这些技术）。好消息是您可
能已经非常熟悉其中的大部分技术，更好的是这些技术都很容易学习，并不像完整的编程语言（如 Java 或 Ruby）那样困难。</p>
		<p>
				<a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/c.gif" target="_blank">
						<img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/c.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" />
				</a> <b>Ajax 的定义</b></p>
		<p>顺便说一下，Ajax 是 Asynchronous <i>javascript</i> and XML（以及 DHTML 等）的缩写。这个短语是 Adaptive Path 的 Jesse James Garrett 发明的（请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#resources" target="_blank"><font color="#4455aa">参考资料</font></a>），按照 Jesse 的解释，这不是 个首字母缩写词。<br /> <br /> <br />下面是 Ajax 应用程序所用到的基本技术：</p>
		<p>HTML 用于建立 Web 表单并确定应用程序其他部分使用的字段。 <br /><i>javascript</i> 代码是运行 Ajax 应用程序的核心代码，帮助改进与服务器应用程序的通信。 <br />DHTML 或 Dynamic HTML，用于动态更新表单。我们将使用 div、span 和其他动态 HTML 元素来标记 HTML。 <br />文档对象模型 DOM 用于（通过 <i>javascript</i> 代码）处理 HTML 结构和（某些情况下）服务器返回的 XML。<br />我们来进一步分析这些技术的职责。以后的文章中我将深入讨论这些技术，目前只要熟悉这些组件和技术就可以了。对这些代码越熟悉，就越容易从对这些技术的零散了解转变到真正把握这些技术（同时也真正打开了 Web 应用程序开发的大门）。</p>
		<p>
				<b>XMLHttpRequest 对象</b>
		</p>
		<p>要了解的一个对象可能对您来说也是最陌生的，即 XMLHttpRequest。这是一个 <i>javascript</i> 对象，创建该对象很简单，如<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code1" target="_blank"><font color="#4455aa">清单 1</font></a> 所示。</p>
		<p>
				<br />
				<b>清单 1. 创建新的 XMLHttpRequest 对象</b>
		</p>
		<p>&lt;script language="<i>javascript</i>" type="text/<i>javascript</i>"&gt;<br />var xmlHttp = new XMLHttpRequest();<br />&lt;/script&gt;</p>
		<p>
				<br />下一期文章中将进一步讨论这个对象，现在要知道这是处理所有服务器通信的对象。继续阅读之前，先停下来想一想：通过 XMLHttpRequest 对象与服务器进行对话的是 <i>javascript</i> 技术。这不是一般的应用程序流，这恰恰是 Ajax 的强大功能的来源。</p>
		<p>在一般的 Web 应用程序中，用户填写表单字段并单击 Submit 按钮。然后整个表单发送到服务器，服务器将它转发给处理表单的脚本（通常是
 PHP 或 Java，也可能是 CGI 进程或者类似的东西），脚本执行完成后再发送回全新的页面。该页面可能是带有已经填充某些数据的新表单的
 HTML，也可能是确认页面，或者是具有根据原来表单中输入数据选择的某些选项的页面。当然，在服务器上的脚本或程序处理和返回新表单时用户必须等待。
屏幕变成一片空白，等到服务器返回数据后再重新绘制。这就是交互性差的原因，用户得不到立即反馈，因此感觉不同于桌面应用程序。</p>
		<p>Ajax 基本上就是把 <i>javascript</i> 技术和 XMLHttpRequest 对象放在 Web 表单和服务器之间。当用户填写表单时，数据发送给一些 <i>javascript</i> 代码而不是 直接发送给服务器。相反，<i>javascript</i> 代码捕获表单数据并向服务器发送请求。同时用户屏幕上的表单也不会闪烁、消失或延迟。换句话说，<i>javascript</i> 代码在幕后发送请求，用户甚至不知道请求的发出。更好的是，请求是异步发送的，就是说 <i>javascript</i> 代码（和用户）不用等待服务器的响应。因此用户可以继续输入数据、滚动屏幕和使用应用程序。</p>
		<p>然后，服务器将数据返回 <i>javascript</i> 代码（仍然在 Web 表单中），后者决定如何处理这些数据。它可以迅速更新表单数据，让人感觉应用程序是立即完成的，表单没有提交或刷新而用户得到了新数据。<i>javascript</i> 
代码甚至可以对收到的数据执行某种计算，再发送另一个请求，完全不需要用户干预！这就是 XMLHttpRequest 的强大之处。它可以根据需要自行
与服务器进行交互，用户甚至可以完全不知道幕后发生的一切。结果就是类似于桌面应用程序的动态、快速响应、高交互性的体验，但是背后又拥有互联网的全部强
大力量。</p>
		<p>
				<b>加入一些 <i>javascript</i></b>
		</p>
		<p>得到 XMLHttpRequest 的句柄后，其他的 <i>javascript</i> 代码就非常简单了。事实上，我们将使用 <i>javascript</i> 代码完成非常基本的任务：</p>
		<p>获取表单数据：<i>javascript</i> 代码很容易从 HTML 表单中抽取数据并发送到服务器。 <br />修改表单上的数据：更新表单也很简单，从设置字段值到迅速替换图像。 <br />解析 HTML 和 XML：使用 <i>javascript</i> 代码操纵 DOM（请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#dom" target="_blank"><font color="#4455aa">下一节</font></a>），处理 HTML 表单服务器返回的 XML 数据的结构。<br />对于前两点，需要非常熟悉 getElementById() 方法，如 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code2" target="_blank"><font color="#4455aa">清单 2</font></a> 所示。</p>
		<p>
				<br />
				<b>清单 2. 用 <i>javascript</i> 代码捕获和设置字段值</b>
		</p>
		<p>// Get the <i>value</i> of the "phone" field and stuff it in a variable called phone<br />var phone = document.getElementById("phone").<i>value</i>;</p>
		<p>// Set some <i>value</i>s on a form using an array called response<br />document.getElementById("order").<i>value</i> = response[0];<br />document.getElementById("address").<i>value</i> = response[1];</p>
		<p>
				<br />这里没有特别需要注意的地方，真是好极了！您应该认识到这里并没有非常复杂的东西。只要掌握了 XMLHttpRequest，Ajax 应用程序的其他部分就是如 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code2" target="_blank"><font color="#4455aa">清单 2</font></a> 所示的简单 <i>javascript</i> 代码了，混合有少量的 HTML。同时，还要用一点儿 DOM，我们就来看看吧。</p>
		<p>
				<b>以 DOM 结束</b>
		</p>
		<p>最后还有 DOM，即文档对象模型。可能对有些读者来说 DOM 有点儿令人生畏，HTML 设计者很少使用它，即使 <i>javascript</i> 程序员也不大用到它，除非要完成某项高端编程任务。大量使用 DOM 的是 复杂的 Java 和 C/C++ 程序，这可能就是 DOM 被认为难以学习的原因。</p>
		<p>幸运的是，在 <i>javascript</i> 技术中使用 DOM 很容易，也非常直观。现在，按照常规也许应该说明如何使用 DOM，或者
至少要给出一些示例代码，但这样做也可能误导您。即使不理会 DOM，仍然能深入地探讨 Ajax，这也是我准备采用的方法。以后的文章将再次讨论
 DOM，现在只要知道可能需要 DOM 就可以了。当需要在 <i>javascript</i> 代码和服务器之间传递 XML 和改变 HTML 表单的时候，我们再深入研究 DOM。没有它也能做一些有趣的工作，因此现在就把 DOM 放到一边吧。</p>
		<p>
				<br />
				<font size="4">获取 Request 对象</font>
		</p>
		<p>有了上面的基础知识后，我们来看看一些具体的例子。XMLHttpRequest 是 Ajax 应用程序的核心，而且对很多读者来说可能还比较陌生，我们就从这里开始吧。从 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code1" target="_blank"><font color="#4455aa">清单 1</font></a> 可以看出，创建和使用这个对象非常简单，不是吗？等一等。</p>
		<p>还记得几年前的那些讨厌的浏览器战争吗？没有一样东西在不同的浏览器上得到同样的结果。不管您是否相信，这些战争仍然在继续，虽然规模较小。但令人
奇怪的是，XMLHttpRequest 成了这场战争的牺牲品之一。因此获得 XMLHttpRequest 对象可能需要采用不同的方法。下面我将详
细地进行解释。</p>
		<p>
				<b>使用 Microsoft 浏览器</b>
		</p>
		<p>Microsoft 浏览器 Internet Explorer 使用 MSXML 解析器处理 XML（可以通过 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#resources" target="_blank"><font color="#4455aa">参考资料</font></a> 进一步了解 MSXML）。因此如果编写的 Ajax 应用程序要和 Internet Explorer 打交道，那么必须用一种特殊的方式创建对象。</p>
		<p>但并不是这么简单。根据 Internet Explorer 中安装的 <i>javascript</i> 技术版本不同，MSXML 实际上有两种不同的版本，因此必须对这两种情况分别编写代码。请参阅 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code3" target="_blank"><font color="#4455aa">清单 3</font></a>，其中的代码在 Microsoft 浏览器上创建了一个 XMLHttpRequest。</p>
		<p>
				<br />
				<b>清单 3. 在 Microsoft 浏览器上创建 XMLHttpRequest 对象</b>
		</p>
		<p>var xmlHttp = false;<br />try {<br />  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");<br />} catch (e) {<br />  try {<br />    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br />  } catch (e2) {<br />    xmlHttp = false;<br />  }<br />}</p>
		<p> </p>
		<p>
				<br />您对这些代码可能还不完全理解，但没有关系。当本系列文章结束的时候，您将对 <i>javascript</i> 编程、错误处理、条件编译等有更深的了解。现在只要牢牢记住其中的两行代码：</p>
		<p>xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");</p>
		<p>和</p>
		<p>xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");。</p>
		<p>这两行代码基本上就是尝试使用一个版本的 MSXML 创建对象，如果失败则使用另一个版本创建该对象。不错吧？如果都不成功，则将
 xmlHttp 变量设为 false，告诉您的代码出现了问题。如果出现这种情况，可能是因为安装了非 Microsoft 浏览器，需要使用不同的
代码。</p>
		<p>
				<b>处理 Mozilla 和非 Microsoft 浏览器</b>
		</p>
		<p>如果选择的浏览器不是 Internet Explorer，或者为非 Microsoft 浏览器编写代码，就需要使用不同的代码。事实上就是 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code1" target="_blank"><font color="#4455aa">清单 1</font></a> 所示的一行简单代码：</p>
		<p>var xmlHttp = new XMLHttpRequest object;。</p>
		<p>这行简单得多的代码在 Mozilla、Firefox、Safari、Opera 以及基本上所有以任何形式或方式支持 Ajax 的非 Microsoft 浏览器中，创建了 XMLHttpRequest 对象。</p>
		<p>
				<b>结合起来</b>
		</p>
		<p>关键是要支持所有 浏览器。谁愿意编写一个只能用于 Internet Explorer 或者非 Microsoft 浏览器的应用程序呢？或者
更糟，要编写一个应用程序两次？当然不！因此代码要同时支持 Internet Explorer 和非 Microsoft 浏览器。<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code4" target="_blank"><font color="#4455aa">清单 4</font></a> 显示了这样的代码。</p>
		<p>
				<br />
				<b>清单 4. 以支持多种浏览器的方式创建 XMLHttpRequest 对象</b>
		</p>
		<p>/* Create a new XMLHttpRequest object to talk to the Web server */<br />var xmlHttp = false;<br />/*@cc_on @*/<br />/*@if (@_jscript_version &gt;= 5)<br />try {<br />  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");<br />} catch (e) {<br />  try {<br />    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br />  } catch (e2) {<br />    xmlHttp = false;<br />  }<br />}<br />@end @*/</p>
		<p>if (!xmlHttp &amp;&amp; typeof XMLHttpRequest != 'undefined') {<br />  xmlHttp = new XMLHttpRequest();<br />}</p>
		<p> </p>
		<p>
				<br />现在先不管那些注释掉的奇怪符号，如 @cc_on，这是特殊的 <i>javascript</i> 编译器命令，将在下一期针对 XMLHttpRequest 的文章中详细讨论。这段代码的核心分为三步：</p>
		<p>建立一个变量 xmlHttp 来引用即将创建的 XMLHttpRequest 对象。 <br />尝试在 Microsoft 浏览器中创建该对象： <br />尝试使用 Msxml2.XMLHTTP 对象创建它。 <br />如果失败，再尝试 Microsoft.XMLHTTP 对象。<br />如果仍然没有建立 xmlHttp，则以非 Microsoft 的方式创建该对象。<br />最后，xmlHttp 应该引用一个有效的 XMLHttpRequest 对象，无论运行什么样的浏览器。</p>
		<p>
				<b>关于安全性的一点说明</b>
		</p>
		<p>安全性如何呢？现在浏览器允许用户提高他们的安全等级，关闭 <i>javascript</i> 技术，禁用浏览器中的任何选项。在这种情况下，
代码无论如何都不会工作。此时必须适当地处理问题，这需要单独的一篇文章来讨论，要放到以后了（这个系列够长了吧？不用担心，读完之前也许您就掌握了）。
现在要编写一段健壮但不够完美的代码，对于掌握 Ajax 来说就很好了。以后我们还将讨论更多的细节。</p>
		<p>
				<font size="4">Ajax 世界中的请求/响应</font>
		</p>
		<p>现在我们介绍了 Ajax，对 XMLHttpRequest 对象以及如何创建它也有了基本的了解。如果阅读得很仔细，您可能已经知道与服务器上的 Web 应用程序打交道的是 <i>javascript</i> 技术，而不是直接提交给那个应用程序的 HTML 表单。</p>
		<p>还缺少什么呢？到底如何使用 XMLHttpRequest。因为这段代码非常重要，您编写的每个 Ajax 应用程序都要以某种形式使用它，先看看 Ajax 的基本请求/响应模型是什么样吧。</p>
		<p>
				<b>发出请求</b>
		</p>
		<p>您已经有了一个崭新的 XMLHttpRequest 对象，现在让它干点活儿吧。首先需要一个 Web 页面能够调用的 <i>javascript</i> 方法（比如当用户输入文本或者从菜单中选择一项时）。接下来就是在所有 Ajax 应用程序中基本都雷同的流程：</p>
		<p>从 Web 表单中获取需要的数据。 <br />建立要连接的 URL。 <br />打开到服务器的连接。 <br />设置服务器在完成后要运行的函数。 <br />发送请求。<br /><a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code5" target="_blank"><font color="#4455aa">清单 5</font></a> 中的示例 Ajax 方法就是按照这个顺序组织的：</p>
		<p>
				<br />
				<b>清单 5. 发出 Ajax 请求</b>
		</p>
		<p>function callServer() {<br />  // Get the city and state from the web form<br />  var city = document.getElementById("city").<i>value</i>;<br />  var state = document.getElementById("state").<i>value</i>;<br />  // Only go on if there are <i>value</i>s for both fields<br />  if ((city == null) || (city == "")) return;<br />  if ((state == null) || (state == "")) return;</p>
		<p>  // Build the URL to connect to<br />  var url = "/scripts/getZipCode.php?city=" + escape(city) + "&amp;state=" + escape(state);</p>
		<p>  // Open a connection to the server<br />  xmlHttp.open("GET", url, true);</p>
		<p>  // Setup a function for the server to run when it's done<br />  xmlHttp.onreadystatechange = updatePage;</p>
		<p>  // Send the request<br />  xmlHttp.send(null);<br />}</p>
		<p> </p>
		<p>
				<br />其中大部分代码意义都很明确。开始的代码使用基本 <i>javascript</i> 代码获取几个表单字段的值。然后设置一个 PHP 脚本作为链接的目标。要注意脚本 URL 的指定方式，city 和 state（来自表单）使用简单的 GET 参数附加在 URL 之后。</p>
		<p>然后打开一个连接，这是您第一次看到使用 XMLHttpRequest。其中指定了连接方法（GET）和要连接的 URL。最后一个参数如果设为
 true，那么将请求一个异步连接（这就是 Ajax 的由来）。如果使用 false，那么代码发出请求后将等待服务器返回的响应。如果设为
 true，当服务器在后台处理请求的时候用户仍然可以使用表单（甚至调用其他 <i>javascript</i> 方法）。</p>
		<p>xmlHttp（要记住，这是 XMLHttpRequest 对象实例）的 onreadystatechange 属性可以告诉服务器在运行完
成 后（可能要用五分钟或者五个小时）做什么。因为代码没有等待服务器，必须让服务器知道怎么做以便您能作出响应。在这个示例中，如果服务器处理完了请
求，一个特殊的名为 updatePage() 的方法将被触发。</p>
		<p>最后，使用值 null 调用 send()。因为已经在请求 URL 中添加了要发送给服务器的数据（city 和 state），所以请求中不需要发送任何数据。这样就发出了请求，服务器按照您的要求工作。</p>
		<p>如果没有发现任何新鲜的东西，您应该体会到这是多么简单明了！除了牢牢记住 Ajax 的异步特性外，这些内容都相当简单。应该感激 Ajax 使您能够专心编写漂亮的应用程序和界面，而不用担心复杂的 HTTP 请求/响应代码。</p>
		<p>
				<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code5" target="_blank">
						<font color="#4455aa">清单 5</font>
				</a> 中的代码说明了 Ajax 的易用性。数据是简单的文本，可以作为请求 URL 的一部分。用 GET 而不是更复杂的 POST 发送请求。没有 XML 和要添加的内容头部，请求体中没有要发送的数据；换句话说，这就是 Ajax 的乌托邦。</p>
		<p>不用担心，随着本系列文章的展开，事情会变得越来越复杂。您将看到如何发送 POST 请求、如何设置请求头部和内容类型、如何在消息中编码
 XML、如何增加请求的安全性，可以做的工作还有很多！暂时先不用管那些难点，掌握好基本的东西就行了，很快我们就会建立一整套的 Ajax 工具库。</p>
		<p>
				<b>处理响应</b>
		</p>
		<p>现在要面对服务器的响应了。现在只要知道两点：</p>
		<p>什么也不要做，直到 xmlHttp.readyState 属性的值等于 4。 <br />服务器将把响应填充到 xmlHttp.responseText 属性中。<br />其
中的第一点，即就绪状态，将在下一篇文章中详细讨论，您将进一步了解 HTTP 请求的阶段，可能比您设想的还多。现在只要检查一个特定的值（4）就可以
了（下一期文章中还有更多的值要介绍）。第二点，使用 xmlHttp.responseText 属性获得服务器的响应，这很简单。<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code6" target="_blank"><font color="#4455aa">清单 6</font></a> 中的示例方法可供服务器根据 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code5" target="_blank"><font color="#4455aa">清单 5</font></a> 中发送的数据调用。</p>
		<p>
				<br />
				<b>清单 6. 处理服务器响应</b>
		</p>
		<p>function updatePage() {<br />  if (xmlHttp.readyState == 4) {<br />    var response = xmlHttp.responseText;<br />    document.getElementById("zipCode").<i>value</i> = response;<br />  }<br />}</p>
		<p> </p>
		<p>
				<br />这些代码同样既不难也不复杂。它等待服务器调用，如果是就绪状态，则使用服务器返回的值（这里是用户输入的城市和州的 ZIP 编码）设置
另一个表单字段的值。于是包含 ZIP 编码的 zipCode 字段突然出现了，而用户没有按任何按钮！这就是前面所说的桌面应用程序的感觉。快速响
应、动态感受等等，这些都只因为有了小小的一段 Ajax 代码。</p>
		<p>细心的读者可能注意到 zipCode 是一个普通的文本字段。一旦服务器返回 ZIP 编码，updatePage() 方法就用城市/州的
 ZIP 编码设置那个字段的值，用户就可以改写该值。这样做有两个原因：保持例子简单，说明有时候可能希望 用户能够修改服务器返回的数据。要记住这两
点，它们对于好的用户界面设计来说很重要。</p>
		<p>
				<br />
				<font size="4">连接 Web 表单</font>
		</p>
		<p>还有什么呢？实际上没有多少了。一个 <i>javascript</i> 方法捕捉用户输入表单的信息并将其发送到服务器，另一个 <i>javascript</i> 方法监听和处理响应，并在响应返回时设置字段的值。所有这些实际上都依赖于调用 第一个 <i>javascript</i> 方法，它启动了整个过程。最明显的办法是在 HTML 表单中增加一个按钮，但这是 2001 年的办法，您不这样认为吗？还是像 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#code7" target="_blank"><font color="#4455aa">清单 7</font></a> 这样利用 <i>javascript</i> 技术吧。</p>
		<p>
				<br />
				<b>清单 7. 启动一个 Ajax 过程</b>
		</p>
		<p>&lt;form&gt;<br /> &lt;p&gt;City: &lt;input type="text" name="city" id="city" size="25" <br />       <b>onChange="callServer();"</b> /&gt;&lt;/p&gt;<br /> &lt;p&gt;State: &lt;input type="text" name="state" id="state" size="25" <br />       <b>onChange="callServer();"</b> /&gt;&lt;/p&gt;<br /> &lt;p&gt;Zip Code: &lt;input type="text" name="zipCode" id="city" size="5" /&gt;&lt;/p&gt;<br />&lt;/form&gt;</p>
		<p> </p>
		<p>
				<br />如果感觉这像是一段相当普通的代码，那就对了，正是如此！当用户在 city 或 state 字段中输入新的值时，callServer() 方法就被触发，于是 Ajax 开始运行了。有点儿明白怎么回事了吧？好，就是如此！</p>
		<p>
				<font size="4">结束语</font>
		</p>
		<p>现在您可能已经准备开始编写第一个 Ajax 应用程序了，至少也希望认真读一下 <a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#resources" target="_blank"><font color="#4455aa">参考资料</font></a> 中的那些文章了吧？但可以首先从这些应用程序如何工作的基本概念开始，对 XMLHttpRequest 对象有基本的了解。在下一期文章中，您将掌握这个对象，学会如何处理 <i>javascript</i> 和服务器的通信、如何使用 HTML 表单以及如何获得 DOM 句柄。</p>
		<p>现在先花点儿时间考虑考虑 Ajax 应用程序有多么强大。设想一下，当单击按钮、输入一个字段、从组合框中选择一个选项或者用鼠标在屏幕上拖动时，Web 表单能够立刻作出响应会是什么情形。想一想异步 究竟意味着什么，想一想 <i>javascript</i> 代码运行而且不等待 服务器对它的请求作出响应。会遇到什么样的问题？会进入什么样的领域？考虑到这种新的方法，编程的时候应如何改变表单的设计？</p>
		<p>如果在这些问题上花一点儿时间，与简单地剪切/粘贴某些代码到您根本不理解的应用程序中相比，收益会更多。在下一期文章中，我们将把这些概念付诸实践，详细介绍使应用程序按照这种方式工作所需要的代码。因此，现在先享受一下 Ajax 所带来的可能性吧。</p>
		<p>
				<br />
				<a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/v14/rules/blue_rule.gif" target="_blank">
						<img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" />
				</a> <br /><a class="contentlink" onfocus="this.blur()" href="http://www.ibm.com/i/v14/icons/u_bold.gif" target="_blank"><img alt="按此在新窗口浏览图片" src="http://www.ibm.com/i/v14/icons/u_bold.gif" onload="javascript:if(this.width&gt;screen.width-333)this.width=screen.width-333" border="0" /></a><br /> [URL=http://www-128.ibm.com/developerworks/cn/xml/wa-ajaxintro1.html#main]<b>回页首</b>[/URL] <br /> </p>
		<p>参考资料 </p>
		<p>
				<b>学习</b>
		</p>
		<p>您可以参阅本文在 developerWorks 全球站点上的 <a class="contentlink" href="http://www.ibm.com/developerworks/xml/library/wa-ajaxintro1.html" target="_blank"><font color="#4455aa">英文原文</font></a>。</p>
		<p>
				<br />
				<a class="contentlink" href="http://www.adaptivepath.com/" target="_blank">
						<font color="#4455aa">Adaptive Path</font>
				</a> 是一家领先的用户界面设计公司，仔细阅读他们的网站可以更多地了解 Ajax。 </p>
		<p>
				<br />如果关心 Ajax 一词的来历，请看一看 <a class="contentlink" href="http://adaptivepath.com/team/jjg.php" target="_blank"><font color="#4455aa">Jesse James Garrett</font></a> 和他的 Ajax 文章（比如 <a class="contentlink" href="http://adaptivepath.com/publications/essays/archives/000385.php" target="_blank"><font color="#4455aa">这一篇</font></a>）。 </p>
		<p>
				<br />可以先了解下一期文章的主题 XMLHttpRequest 对象，请阅读 <a class="contentlink" href="http://www.jibbering.com/2002/4/httprequest.html" target="_blank"><font color="#4455aa">关于 XMLHttpRequest 对象的这篇文章</font></a>。 </p>
		<p>
				<br />如果使用 Internet Explorer，可以访问 <a class="contentlink" href="http://msdn.microsoft.com/xml/" target="_blank"><font color="#4455aa">Microsoft Developer Network 的 XML Developer Center</font></a>。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax1/" target="_blank">
						<font color="#4455aa">面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序</font>
				</a>（developerWorks，2005 年 9 月）介绍了这种革新方法，它解决了页面重新加载难题，可以创建动态的 Web 应用程序体验。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www-128.ibm.com/developerworks/cn/java/j-ajax2/" target="_blank">
						<font color="#4455aa">面向 Java 开发人员的 Ajax: Ajax 的 Java 对象序列化</font>
				</a>（developerWorks，2005 年 10 月）介绍了在 Ajax 应用程序中对数据进行序列化的五种方法。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www-128.ibm.com/developerworks/edu/os-dw-os-phpajax-i.html" target="_blank">
						<font color="#4455aa">Using Ajax with PHP and Sajax</font>
				</a>（developerWorks，2005 年 10 月），这篇教程针对那些对开发丰富 Web 应用程序感兴趣的人，介绍了使用 Ajax 和 PHP 动态更新内容。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www-128.ibm.com/developerworks/webservices/library/ws-wsajax/" target="_blank">
						<font color="#4455aa">Call SOAP Web services with AJAX, Part 1: Build the Web services client</font>
				</a>（developerWorks，2005 年 10 月）介绍了如何使用 Ajax 设计模式实现基于 Web 浏览器的 SOAP Web 服务客户机。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www.ibm.com/developerworks/cn/xml/x-matters41.html" target="_blank">
						<font color="#4455aa">XML 问题: 超越 DOM</font>
				</a>（developerWorks，2005 年 5 月）详细阐述了如何使用文档对象模型来构建动态 Web 应用程序。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www.ibm.com/developerworks/edu/wa-dw-wa-ajax-i.html" target="_blank">
						<font color="#4455aa">Build apps with Asynchronous <i>javascript</i> with XML, or AJAX</font>
				</a>（developerWorks，2005 年 11 月）演示了如何使用 Ajax 构造支持实时检验的 Web 应用程序。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www.ibm.com/developerworks/cn/java/j-ajax3/" target="_blank">
						<font color="#4455aa">面向 Java 开发人员的 Ajax: 结合 Direct Web Remoting 使用 Ajax </font>
				</a>（developerWorks，2005 年 11 月）演示了如何实现 Ajax 的繁琐细节的自动化处理。 </p>
		<p>
				<br />OSA Foundation 有一个 wiki <a class="contentlink" href="http://wiki.osafoundation.org/bin/view/Projects/AjaxLibraries" target="_blank"><font color="#4455aa">调查了 AJAX/<i>javascript</i> 库</font></a>。 </p>
		<p>
				<br />XUL Planet 的 <a class="contentlink" href="http://www.xulplanet.com/references/objref/XMLHttpRequest.html" target="_blank"><font color="#4455aa">对象参考部分</font></a> 详细介绍了 XMLHttpRequest 对象（更不用说其他各种 XML 对象了，如 DOM、CSS、HTML、Web Service 以及 Windows 和 Navigation 对象）。 </p>
		<p>
				<br />关于 AJax 的基本原理，请阅读 <a class="contentlink" href="http://www.backbase.com/download/Whitepaper%20Backbase%20AJAX%20and%20Beyond.pdf" target="_blank"><font color="#4455aa">策略白皮书</font></a>。 </p>
		<p>
				<br />请看看 <a class="contentlink" href="http://www.flickr.com/" target="_blank"><font color="#4455aa">Flickr.com</font></a> 上展示的一些很棒的 Ajax 应用程序。 </p>
		<p>
				<br />Google 的 <a class="contentlink" href="http://gmail.google.com/" target="_blank"><font color="#4455aa">GMail</font></a> 是另一个利用 Ajax 的革命性 Web 应用程序的例子。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www.oreilly.com/catalog/headra/index.html" target="_blank">
						<font color="#4455aa">Head Rush Ajax</font>
				</a> （O'Reilly Media, Inc.，2006 年 2 月）包含了本文以及本系列文章所述的内容（还有更多），并采用了创新的获奖格式 Head First。 </p>
		<p>
				<br />
				<a class="contentlink" href="http://www.oreilly.com/catalog/jscript4/index.html" target="_blank">
						<font color="#4455aa">
								<i>javascript</i>: The Definitive Guide</font>
				</a>，第 4 版（O'Reilly Media, Inc.，2001 年 11 月）是关于 <i>javascript</i> 语言和使用动态网页的好资料。 </p>
		<p>
				<br />developerWorks <a class="contentlink" href="http://www.ibm.com/developerworks/web/" target="_blank"><font color="#4455aa">Web 体系结构专区</font></a> 专门发表关于各种基于 Web 的解决方案的文章。 <br /></p>
<img src ="http://www.blogjava.net/Vencent/aggbug/35960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Vencent/" target="_blank"><font color='GREEN'>Vincent Chen</font></a> 2006-03-18 18:57 <a href="http://www.blogjava.net/Vencent/articles/35960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>