用XML和XSLT进行高级的Web UI设计

创建目录树 本文要求读者熟悉JScript,MSXML,XSL/XSLT,DOM。 下载例子代码 简介     XML和XSL/XSLT是当今越来越流行的一种数据处理技术。本文是系列文章的第一篇,介绍如何用XML和XSL/XSLT设计和创建目录树。后续的每一篇文章都将介绍如何用XML和XSL/XSLT设计和创建一个特定的高级Web 应用程序用户界面对象。 本文创建的目录树层次可以是无限制的。其建立机制是通过特定的XSL风格页将定义好的目录树XML文件转换成满足要求的HTML推送给客户端浏览器(IE5.5+)显示。客户端负责处理所有对目录的操作,如展开/收缩、最大化/最小化子目录和整个目录结点。 目录树结构介绍   与建立大多数Web页面对象一样,用XML/XSLT创建目录树的方法有很多,关键是确定目录树的结构,如图一是本文创建的一个目录树例子: 图一 嵌套的目录树结构     目录树中使用线条主要是为了有一个较好的可视化效果。但反过来会影响性能。有100个项的树大概要用300个图像来显示实体间的关系。尽管可以使用缓冲和预先加载,但在DOM中仍然犹如单个对象。不使用线条,而用简单的缩进可以说明父子之间的关系。本文中拟使用不带线条的树结构。 描述目录树结构的XML 文件     目录树的结构根据需要可以是多种多样的。XML为我们提供了无数的可能性来描述树型目录界面的结构。你所选择的格式直接影响XSL风格页的行为和客户的操作。本文所选则的目录树格式比较适用于XSL进行递归处理,它能很好地满足和实现无限深度的目录树的需要。     本文范例构造的XML文档包含一个根元素"tree",这个根元素下只有一个元素"entity"。可以把它看成是目录树的一个节点,整个树的结构是通过在每一层的entity元素的"contents"子元素中嵌套的entity元素来实现的。下面是"entity"元素中包含的关键所有元素或属性的清单。
名称类型描述
id属性目录节点元素(entity)的id号,唯一标示一个节点
description元素显示给用户的文本,目录节点元素的描述
onClick元素客户端触发onClick事件的函数名
image元素当目录节点被关闭或出于非选中状态时要显示的图像
imageOpen元素当目录节点打开时显示的图像
contents元素包含目录节点元素,其内容用以确定目录节点元素是否有子元素

    在这个树结构中,用entity元素来添加与每一个树节点有关的特定数据。这些特定的数据可以是entity所表示的数据库记录的ID。在后续文章中,我们还将探讨如何创建目录节点的上下文菜单。我们将添加另外一个元素"oncontextmenu"到entity元素中。     下面的XML是本文所使用的目录树结构XML文件。这是一个静态的XML文件,在实际使用中,它可能是一个从数据库记录查询中产生出来的XML文件。

<?xml version="1.0" encoding="gb2312"?>
<tree>
  <entity id="e1">
    <description>在线杂志</description>
    <image>images/book.gif</image>
    <imageOpen>images/bookOpen.gif</imageOpen>
    <contents>
      <entity id="e2">
        <description>第十二期</description>
        <image>images/book.gif</image>
        <imageOpen>images/bookOpen.gif</imageOpen>
        <onClick></onClick>
        <contents>
          <entity id="e3">
            <description>组件对象模型</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents>
              <entity id="e4">
                <description>OLE 编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
              <entity id="e5">
                <description>ATL编程</description>
                <image>images/book.gif</image>
                <imageOpen>images/bookOpen.gif</imageOpen>
                <onClick></onClick>
	          <contents>
	            <entity id="e51">
	              <description>OLE 编程</description>
	              <image>images/paper.gif</image>
	              <imageOpen>images/paper.gif</imageOpen>
	              <onClick></onClick>
	              <contents/>
	            </entity>
	            <entity id="e52">
	              <description>ATL编程</description>
	              <image>images/paper.gif</image>
	              <imageOpen>images/paper.gif</imageOpen>
	              <onClick></onClick>
	              <contents/>
	            </entity>
	          </contents>
              </entity>
            </contents>
          </entity>
          <entity id="e3">
            <description>dotNet框架</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents>
              <entity id="e4">
                <description>C# 编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
              <entity id="e5">
                <description>数据库编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
            </contents>
          </entity>
        </contents>
      </entity>
      <entity id="e2">
        <description>第十三期</description>
        <image>images/book.gif</image>
        <imageOpen>images/bookOpen.gif</imageOpen>
        <onClick></onClick>
        <contents>
          <entity id="e3">
            <description>组件对象模型</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents>
              <entity id="e4">
                <description>OLE 编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick>www.vckbase.com/index.html</onClick>
                <contents/>
              </entity>
              <entity id="e5">
                <description>ATL编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick>www.vckbase.com/index.html</onClick>
                <contents/>
              </entity>
            </contents>
          </entity>
          <entity id="e3">
            <description>dotNet框架</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents>
              <entity id="e4">
                <description>C# 编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
              <entity id="e5">
                <description>数据库编程</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
            </contents>
          </entity>
        </contents>
      </entity>
    </contents>
  </entity>
</tree>
		
上面这个XML文件名为tree.xml,包含在可下载的例子代码中。下面我们来讨论如何在客户端浏览器中显示这个目录结构。 XSLT 式样文件    图一就是用式样文件XSLT转换XML的结果,其代码全文如下,它是应用到目录树XML文档的标准XSL风格页:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" language="JavaScript">
<xsl:template match="tree">
  <xsl:apply-templates select="entity"/>
</xsl:template>

<xsl:template match="entity">
  <div οnclick="window.event.cancelBubble = true;clickOnEntity(this);" onselectstart="return false" οndragstart="return false">
  <xsl:attribute name="image"><xsl:value-of select="image"/></xsl:attribute>
  <xsl:attribute name="imageOpen"><xsl:value-of select="imageOpen"/></xsl:attribute>
  <xsl:attribute name="open">false</xsl:attribute>
  <xsl:attribute name="id">f<xsl:value-of select="@id"/></xsl:attribute>
  <xsl:attribute name="open">false</xsl:attribute>
  <xsl:attribute name="STYLE">
    padding-left: 20px;
    cursor: hand;
    <xsl:if expr="depth(this) > 2">
      display: none;
    </xsl:if>
  </xsl:attribute>
    <table border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td valign="middle">
          <img border="0" id="image">
            <xsl:attribute name="SRC">
              <xsl:value-of select="image"/>
            </xsl:attribute>
          </img>
        </td>
        <td valign="middle" nowrap="true">
        <xsl:attribute name="STYLE">
          padding-left: 7px;
          font-family: Verdana;
          font-size: 11px;
          font-color: black;
        </xsl:attribute>
        <xsl:value-of select="description"/></td>
      </tr>
    </table>
  <xsl:apply-templates select="contents/entity"/>
  </div>
</xsl:template>

</xsl:stylesheet>
      
客户端操作     为了让目录树按照我们自己的意图运行,还需要在客户端做一些工作:例如初始化、实现展开、收缩目录节点等功能……。归纳起来就是下面这些脚本函数: Initialize 初始化 Expand 展开单个节点 Collapse 收缩单个节点 Expand All (Maximize) 展开所有节点 Collapse All (Minimize) 收缩所有节点 下面是以上五个客户端操作的详细脚本代码。它们都放在文件tree.js中。
function initialize() {
  var xmlDoc
  var xslDoc

  xmlDoc = new ActiveXObject(''''Microsoft.XMLDOM'''')
  xmlDoc.async = false;

  xslDoc = new ActiveXObject(''''Microsoft.XMLDOM'''')
  xslDoc.async = false;

  xmlDoc.load("tree/tree.xml")
  xslDoc.load("tree/tree.xsl")

  folderTree.innerHTML = xmlDoc.documentElement.transformNode(xslDoc)
}

function clickOnEntity(entity) {
  if(entity.open == "false") {
    expand(entity, true)
  }
  else {
    collapse(entity)
  }
  window.event.cancelBubble = true
}

function expand(entity) {
  var oImage

  oImage = entity.childNodes(0).all["image"]
  oImage.src = entity.imageOpen
  for(i=0; i < entity.childNodes.length; i++) {
    if(entity.childNodes(i).tagName == "DIV") {
      entity.childNodes(i).style.display = "block"
    }
  }
  entity.open = "true"
}

function collapse(entity) {
  var oImage
  var i

  oImage = entity.childNodes(0).all["image"]
  oImage.src = entity.image

  // 收缩和隐藏字节点
  for(i=0; i < entity.childNodes.length; i++) {
      if(entity.childNodes(i).tagName == "DIV") {
        if(entity.id != "folderTree") entity.childNodes(i).style.display = "none"
        collapse(entity.childNodes(i))
      }
    }
  entity.open = "false"
}

function expandAll(entity) {
  var oImage
  var i

  expand(entity, false)

  // 展开子节点
  for(i=0; i < entity.childNodes.length; i++) {
    if(entity.childNodes(i).tagName == "DIV") {
      expandAll(entity.childNodes(i))
    }
  }
}      
      
    随着Web技术的进步,维护Web应用程序的状态逐渐成为可能。更多的处理和操作将从服务器端移到客户端进行,从而减轻服务器的工作负担,使得我们的程序界面越来越复杂,同时,应用程序的可用性和性能也需要不断的改进。     希望本文能抛砖引玉,共同探讨目前比较时髦的XML/XSL技术,利用它们来提高Web应用程序界面的质量。我们将在下一篇文章中继续我们的主题,讨论如何在目录树中创建上下文菜单。(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值