XML(可扩展标记语言)看起来可能像某种W3C标准??现在没有什么实际影响
![](/icons/23330dou.gif)
即使以后能派上用场
![](/icons/23330dou.gif)
也是很久以后
![](/icons/23330de.gif)
事
![](/icons/23330dou2.gif)
但实际上
![](/icons/23330dou.gif)
它现在已经得到了应用
![](/icons/23330dou2.gif)
所以
![](/icons/23330dou.gif)
不要等到XML已被加进了你最喜爱
![](/icons/23330de.gif)
HTML编辑器中才开始使用它
![](/icons/23330dou2.gif)
它现在就可以解决各种内部问题和B2B系统问题
在Sparks.com
![](/icons/23330dou.gif)
我们使用XML来标准化从Java对象到HTML数据显示等区别系统的间
![](/icons/23330de.gif)
数据表示
特别需要指出
![](/icons/23330de.gif)
是
![](/icons/23330dou.gif)
我们发现
![](/icons/23330dou.gif)
只要以非常基本
![](/icons/23330de.gif)
XML结构来实现标准化
![](/icons/23330dou.gif)
就可以更容易地共享和操作数据
![](/icons/23330dou2.gif)
在这
![](/icons/23330yi.gif)
过程中
![](/icons/23330dou.gif)
我们发现了使用XML
![](/icons/23330de.gif)
很多有效思路方法
![](/icons/23330dou2.gif)
下面详细介绍我们现在
![](/icons/23330de.gif)
应用情况
标准化
在使用XML的前
![](/icons/23330dou.gif)
建立和你要使用
![](/icons/23330de.gif)
信息区别
![](/icons/23330de.gif)
XML数据格式
生成动态XML
从数据库中生成HTML并不新鲜
![](/icons/23330dou.gif)
但生成XML却很新鲜
![](/icons/23330dou2.gif)
这里我们介绍具体
![](/icons/23330de.gif)
生成步骤
用XSL作为模板语言
XSL(可扩展样式表语言)是定义XML数据显示格式
![](/icons/23330de.gif)
好思路方法
![](/icons/23330dou.gif)
如果写成几个静态模板会更有效
生成HTML
XML加上XSL就等于HTML
![](/icons/23330dou2.gif)
这听起来似乎不对
![](/icons/23330dou.gif)
但用户所见
![](/icons/23330de.gif)
我们
![](/icons/23330de.gif)
HTML页面其实就是XML和XSL共同产生
![](/icons/23330de.gif)
效果
![](/icons/23330yi.gif)
、标准化
XML
![](/icons/23330de.gif)
能力来自于它
![](/icons/23330de.gif)
灵活性
![](/icons/23330dou2.gif)
但不幸
![](/icons/23330de.gif)
是
![](/icons/23330dou.gif)
它有时太灵活了
![](/icons/23330dou.gif)
以至于你会面对
![](/icons/23330yi.gif)
个空白
![](/icons/23330de.gif)
页面
![](/icons/23330dou.gif)
发愁该如何解决问题
在任何XML
![](/icons/23330de.gif)
项目中
![](/icons/23330dou.gif)
第
![](/icons/23330yi.gif)
步工作都是创建标准
![](/icons/23330de.gif)
数据格式
![](/icons/23330dou2.gif)
为此你要作出以下决定:
&&&
确定数据:
![](/icons/23330yinwei.gif)
没有标准
![](/icons/23330de.gif)
XML格式
![](/icons/23330dou.gif)
开发者可以自由地开发自己
![](/icons/23330de.gif)
格式
![](/icons/23330dou2.gif)
然而
![](/icons/23330dou.gif)
如果你
![](/icons/23330de.gif)
格式只能被
![](/icons/23330yi.gif)
个应用
![](/icons/23330chengxu.gif)
识别
![](/icons/23330dou.gif)
那么你只能运行这个
![](/icons/23330chengxu.gif)
来使用该格式
![](/icons/23330dou2.gif)
如果还有其他
![](/icons/23330chengxu.gif)
也能读懂你
![](/icons/23330de.gif)
XML格式
![](/icons/23330dou.gif)
那显然会更有帮助
![](/icons/23330dou2.gif)
如果某个XML格式被修
改
![](/icons/23330dou.gif)
则使用它
![](/icons/23330de.gif)
系统可能也需要被修改
![](/icons/23330dou.gif)
所以你应该建立尽可能完整
![](/icons/23330de.gif)
格式
![](/icons/23330dou2.gif)
![](/icons/23330yinwei.gif)
大多数系统忽略它们无法识别
![](/icons/23330de.gif)
标签
![](/icons/23330dou.gif)
所以改变
![](/icons/23330yi.gif)
个XML格式
![](/icons/23330de.gif)
最安全
![](/icons/23330de.gif)
思路方法是添加标签
![](/icons/23330dou.gif)
而不是修改标签
单击此处查看XML数据格式例子
在Sparks.com
![](/icons/23330dou.gif)
我们查看了区别
![](/icons/23330de.gif)
产品展示需要
![](/icons/23330de.gif)
所有产品数据
![](/icons/23330dou2.gif)
尽管并不是所有
![](/icons/23330de.gif)
页面都使用全部数据
![](/icons/23330dou.gif)
但我们还是由此开发出适用于所有数据
![](/icons/23330de.gif)
非常完整
![](/icons/23330de.gif)
XML数据格式
![](/icons/23330dou2.gif)
例如
![](/icons/23330dou.gif)
我们
![](/icons/23330de.gif)
产品明细信息页面显示
![](/icons/23330de.gif)
数据要比产品浏览页面多
![](/icons/23330dou2.gif)
然而
![](/icons/23330dou.gif)
我们在这两种情况下仍然使用相同
![](/icons/23330de.gif)
数据格式
![](/icons/23330dou.gif)
![](/icons/23330yinwei.gif)
每个页面
![](/icons/23330de.gif)
XSL模板都只使用它所需要
![](/icons/23330de.gif)
字段
是否使用DTD
在Sparks.com
![](/icons/23330dou.gif)
我们使用组织良好
![](/icons/23330de.gif)
XML
![](/icons/23330dou.gif)
而不使用仅仅是正确
![](/icons/23330de.gif)
XML
![](/icons/23330dou.gif)
![](/icons/23330yinwei.gif)
前者不需要DTD
![](/icons/23330dou2.gif)
DTD在用户点击和看到页面的间加入了
![](/icons/23330yi.gif)
个处理层
![](/icons/23330dou2.gif)
我们发现这
![](/icons/23330yi.gif)
层需要太多
![](/icons/23330de.gif)
处理
![](/icons/23330dou2.gif)
当然
![](/icons/23330dou.gif)
在以XML格式和其他公司通信时
![](/icons/23330dou.gif)
使用DTD还是很不错
![](/icons/23330de.gif)
![](/icons/23330dou2.gif)
![](/icons/23330yinwei.gif)
DTD能在发送和接受时能保证数据结构正确
选择解析引擎
现在
![](/icons/23330dou.gif)
可以使用
![](/icons/23330de.gif)
解析引擎有好几个
![](/icons/23330dou2.gif)
选择哪
![](/icons/23330yi.gif)
个几乎完全取决于你
![](/icons/23330de.gif)
应用需要
![](/icons/23330dou2.gif)
如果你决定使用DTD
![](/icons/23330dou.gif)
那么这个解析引擎必须能使你
![](/icons/23330de.gif)
XML被DTD验证
![](/icons/23330dou2.gif)
你可以将验证另放到
![](/icons/23330yi.gif)
个进程中
![](/icons/23330dou.gif)
但那样会影响性能
SAX和DOM是两个基本
![](/icons/23330de.gif)
解析模型
![](/icons/23330dou2.gif)
SAX基于事件
![](/icons/23330dou.gif)
所以在XML被解析时
![](/icons/23330dou.gif)
事件被发送给引擎
![](/icons/23330dou2.gif)
接下来
![](/icons/23330dou.gif)
事件和输出文件同步
![](/icons/23330dou2.gif)
DOM解析引擎为动态XML数据和XSL样式表建立层次树状结构
![](/icons/23330dou2.gif)
通过随机访问DOM树
![](/icons/23330dou.gif)
可以提供XML数据
![](/icons/23330dou.gif)
就象由XSL样式表来决定
![](/icons/23330yi.gif)
样
![](/icons/23330dou2.gif)
SAX模型上
![](/icons/23330de.gif)
争论主要集中于对DOM结构
![](/icons/23330de.gif)
内存降低过度和加快XSL样式表解析时间缩短方面
然而
![](/icons/23330dou.gif)
我们发现使用SAX
![](/icons/23330de.gif)
很多系统并没有充分发挥它
![](/icons/23330de.gif)
能力
![](/icons/23330dou2.gif)
这些系统用它来建立DOM结构并通过DOM结构来发送事件
![](/icons/23330dou2.gif)
用这种思路方法
![](/icons/23330dou.gif)
在任何XML处理的前必须从样式表中建立DOM
![](/icons/23330dou.gif)
所以性能会下降
2、生成动态XML
![](/icons/23330yi.gif)
旦建立了XML格式
![](/icons/23330dou.gif)
我们需要
![](/icons/23330yi.gif)
种能够将其从数据库中动态移植
![](/icons/23330de.gif)
思路方法
生成XML文档相对来说比较简单
![](/icons/23330dou.gif)
![](/icons/23330yinwei.gif)
它只需要
![](/icons/23330yi.gif)
个可以处理
![](/icons/23330zifu.gif)
串
![](/icons/23330de.gif)
系统
![](/icons/23330dou2.gif)
我们建立了
![](/icons/23330yi.gif)
个使用Java Servlet、Enterprise JavaBean server、JDBC和RDBMS(关系型数据库管理系统)
![](/icons/23330de.gif)
系统
&&&&
(有关XSL应用
![](/icons/23330de.gif)
其他信息
![](/icons/23330dou.gif)
请参阅用XSL作为模板语言
![](/icons/23330dou2.gif)
)
生成XML
![](/icons/23330de.gif)
例子
在Java中创建XML文档
![](/icons/23330zifu.gif)
串
![](/icons/23330de.gif)
真正代码可以分成几个思路方法和类
启动XML生成过程
![](/icons/23330de.gif)
代码放在EJB思路方法里
![](/icons/23330dou2.gif)
这
![](/icons/23330yi.gif)
例子会立即创建
![](/icons/23330yi.gif)
个StringBuffer
![](/icons/23330dou.gif)
以便存储生成
![](/icons/23330de.gif)
XML
![](/icons/23330zifu.gif)
串
StringBuffer xml =
![](/icons/23330new.gif)
StringBuffer
![](/icons/23330kh.gif)
;
xml.append(XmlUtils.beginDocument("/browse_find/browse.xsl", "browse", request));
xml.append(product.toXml
![](/icons/23330kh.gif)
);
xml.append(XmlUtils.endDocument("browse");
out.pr
![](/icons/23330int.gif)
(xml.toString
![](/icons/23330kh.gif)
);
后面
![](/icons/23330de.gif)
3个xml.append
![](/icons/23330kh.gif)
变元本身就是对其他思路方法
![](/icons/23330de.gif)
![](/icons/23330diaoyong.gif)
产生文件头
第
![](/icons/23330yi.gif)
个附加思路方法
![](/icons/23330diaoyong.gif)
XmlUtils类来产生XML文件头
![](/icons/23330dou2.gif)
我们
![](/icons/23330de.gif)
Java Servlet中
![](/icons/23330de.gif)
代码如下:
public
![](/icons/23330static.gif)
String beginDocument(String stylesheet, String page)
{
StringBuffer xml =
![](/icons/23330new.gif)
StringBuffer
![](/icons/23330kh.gif)
;
xml.append("<?xml version="1.0"?> ")
.append("<?xml-stylesheet href="")
.append(stylesheet).append(""")
.append(" type ="text/xsl"?> ");
xml.append("<").append(page).append("> ");
![](/icons/23330return.gif)
xml.toString
![](/icons/23330kh.gif)
;
}
这段代码生成了XML文件头
![](/icons/23330dou2.gif)
<?xml>标签把本文件定义为支持1.0版本
![](/icons/23330de.gif)
XML文件
![](/icons/23330dou2.gif)
第 2行代码指向用以显示数据
![](/icons/23330de.gif)
正确样式表
![](/icons/23330de.gif)
位置
![](/icons/23330dou2.gif)
最后包括进去
![](/icons/23330de.gif)
是项级标签(本例子中为<browse>)
![](/icons/23330dou2.gif)
在文件末尾
![](/icons/23330dou.gif)
只有<browse>标签需要被关闭
<?xml version="1.0"?> <?xml-stylesheet href="/browse_find/browse.xsl" type="text/xsl"?> <browse>
填入产品信息
完成了文件头后
![](/icons/23330dou.gif)
控制思路方法会
![](/icons/23330diaoyong.gif)
Java对象来产生它
![](/icons/23330de.gif)
XML
![](/icons/23330dou2.gif)
本例中
![](/icons/23330diaoyong.gif)
![](/icons/23330de.gif)
是product对象
![](/icons/23330dou2.gif)
product对象使用两个思路方法来产生它
![](/icons/23330de.gif)
XML表示
![](/icons/23330dou2.gif)
第
![](/icons/23330yi.gif)
个思路方法toXML
![](/icons/23330kh.gif)
通过产生<product>和</product>标签来建立product节点
![](/icons/23330dou2.gif)
然后它会
![](/icons/23330diaoyong.gif)
![](/icons/23330int.gif)
ernalXML
![](/icons/23330kh.gif)
![](/icons/23330dou.gif)
这样就能提供产品XML所需
![](/icons/23330de.gif)
内容
![](/icons/23330dou2.gif)
![](/icons/23330int.gif)
ernalXML
![](/icons/23330kh.gif)
是
![](/icons/23330yi.gif)
系列
![](/icons/23330de.gif)
StringBuffer.append
![](/icons/23330kh.gif)
![](/icons/23330diaoyong.gif)
![](/icons/23330dou2.gif)
StringBuffer也被转换成
![](/icons/23330zifu.gif)
串并返回给控制思路方法
public String toXml
{
StringBuffer xml =
![](/icons/23330new.gif)
StringBuffer("<product> ");
xml.append(
![](/icons/23330int.gif)
ernalXml
![](/icons/23330kh.gif)
);
xml.append("</product> ");
![](/icons/23330return.gif)
xml.toString
![](/icons/23330kh.gif)
;
}
public String
![](/icons/23330int.gif)
ernalXml
{
StringBuffer xml =
StringBuffer(" ")
.append(productType).append(" ");
xml.append(" ").append(idValue.trim
![](/icons/23330kh.gif)
)
.append(" ");
xml.append(" ").append(idName.trim
![](/icons/23330kh.gif)
)
.append(" ");
xml.append(" ").append(page.trim
![](/icons/23330kh.gif)
)
.append(" ");
??
xml.append(" ").append(amount).append(" ");
xml.append(" ").append(vendor).append(" ");
xml.append(" ");
xml.append(" ").append(pubDesc).append(" ");
xml.append(" ").append(venDesc).append(" ";
??
![](/icons/23330return.gif)
xml.toString
![](/icons/23330kh.gif)
;
}
关闭文件
最后
![](/icons/23330dou.gif)
XMLUtils.endDocument
![](/icons/23330kh.gif)
思路方法被
![](/icons/23330diaoyong.gif)
![](/icons/23330dou2.gif)
这个
![](/icons/23330diaoyong.gif)
关闭XML标签(本例中为)
![](/icons/23330dou.gif)
并最终完成架构好
![](/icons/23330de.gif)
XML文件
![](/icons/23330dou2.gif)
来自控制思路方法
![](/icons/23330de.gif)
整个StringBuffer也转换成
![](/icons/23330zifu.gif)
串
![](/icons/23330dou.gif)
并返回给处理最初HTTP请求
![](/icons/23330de.gif)
servlet
3、用XSL作为模板语言
为了得到HTML输出
![](/icons/23330dou.gif)
我们把生成
![](/icons/23330de.gif)
XML文件和控制XML数据如何表示
![](/icons/23330de.gif)
XSL模板相结合
![](/icons/23330dou2.gif)
我们
![](/icons/23330de.gif)
XSL模板由精心组织
![](/icons/23330de.gif)
XSL和HTML标签组成
开始建模板
我们
![](/icons/23330de.gif)
XSL模板开始部分和下面这段代码类似
![](/icons/23330dou2.gif)
第
![](/icons/23330yi.gif)
行代码为必需代码
![](/icons/23330dou.gif)
将本文件定义为XSL样式表
![](/icons/23330dou2.gif)
xmlns:xsl=属性引用本文件所使用
![](/icons/23330de.gif)
XML名称空间
![](/icons/23330dou.gif)
而version=属性则定义名称空间
![](/icons/23330de.gif)
版本号
![](/icons/23330dou2.gif)
在文件
![](/icons/23330de.gif)
末尾
![](/icons/23330dou.gif)
我们关闭标签
由<xsl:template>开始
![](/icons/23330de.gif)
第 2行代码确定了XSL模板
![](/icons/23330de.gif)
模式
![](/icons/23330dou2.gif)
Match属性是必需
![](/icons/23330de.gif)
![](/icons/23330dou.gif)
在这里指向XML标签<basketPage>
![](/icons/23330dou2.gif)
在我们
![](/icons/23330de.gif)
系统里
![](/icons/23330dou.gif)
<basketPage>标签里包含<product> 标签
![](/icons/23330dou.gif)
这使得XSL模板可以访问嵌在<product>标签内
![](/icons/23330de.gif)
产品信息
![](/icons/23330dou2.gif)
我们又
![](/icons/23330yi.gif)
次必须在文件末尾关闭<xsl:template>标签
接下来
![](/icons/23330dou.gif)
我们来看
![](/icons/23330yi.gif)
看组织良好
![](/icons/23330de.gif)
HTML
![](/icons/23330dou2.gif)
由于它将被XML解析引擎处理
![](/icons/23330dou.gif)
所以必须符合组织良好
![](/icons/23330de.gif)
XML
![](/icons/23330de.gif)
所有规则
![](/icons/23330dou2.gif)
从本质上来讲
![](/icons/23330dou.gif)
这意味着所有
![](/icons/23330de.gif)
开始标签必须有对应
![](/icons/23330de.gif)
结束标签
![](/icons/23330dou2.gif)
例如
![](/icons/23330dou.gif)
通常不被结束
![](/icons/23330de.gif)
<P>标签
![](/icons/23330dou.gif)
必须用</P>关闭
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="basketPage">
<html>
<head>
<title>Shopping Bag / Adjust Quantity</title>
</head>
<body bgcolor="
</xsl:template>
</xsl:stylesheet>
在模板
![](/icons/23330de.gif)
主体内
![](/icons/23330dou.gif)
有很多XSL标签被用于为数据表示提供逻辑
![](/icons/23330dou2.gif)
下面解释两个常用
![](/icons/23330de.gif)
标签
Choose
<xsl:choose>标签类似于传统编程语言中
![](/icons/23330if.gif)
-then-
![](/icons/23330else.gif)
结构
![](/icons/23330de.gif)
开始部分
![](/icons/23330dou2.gif)
在XSL中
![](/icons/23330dou.gif)
choose标签表示在代码进入
![](/icons/23330de.gif)
部分中
![](/icons/23330dou.gif)
赋值将触发动作
![](/icons/23330de.gif)
发生
![](/icons/23330dou2.gif)
拥有赋值属性
![](/icons/23330de.gif)
<xsl:when>标签跟在choose标签后面
![](/icons/23330dou2.gif)
如果赋值是正确
![](/icons/23330de.gif)
![](/icons/23330dou.gif)
位于<xsl:when>
![](/icons/23330de.gif)
开始和结束标签的间
![](/icons/23330de.gif)
内容将被使用
![](/icons/23330dou2.gif)
如果赋值
![](/icons/23330cuowu.gif)
![](/icons/23330dou.gif)
就使用<xsl:otherwise>
![](/icons/23330de.gif)
开始和结束标签的间
![](/icons/23330de.gif)
内容
![](/icons/23330dou2.gif)
整个部分用</xsl:choose>来结束
在这个例子里
![](/icons/23330dou.gif)
when标签会为quantity标签检查XML
![](/icons/23330dou2.gif)
如果quantity标签里含有值为真
![](/icons/23330de.gif)
error属性
![](/icons/23330dou.gif)
quantity标签将会显示列在下面
![](/icons/23330de.gif)
表格单元
![](/icons/23330dou2.gif)
如果属性
![](/icons/23330de.gif)
值不为真
![](/icons/23330dou.gif)
XSL将会显示otherwise标签间
![](/icons/23330de.gif)
内容
![](/icons/23330dou2.gif)
在下面
![](/icons/23330de.gif)
例子里
![](/icons/23330dou.gif)
如果error属性不真
![](/icons/23330dou.gif)
则什么都不会被显示
<xsl:choose>
<xsl:when test="quantity[@error=\'true\']">
<td bgcolor="src=\"http://www./Files/BeyondPic/2007-6/8/076813492121510.g
![](/icons/23330if.gif)
\""/></td>
<td valign="top" bgcolor="<font face="Verdana, Arial" size="1" color="<b>*Not enough in stock. Your quantity was adjusted accordingly.</b></font>
</td>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
For-each
<xsl:for-each>标签可以用来对相似XML数据
![](/icons/23330de.gif)
多种情况应用同
![](/icons/23330yi.gif)
个样式表
![](/icons/23330dou2.gif)
对于我们来说
![](/icons/23330dou.gif)
可以从数据库中取出
![](/icons/23330yi.gif)
系列产品信息
![](/icons/23330dou.gif)
并在Web页上进行统
![](/icons/23330yi.gif)
格式化
![](/icons/23330dou2.gif)
这里有
![](/icons/23330yi.gif)
个例子:
<xsl:for-each select="package">
<xsl:apply-templates select="product"/>
</xsl:for-each>
for-each 循环在
![](/icons/23330chengxu.gif)
遇到标签时开始
![](/icons/23330dou2.gif)
这个循环将在
![](/icons/23330chengxu.gif)
遇到标签时结束
![](/icons/23330dou2.gif)
![](/icons/23330yi.gif)
旦这个循环运行
![](/icons/23330dou.gif)
每次标签出现时都会应用这个模板
4、生成HTML
将来
![](/icons/23330de.gif)
某
![](/icons/23330yi.gif)
时刻
![](/icons/23330dou.gif)
浏览器将会集成XML解析引擎
![](/icons/23330dou2.gif)
到那时
![](/icons/23330dou.gif)
你可以直接向浏览器发送XML和XSL文件
![](/icons/23330dou.gif)
而浏览器则根据样式表中列出
![](/icons/23330de.gif)
规则显示XML数据
![](/icons/23330dou2.gif)
不过
![](/icons/23330dou.gif)
在此的前开发者们将不得不在他们服务器端
![](/icons/23330de.gif)
系统里创建解析功能
在Sparks.com
![](/icons/23330dou.gif)
我们已经在Java servlet里集成了
![](/icons/23330yi.gif)
个XML解析器
![](/icons/23330dou2.gif)
这个解析器使用
![](/icons/23330yi.gif)
种称为XSLT (XSL Transformation)
![](/icons/23330de.gif)
机制
![](/icons/23330dou.gif)
按XSL标签
![](/icons/23330de.gif)
介绍说明向XSL模板中添加XML数据
当我们
![](/icons/23330de.gif)
Java servlet处理HTTP请求时
![](/icons/23330dou.gif)
servlet检索动态生成
![](/icons/23330de.gif)
XML
![](/icons/23330dou.gif)
然后XML被传给解析引擎
![](/icons/23330dou2.gif)
根据XML文件中
![](/icons/23330de.gif)
指令
![](/icons/23330dou.gif)
解析引擎查找适当
![](/icons/23330de.gif)
XSL样式表
![](/icons/23330dou2.gif)
解析器通过DOM结构创建HTML文件
![](/icons/23330dou.gif)
然后这个文件再传送给发出HTTP请求
![](/icons/23330de.gif)
用户
如果你选择使用SAX模型
![](/icons/23330dou.gif)
解析器会通读XML源
![](/icons/23330chengxu.gif)
![](/icons/23330dou.gif)
为每个XML标签创建
![](/icons/23330yi.gif)
个事件
![](/icons/23330dou2.gif)
事件和XML数据对应
![](/icons/23330dou.gif)
并最终按XSL标签向样式表中插入数据