荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Jobs (温少), 信区: Visual
标  题: "DXML":将 TOC 从 XML 带到 DHTML
发信站: BBS 荔园晨风站 (Mon Mar  6 12:14:35 2000), 转信

"DXML":将 TOC 从 XML 带到 DHTML

--------------------------------------------------------------------------------

George Young
Microsoft Corporation



我真的很喜欢那些将几种不同的技术集成在一个小应用程序中的综合示例。

在本月的 Code Corner 中,我们即将进行这样的工作,即将“可扩展的标记语言
(XML)”、“可扩展的样式表语言 (XSL)”、JScript? 以及“层叠样式表 (CSS)
”结合在一起,创建一个分层的动态 HTML(DHTML) 目录 (TOC)。既然我们已经涉
及到了这些缩写词,我们有意识地举一个简单示例 — 并且,您可能已经对各项
技术非常熟悉了。如果您已熟悉,则希望当您看见它们结合在一起使用时会发现
某些价值所在;如果您还不熟悉,也许这个例子会激起您对这些内容进一步探索
的兴趣。


对 Web 开发人员而言,通过使用带有“有意义的”标记数据元素的 XML,可实现
使信息更有携带性与弹性。由于在 Internet Explorer 5 中增强的 XSL 支持,
使得在浏览器中显示 XML 数据更加容易。


我们在 Web Workshop 中使用 XML 存储 TOC 信息已经有一段时间了,通过 XSL
样式表可以将该信息转换为 HTML。样式表还“写下”链接到一个 CSS 和
JScript 文件,因此我们一次就可将 XML 转换到 DHTML。通过修改单一的 XSL
样式表,XML 存储的数据即可轻松改变所有 TOC 的输出格式。



让我们来依次看一下这四种文件 — XML、XSL、JScript 及 CSS。

在 XML 存储 TOC
对于本示例,我们已经创建了一个与 web 开发有关的文章或“主题”的列表。每
个 TOPIC 元素都有一个说明性的 TITLE 和 URL。主题按 TOPICS 元素内的 TYPE
进行分组。注意第三个 TOPICS 元素自身包含 TOPICS 元素。webdev.xml 文件顶
端的<?xml:stylesheet type="text/xsl" href="list.xsl"?>处理指令会告诉
Internet Explorer 5 当该 XML 文件直接在浏览器中打开时,按照此样式表实施
XML。(我们将在栏目尾端讨论如何在服务器上以 ASP 实现此项操作。)

以下是 XML 数据:

列表 1:webdev.xml
<?xml version="1.0"?>
<?xml:stylesheet type="text/xsl" href="list.xsl"?>

<TOPICLIST TYPE="Web Dev References">

<TOPICS TYPE="DHTML">
  <TOPIC>
    <TITLE>Objects</TITLE>
    <URL>/workshop/author/dhtml/reference/objects.asp</URL>
  </TOPIC>
  <TOPIC>
    <TITLE>Properties</TITLE>
    <URL>/workshop/author/dhtml/reference/properties.asp</URL>
  </TOPIC>
  <TOPIC>
    <TITLE>Methods</TITLE>
    <URL>/workshop/author/dhtml/reference/methods.asp</URL>
  </TOPIC>
  <TOPIC>
    <TITLE>Events</TITLE>
    <URL>/workshop/author/dhtml/reference/events.asp</URL>
  </TOPIC>
  <TOPIC>
    <TITLE>Collections</TITLE>
    <URL>/workshop/author/dhtml/reference/collections.asp</URL>
  </TOPIC>
</TOPICS>

<TOPICS TYPE="CSS">
  <TOPIC>
    <TITLE>Attributes</TITLE>
    <URL>/workshop/author/css/reference/attributes.asp</URL>
  </TOPIC>
  <TOPIC>
    <TITLE>Length units</TITLE>
    <URL>/workshop/author/css/reference/lengthunits.asp</URL>
  </TOPIC>
  <TOPIC>
    <TITLE>Color table</TITLE>
    <URL>/workshop/author/dhtml/reference/colors/colors.asp</URL>
  </TOPIC>
</TOPICS>

<TOPICS TYPE="XML">

  <TOPICS TYPE="XML DOM">
    <TOPIC>
      <TITLE>Developer's guide</TITLE>
      <URL>/xml/XMLGuide/default.asp</URL>
    </TOPIC>
    <TOPIC>
      <TITLE>Objects</TITLE>
      <URL>/xml/reference/scriptref/XMLDOM_Objects.asp</URL>
    </TOPIC>
  </TOPICS>

  <TOPICS TYPE="XSL">
    <TOPIC>
      <TITLE>Developer's guide</TITLE>
      <URL>/xml/XSLGuide/default.asp</URL>
    </TOPIC>
    <TOPIC>
      <TITLE>Elements</TITLE>
      <URL>/xml/reference/xsl/XSLElements.asp</URL>
    </TOPIC>
    <TOPIC>
      <TITLE>Methods</TITLE>
      <URL>/xml/reference/xsl/xslmethods.asp</URL>
    </TOPIC>
    <TOPIC>
      <TITLE>Pattern syntax</TITLE>
      <URL>/xml/reference/xsl/XSLPatternSyntax.asp</URL>
    </TOPIC>
  </TOPICS>

</TOPICS>

</TOPICLIST>


使用一个 XSL 样式表将 XML 转换为 HTML
虽然我们可以在代码中直接对 XML 进行操作,但 XSL 让我们使用陈述的方法,
将 XML 转换到显示输出(在此例中为 HTML)d放入 <TITLE> 和 <H1> HTML 元素中
;我们还挂接脚本 (list.js) 和样式表 (list.css) 文件,它们将提供对 DHTML
外观和行为的处理。我们使用脚本文件中的两个函数,在顶端绘制了一些供用户
显示或隐藏所有 TOC 节点的按钮,在底端添加了另一个按钮,来查看警报框中的
HTML 源文件。

第一个块中最有趣的元素是 <xsl:apply-templates select="TOPICLIST/TOPICS"
/>。它通知处理器转换 XML 文档的所有 TOPICS 节点,这些节点是根目录
TOPICLIST 节点的子节点。如果您查看一下上面的 XML 文件,您会注意到它是由
TYPE "DHTML"、"CSS" 和 "XML" 的 TOPICS 节点组成的。在这里,XSL 处理器将
从此第一个块开始分支,并在样式表中搜索另一个 xsl:template 块,它与我们
的 select="TOPICLIST/TOPICS" 属性相匹配。正如您可能猜到的,这就是我们的
第二个块。

转换 TOPICLIST
第二个模板块 <xsl:template match="TOPICS"> 才是L 将某一属性动态添加到一个 HTML
输出元素中,我们可以使用
xsl:attribute,其 name 属性设为我们希望创建的 HTML 属性;正如:
<xsl:attribute name="HREF">。我们用服务器名称(
http://msdn.microsoft.com)以及 TOPIC URL, <xsl:value-of select="URL"
/> 植入 HREF 值。

好了,我们已经写出了顶端组中的所有链接,但我们还没有涉及 TOPICS 的子
TOPICS — 主题的嵌套列表。这是一个 XSL 真正表现出色的区域,它可以使用一
条语句处理所有的递归!关闭进入第二个块先开始处理 TOPICS 元素时打开的容
器 <UL> 及其父级 <LI> 之前, 我们要声明 <xsl:if
test="TOPICS"><xsl:apply-templates /></xsl:if>。通过使用将上下文更改为
我们正在测试的元素的 xsl:if 条件语句,我们可以探询该树是否存在一个子
TOPICS 节点。如果存在,则 <xsl:apply-templates /> 将通知处理器无论当前
上下文是什么都与之匹配。由于我们已漾成了一组嵌套的
HTML 列表。既然我们已经得到了该输出,则让我们现在来快速浏览一下使 TOC
变为动态 .js 和 .css 的代码。


使用脚本显示和隐藏列表节点
共有四个函数处理我们的 HTML TOC 中的所有“操作”。ShowAll() 和
HideAll() 只需要一个 tagName 参数,它们在页面上构建一个该标记(除了第一
个)的所有元素的集合,然后将每个元素的 style.display 属性设定为 "block"
(显示)或 "none"(隐藏)。前两个函数,document.onclick() 和
GetChildElem() 协同运行,以显示或隐藏父 <LI> 被单击的某个 <UL>。实际上
我们可能已经在 XSL 中编写了每个 <LI> 的 ONCLICK 属性,但像我们的同事
DHTML Dude (英文)一样,我们喜欢 Internet Explorer 事件排序的抽象、能
力和灵活性。


document.onlclick() 将文档的 onclick() 事件与本函数联系起来,因此在文档
上的单击都在此得以处理。现在,我们只希望在单击带有子 <UL> 的 <LI> 时执
行某种操作,我们首先检查用户是否单击了类名 为 "clsHasKids" 的元素。然后
,执行一些预防性的异常处理后,使用 GetChildElem() 要么返回对某个有效子
<UL> 的引用,要么返回错误,如果它不存在的话。最后,我们使用三组 JScript
条件语句将 style.disName)
{
  var cElems = document.all.tags(sTagName);
  var iNumElems = cElems.length;
  for (var i=1;i<iNumElems;i++) cElems[i].style.display = "block";
}

function HideAll(sTagName)
{
  var cElems = document.all.tags(sTagName);
  var iNumElems = cElems.length;
  for (var i=1;i<iNumElems;i++) cElems[i].style.display = "none";
}


使用 CSS 美化外观
最后,我们使用一点 CSS 小技巧来美化 TOC 的外观。本示例中的 CSS 相当简单
;您可以容易地完成一些更为复杂(也更为漂亮)的工作,如 Web Workshop(英
文)中的 TOC。这里祃eft:0px; margin-bottom:5px; }
LI UL { display:none; margin-left:16px; }
LI { font-weight:bold; list-style-type:square; cursor:default; }
LI.clsHasKids { list-style-type:none; cursor:hand; }

A:link, A:visited, A:active { font-weight:normal; color:navy; }
A:hover { text-decoration:none; }

BUTTON { font-family:tahoma; font-size:100%; }

显示不同的 TOC 视图
正如上面提到的,在 XML 存储数据的一个优点就是可以使用不同的样式表进行转
换,很容易地生成同一数据的不同视图。可下载的示例代码包括四个附加的 XSL
样式表(以及脚本和样式文件):divs.xsl 可以直观的层次 DIV 生成 TOPIC,
flat.xsl 在相同层次上生成所有 TOPIC,links.xsl 打印某个 TABLE 中的实际
URL,而 list_pp.xs、l 则对 list.xsl 稍作修改,以便生成较规整的 HTML 源
代码。

对所有浏览器进行处理:在服务器上进行转换
示例是基于在客户机的 Internet Explorer 5 上运行而编写的,它使用了 XML
mime-type。无论怎样,在跨浏览器的情形中,在服务器上转换 XML 并将其下传
“确实”是很容易的。下面的代码(它也在可下载的 .zip 文件中)就是针对这
一问题的。用户只需将示例文件放在 Internet Inflse;
  oXslDoc.async = false;
  oXmlDoc.load(Server.MapPath(sXml));
  oXslDoc.load(Server.MapPath(sXsl));
  Response.Write(oXmlDoc.transformNode(oXslDoc));
%>

详细信息
有关从 XML 创建 DHTML,或者其他使用 XML 的有趣信息,可访问 MSDN Online
Web Workshop(英文) 的 XML(英文)区,特别是本示例中突出显示的那些链接
。还请务必留意我的同事 Charlie Heinemann 的定期 Extreme XML(英文) 专
栏,它在 MSDN Online Voices 中。


George Young 是 Microsoft 的 MSDN Online 站点的开发负责人,以前曾在
Site Builder Network 站点工作。在他有空时,喜欢用 Windows 媒体播放器收
听墨西哥的广播电台,也常开着他的宝贝卡迪车往返于新奥尔良和华盛顿之间的
Redmond。


--


   我想超越这平凡的生活,注定我暂时漂泊!

   我无法停止我内心的狂热,对未来的执着!

※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.11.111]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店