首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 操作系统-> Linux教程
XML应用-利用XML 与XSL-.NET教程,XML应用
作者:网友供稿 点击:398
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
本文将介绍利用xml与xsl技术内容与表示相分离的特点,创建一个易于扩充,结构灵活的用户手册文档。当然,本文的重点在于阐述一种利用xml的方法,并不仅限于用户手册文档,您可以利用在任何您认为需要的地方。

本文介绍的内容基于xml、xsl与dtd技术规范,您可以使用ie5.0及其以上版本进行测试。

用户的需求
从用户的视角,我们要实现的用户手册包含以下几个部分:

在页面左侧的导航栏,利用树状显示每一个级别的标题,每个标题前按顺序标有标题序号,形如2.1或2.1.8,对于包含子标题的标题要与不包含子标题的标题,即叶子标题区分显示,前面用不同的图片区分。
页面右侧是内容栏,除包含各级标题外,还包含各级标题下的具体内容,内容类型有文字和图片。不同级别的标题要使用不同的现实方式,每个标题前也加有标题序号,与左侧导航栏一致。
对于含有图片的内容部分,图片显示为缩略图,通过点击可以在正常大小与缩略图之间切换。
点击左侧导航栏的标题,可以定位到右侧的相关内容。
对于手册的标题和内容,应该可以方便添加与删除,修改了一个标题的级别,比如从一级标题换到三级标题的位置,其显示风格可以自动更改。理论上,标题的级别可能会有无限多层。
无论是左侧的导航栏,还是右侧的内容区域,用户只对标题的相对位置和级别负责,标题前面的序号要求自动生成。
对应的技术实现
我们打算开发如下几个部分来实现这个用户手册:

一个dtd定义文件,即document type defination(文档类型定义)。定义这个文件需要根据客户对于手册的需求来做,这也是我们需要首先着手去做的部分。
一个xml文档,包含了用户手册的真实的、具体的内容,这个文档当然应该是良构的,需要遵循我们在上面dtd文件中定义的规则。这个文档的内容由手册的编写者来提供,他无需了解其他的技术细节,只需遵照一个简单的规则即可,如果能够使用像xmlspy这样的工具编辑会更省力。
两个xsl文件,这是我们需要开发的主体部分,也就是决定内容将如何呈现给用户,共有两个xsl文件,分别针对左侧的导航栏和右侧的内容主体。
一个超文本文件,构成用户手册的框架,实现导航栏与内容主体的分割。
定义dtd
通过前面的需求陈述,可以抽象出如下页面元素:

标题,会有不同的级别
内容,包括文本和图片
为此我们定义如下dtd元素:

<!element image (#pcdata)>
<!element para (#pcdata)>
<!element name (#pcdata)>
分别表示图片、段落文本和标题。为了表示标题的嵌套关系,我们又定义一个item元素,把它作为一个块,不同的item之间可以是平行关系,也可以是嵌套关系,所有的基本元素(图片、段落文本和标题)必须从属于一个item。具体的关系描述如下:

一个item中只能包含、并且必须包含一个标题(name)
一个item中可以同时包含多段文字或者多张图片,或者只包含其中一种
一个item中可以嵌套一个或多个item,也可以不嵌套任何item,嵌套的item具有相同的属性
通过以上描述,我们可以定义元素item:

<!element item (name, (para | image)*, item*)>
元素名称后面的* 代表此元素可以为0个或者多个。

(para | image)* 与 para*, image* 同义。

作为dtd,还必须定义一个根元素,我们起名为pms_help,它将包含item元素,进而间接的包含了所有的元素。

<!element pms_help (item*)>
上面表示为,使用了这个dtd的xml文档中可以定义0个或者多个item元素。

此外,我们还需要为图片的缩略图定义:

<!attlist image small id #implied>
至此,dtd文件我们就已经定义完了,我们将其保存为pms_help.dtd,这里下载完整的dtd文件。

如何准备手册内容
接下来我们要根据上面定义的dtd文件,整理含有实际内容的xml文件,文件内容示例如下:

<pms_help>
<item>
<name>第一级别标题</name>
<item>

<name>第二级别标题</name>
<item>
<name>第三级别标题</name>
<para>段落文本1</para>

<image small="image1_small.gif">image1.gif</image>
<para>段落文本2</para>
<para>段落文本3</para>
</item>

<item>
...
</item>
</item>
<item>
...
</item>

</item>
<item>
...
</item>
</pms_help>
在第三级标题下面,当然还可以继续嵌套item元素,有更多级别的标题,只要你在下面的xsl样式文件中对应说明了这个级别标题如何显示即可。

在para标记之间的文本在显示时会被格式化为一个段落,如果你有多段文本,应该分别用para进行标记。

image标记中有一个属性字段small,其值应是一个图片文件名,这个图片用作默认的缩略图显示,当点击这个图片,会显示出image标记之间的图片文件,当然您也可以对着两个图片使用同一个文件名。图片文件的路径不需要在这里指定,路径是写在下面xsl文件中的。

当我们把包含手册内容的xml文件准备好之后,我们还需要做一个额外的工作,就是将此xml文件复制一份,两个文件分别取名为:pms_help.xml, pms_help_lf.xml,两个文件分别绑定不同的xsl样式文件,以取得不同的显示效果,除此以外,两个xml文件是完全相同的。下载两个xml文件:导航栏xml文件,内容栏xml文件

最关键的部分: 开发xsl
1. 首先实现相对简单一点的对应左侧导航栏的xsl文件。

xml文件以一定的结构描述了我们要展现的内容,而在xsl当中,决定了这些内容将以何种方式展现,实际上是xsl是将xml文档格式化为浏览器可以理解的html格式文本,在xsl中首先需要定义根级的模板,实际对应了html文档的head以及body部分,代码如下:

<xsl:template match="pms_help">

<html>
<head>
<title>index</title>
<style media="screen">
<xsl:comment><![cdata[
body {font-fimaly:宋体,arial; font-size:9pt; color:#000000;}
]]></xsl:comment>

</style>
</head>
<body>
<h2>index</h2>
<p/>

<xsl:for-each select="item">
<xsl:apply-templates select="."/>
</xsl:for-each>
</body>
</html>

</xsl:template>
 
接下来实现对应处理item部分的模板:

<xsl:variable name="allparentnode" select="ancestor::item/name"/>
<xsl:variable name="allchildnode" select="child::item/name"/>

<xsl:variable name="numofallparentnode" select="count($allparentnode) + 1"/>
<xsl:variable name="numofallchildnode" select="count($allchildnode)"/>
<!-- output the index of help begin -->

<xsl:element name="div">
<xsl:attribute name="onclick">
window.open(pms_help.xml#<xsl:number count="item" level="multiple" format="01-01-01"/>,main)
<!-- <xsl:value-of select="&quot;alert(this.id)&quot;" /> --></xsl:attribute>

<xsl:attribute name="style"><xsl:value-of select="concat(text-indent:,(($numofallparentnode - 1) * 30),;white-space: nowrap)"/></xsl:attribute>
<xsl:attribute name="id"><xsl:number count="item" level="multiple" format="01-01-01"/></xsl:attribute>

<xsl:attribute name="onmouseover"><xsl:value-of select="&quot; this.style.color=red;this.style.cursor=hand &quot;"/></xsl:attribute>
<xsl:attribute name="onmouseout"><xsl:value-of select="&quot; this.style.color=black &quot;"/></xsl:attribute>

<xsl:choose>
<xsl:when test="$numofallparentnode = 0">
<img src="images/page/minus.gif" alt="" border="0"/>

</xsl:when>
<xsl:when test="$numofallparentnode != 0 and $numofallchildnode = 0">
<img src="images/page/passage.gif" alt="" border="0"/>

</xsl:when>
<xsl:otherwise>
<img src="images/page/minus.gif" alt="" border="0"/>
</xsl:otherwise>

</xsl:choose>
<xsl:number count="item" level="multiple"/>_
<xsl:value-of select="name"/>
</xsl:element>

<!-- 如果还存在下一级item,则递归调用此模板 -->
<xsl:if test="count(item)>0">
<xsl:apply-templates select="item"/>
</xsl:if>
</xsl:template>


在上面的代码中,我们通过如下的方式定义变量:

<xsl:variable name="allparentnode" select="ancestor::item/name"/>
其中,allparentnode是我们为变量取的名字,后面使用select关键字为其赋值,ancestor关键字用于取出后面给定节点的所有父节点,item/name是我们在dtd中定义的节点名称。之后我们可以通过 $allparentnode 来引用这个变量。接下来我们使用:

<xsl:variable name="numofallparentnode"

select="count($allparentnode) + 1"/>
取出当前节点所有父节点的数量。使用以下代码能够在xsl当中实现一个类似case语句的功能,用来判断是否是叶子节点,以显示不同的图片。

<xsl:choose>
<xsl:when test="$numofallparentnode = 0">
<img src="images/page/minus.gif" alt="" border="0"/>

</xsl:when>
<xsl:when test="$numofallparentnode != 0 and $numofallchildnode = 0">
<img src="images/page/passage.gif" alt="" border="0"/>

</xsl:when>
<xsl:otherwise>
<img src="images/page/minus.gif" alt="" border="0"/>
</xsl:otherwise>

</xsl:choose>

由于我们的dtd中不限制item定义的级别,因此,我们需要递归的处理item的显示,使用如下语句:

<xsl:if test="count(item)>0">
<xsl:apply-templates select="item"/>
</xsl:if> 
我们将此xsl文件保存为pms_help_lf.xsl,下载此文件。

2. 接下来实现对应右侧具体内容展示的xsl。

同样,也需要定义head和body部分,不同的是,这里定义了更加复杂的样式单(css),并增加了一段javascript脚本:

<xsl:template match="pms_help">
<html>
<head>

<title>content</title>
<style media="screen, print">
<xsl:comment><![cdata[
body {font-fimaly:宋体,arial; font-size:9pt; color:#000000;}
.title1 {font-fimaly:宋体; font-size:17.2pt; color:#333333; font-weight:bold; margin-left:0pt; background-color:#eeeeee; white-space: nowrap}
.title2 {font-fimaly:宋体; font-size:14pt; color:#000000; font-weight:bold; margin-left:0pt; white-space: nowrap}
.title3 {font-fimaly:宋体; font-size:12pt; color:#333333; font-weight:bold; margin-left:90pt; background-color:#eeeeee; white-space: nowrap}
.title4 {font-fimaly:宋体; font-size:12pt; color:#000000; font-weight:bold; margin-left:90pt; white-space: nowrap}
.title5 {font-fimaly:宋体; font-size:10pt; color:#333333; font-weight:bold; margin-left:160pt; background-color:#eeeeee; white-space: nowrap}
.title6 {font-fimaly:宋体; font-size:10pt; color:#000000; font-weight:bold; margin-left:160pt; white-space: nowrap}
.para1 {font-fimaly:宋体; font-size:9pt; color:#333333; margin-left:90pt}
.para2 {font-fimaly:宋体; font-size:9pt; color:#333333; margin-left:90pt}
.para3 {font-fimaly:宋体; font-size:9pt; color:#333333; margin-left:90pt}
.para4 {font-fimaly:宋体; font-size:9pt; color:#333333; margin-left:90pt}
.para5 {font-fimaly:宋体; font-size:9pt; color:#333333; margin-left:160pt}
.para6 {font-fimaly:宋体; font-size:9pt; color:#333333; margin-left:160pt}
.image {cursor:hand}
]]></xsl:comment>
</style>

<script>
<xsl:comment><![cdata[
/* 当用户点击图片时,交替显示缩略图和全图 */
function swapimg(which, small, normal){
var s = "/";
//alert(which + | + small + | + normal);
//alert(which.src.substring(which.src.lastindexof(s)+1));
if (which.src.substring(which.src.lastindexof(s)+1) == small){
which.src = images/ + normal;
which.alt = ===> 缩小 <===;
}
else{
which.src = images/ + small;
which.alt = <=== 放大 ===>;
}
}
]]></xsl:comment>
</script>

</head>
<body>
<a name="top"/>
<h2>content</h2>
<p align="right">

<a href="mailto:yourname@yourdomain.com">email to us</a><xsl:text> </xsl:text><a href="javascript:print()">打印本手册</a>
</p>
<xsl:for-each select="item">

<xsl:apply-templates select="."/>
</xsl:for-each>
</body>
</html>
</xsl:template>


接下来是处理item的部分:

<xsl:template match="item">
<xsl:variable name="allparentnode" select="ancestor::item/name"/>
<xsl:variable name="allchildnode" select="child::item/name"/>

<xsl:variable name="numofallparentnode" select="count($allparentnode) + 1"/>
<xsl:variable name="numofallchildnode" select="count($allchildnode)"/>
<!-- output the content of help -->

<!-- 显示各级标题 -->
<xsl:element name="a">
<xsl:attribute name="name"><xsl:number count="item" level="multiple" format="01-01-01"/></xsl:attribute>

</xsl:element>
<xsl:element name="div">
<xsl:attribute name="class"><xsl:value-of select="concat(title, $numofallparentnode)"/></xsl:attribute>
<xsl:number count="item" level="multiple"/><xsl:text> </xsl:text>

<xsl:value-of select="name"/>
<!-- 级别为奇数的标题下加横线 -->
<xsl:if test="$numofallparentnode = 1 or ($numofallparentnode mod 2) != 0">
::<a href="#top" target="_self">top</a>

<hr size="1" noshade="noshade"/>
</xsl:if>
</xsl:element>
<p/>

<!-- 如果还存在下一级item,则递归调用此模板 -->
<xsl:if test="count(item)>0">
<xsl:apply-templates select="item"/>
</xsl:if>
<!-- 如果不存在下一级标题,显示段落和图片内容 -->

<xsl:if test="count(item)=0">
<xsl:apply-templates select="para | image"/>
</xsl:if>
</xsl:template>
 
为了以不同的样式显示不同级别的标题我们做了如下处理,根据级别的不同,选择不同的样式单(css)定义:

<xsl:attribute name="class"><xsl:value-of select="concat(title, $numofallparentnode)"/></xsl:attribute>
额外的,我们在级别为奇数的标题下画上横线:

<!-- 级别为奇数的标题下加横线 -->
<xsl:if test="$numofallparentnode = 1 or ($numofallparentnode mod 2) != 0">

::<a href="#top" target="_self">top</a>
<hr size="1" noshade="noshade"/>

</xsl:if>
 
同样的,我们也需要递归调用此模板进行处理:

  <!-- 如果还存在下一级item,则递归调用此模板 -->
<xsl:if test="count(item)>0">
<xsl:apply-templates select="item"/>

</xsl:if>
与上一个xsl不同,我们在这里还需要处理para和image标记,这些内容在导航栏是不需要显示的。我们定义了模板:

  <xsl:template match="para | image">
<xsl:variable name="allparentnode" select="ancestor::item/name"/>

<xsl:variable name="numofallparentnode" select="count($allparentnode) + 1"/>
<!-- 如果节点是para,显示段落 -->
<xsl:if test="self::para">
<xsl:element name="div">

<xsl:attribute name="class"><xsl:value-of select="concat(para, ($numofallparentnode) - 1)"/></xsl:attribute>
<p>
<xsl:value-of select="."/>
</p>

</xsl:element>
</xsl:if>

<!-- 如果节点是image,显示图片 -->
<xsl:if test="self::image">
<xsl:variable name="small" select="normalize-space(@small)"/>

<xsl:variable name="normal" select="normalize-space(.)"/>
<xsl:element name="div">
<xsl:attribute name="class"><xsl:value-of select="concat(para, ($numofallparentnode) - 1)"/></xsl:attribute>

<xsl:element name="img">
<xsl:choose>
<xsl:when test="boolean($small)">
<xsl:attribute name="src">images/<xsl:value-of select="$small"/></xsl:attribute>

<xsl:attribute name="alt">&lt;=== 放大 ===&gt;</xsl:attribute>
<xsl:attribute name="onclick"><xsl:value-of select="concat(swapimg(this, &quot;,$small,&quot;,&quot;,$normal,&quot;))"/></xsl:attribute>

</xsl:when>
<xsl:when test="not(boolean($small))">
<xsl:attribute name="src">images/<xsl:value-of select="$normal"/></xsl:attribute>
</xsl:when>

</xsl:choose>
<xsl:attribute name="class">image</xsl:attribute>
<xsl:attribute name="border">0</xsl:attribute>
</xsl:element>

<p/>
</xsl:element>
</xsl:if>
</xsl:template>
通过onclick属性,我们为图片定义了onclick事件,以处理缩略图与正常大小图片之间的转换:

  <xsl:attribute name="onclick"><xsl:value-of select="concat(swapimg(this, &quot;,$small,&quot;,&quot;,$normal,&quot;))"/></xsl:attribute>
这个xsl文件我们保存为pms_help.xsl,下载此xsl文件。

将各部分粘合起来
最后写一个html文件,定义两个框架,将两个xml文件粘合起来,点此查看此用户手册的效果。

回顾一下,此用户手册包含:

一个dtd文件,用于定义xml文档的结构。此文件在xml文件中被引用,但并不是强制性的,换句话说,你可以根本就不生成这个文件,但实际上你必须遵循一定的规则来编写xml文件以及实现你的xsl样式文件。
两个xml文件,包含了手册的实际内容。这两个文件除了链接的xsl样式文件不同外,其他完全相同。
两个xsl样式文件,在以上的两个xml文件中被引用。一个用于格式化左侧导航栏显示,一个用于格式化右侧具体内容显示。
一个超文本文件,用于粘合两个xml文件。

文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·最简单的Struts程序-JSP教程,资料/其它
·利用激光供电的光电电流互感器
·java到structs-JSP教程,Java技巧及代码
·鼠标样式,整体背景图,滚动条的效果(网页效果)-ASP教程,ASP应用
·ASP中正则表达式的应用-ASP教程,正则表达式
·XML应用-利用XML 与XSL-.NET教程,XML应用
·.net 下用javascript调用webservice-.NET教程,Web Service开发
·Asp无组件上传进度条解决方案-ASP教程,组件开发
·破译动网验证码的简单方法-.NET教程,评论及其它
·linux系统文件命令精通指南(上)
最新文章
·mashups+ajax打造全新web开发_ajax教程
·windows vista系统中写字板应用全攻略_windows vista
·adsense单价持续低迷的解读_网赚技巧
·google反作弊小组成员专访_站长访谈
·端午议话:谈网站的特色_站长心得
·浅谈我的十点论坛管理经验_站长心得
·如何针对msn的onpage进行网页优化_站长心得
·用google 搜索框黏住易变的访问者_google推广
·google关键词广告每次点击付费(ppc)术语表_google推广
·确保万无一失的google 关键词广告公式_google推广
相关主题
  • XML应用与XGen实战-JSP教程,Java与XML
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭