您的位置: 南昌信息港 > 健康

用XSLT轻松实现树形折叠导航栏

发布时间:2019-06-19 21:28:28

  一般我们见到的XML文件是以元素为结点的,随着层次的不断加深,逐渐成了一棵树,这种文件的好处是我们一看就很明白其中的子、父、祖宗、兄弟关系,不方便之处在于,我个人认为,如果层次很深又有很多的兄弟结点的话,那么文件可能很大而影响处理的效率。正由于XML对描述数据结构的灵活性,所以在某些环境下采用属性值来描述元素之间的关系。例如花园左边的TOC(TABLE OF CONTENT),实现它的XML文件通过属性值来说明元素的类型(NODE OR LEAF), 不过里面仍有子结点存在, 所以用来TRANSFORM它的XSL文件很复杂,分了好几种情况。当然今天我们不是谈花园TOC的实现方法而是用一种更快速、更巧妙的方法来实现类似的TOC,当然也可以叫"树形折叠导航栏"。 好了,废话少说,进入正题。先来看一个很简单的DTD。 D

  !ELEMENT Navigation (Navigator*)

  !ELEMENT Navigator EMPTY

  !ATTLIST Navigator ID CDATA #IMPLIED AncestorID CDATA #IMPLIED Layer CDATA #IMPLIED Title CDATA #IMPLIED Childs CDATA #IMPLIED Url CDATA #IMPLIED Image CDATA #IMPLIED 文件很简单,可以这样理解,顶层元素Navigation包含了多个Navigator元素定义了,Navigator不包含元素但有一系列属性。 也许您已经发现, 属性中有两个叫AncestorID Childs的,对了,这两个属性是关键, 当然还有Layer, 在他们的共同作用下, Navigator元素之间的关系将被明确描述。 好了, 我们来看l文件, 以花园TOC做为例子。

  查看花园TOC例子:

  l

  ?xml version="1.0" encoding="gb2312"?

  !DOCTYPE Navi SYSTEM "d"

  ?xml-stylesheet type="text/xsl" href="l" ?

  Navigation

  Navigator ID=''1'' AncestorID=''1'' Layer=''0'' Title=''花园首页'' Childs=''0'' Url=''p'' Image=''images/f''/

  Navigator ID=''2'' AncestorID=''2'' Layer=''0'' Title=''我的花园'' Childs=''4'' Url=''#'' Image=''default''/

  Navigator ID=''3'' AncestorID=''2'' Layer=''1'' Title=''收藏夹'' Childs=''4'' Url=''#'' Image=''default''/

  Navigator ID=''21'' AncestorID=''3'' Layer=''2'' Title=''我管理的花坛'' Childs=''0'' Url=''p?cat=g'' Image=''images/f''/

  Navigator ID=''22'' AncestorID=''3'' Layer=''2'' Title=''我种下的种子'' Childs=''0'' Url=''p?cat=t'' Image=''images/f''/

  Navigator ID=''23'' AncestorID=''3'' Layer=''2'' Title=''我喜欢的花园'' Childs=''0'' Url=''p?cat=g'' Image=''images/f''/

  Navigator ID=''24'' AncestorID=''3'' Layer=''2'' Title=''我收藏的文章'' Childs=''0'' Url=''p?cat=t'' Image=''images/f''/

  Navigator ID=''4'' AncestorID=''2'' Layer=''1'' Title=''个人工具箱'' Childs=''2'' Url=''#'' Image=''default''/

  Navigator ID=''25'' AncestorID=''4'' Layer=''2'' Title=''配置和管理'' Childs=''0'' Url=''p'' Image=''images/f''/

  Navigator ID=''26'' AncestorID=''4'' Layer=''2'' Title=''花瓣兑换点'' Childs=''0'' Url=''p'' Image=''images/f''/

  Navigator ID=''27'' AncestorID=''2'' Layer=''1'' Title=''我的日记本'' Childs=''0'' Url=''p'' Image=''images/f''/

  Navigator ID=''6'' AncestorID=''2'' Layer=''1'' Title=''好友和短讯'' Childs=''0'' Url=''p'' Image=''images/f''/

  Navigator ID=''7'' AncestorID=''7'' Layer=''0'' Title=''计算机技术'' Childs=''2'' Url=''#'' Image=''default''/

  Navigator ID=''8'' AncestorID=''7'' Layer=''1'' Title=''DHTML,JScript'' Childs=''0'' Url=''p?c=6g=16'' Image=''images/f''/

  Navigator ID=''9'' AncestorID=''7'' Layer=''1'' Title=''.NET,ASP+探讨'' Childs=''0'' Url=''p?c=6g=17'' Image=''images/f''/

  Navigator ID=''10'' AncestorID=''7'' Layer=''1'' Title=''ASP互助'' Childs=''0'' Url=''p?c=6g=18'' Image=''images/f''/

  Navigator ID=''11'' AncestorID=''11'' Layer=''0'' Title=''箐箐校园'' Childs=''2'' Url=''#'' Image=''default''/

  Navigator ID=''12'' AncestorID=''11'' Layer=''1'' Title=''南京大学'' Childs=''0'' Url=''p?c=7g=19'' Image=''images/f''/

  Navigator ID=''13'' AncestorID=''11'' Layer=''1'' Title=''东南大学'' Childs=''0'' Url=''p?c=7g=20'' Image=''images/f''/

  Navigator ID=''14'' AncestorID=''14'' Layer=''0'' Title=''花园·有个广场'' Childs=''2'' Url=''#'' Image=''default''/

  Navigator ID=''15'' AncestorID=''14'' Layer=''1'' Title=''意见箱'' Childs=''0'' Url=''p?c=8g=21'' Image=''images/f''/

  Navigator ID=''16'' AncestorID=''14'' Layer=''1'' Title=''花园·人物故事'' Childs=''0'' Url=''p?c=8g=22'' Image=''images/f''/

  Navigator ID=''17'' AncestorID=''17'' Layer=''0'' Title=''园丁办公室'' Childs=''0'' Url=''p?c=9g=23'' Image=''images/f''/

  Navigator ID=''18'' AncestorID=''18'' Layer=''0'' Title=''青青芳草地'' Childs=''0'' Url=''p?c=9g=24'' Image=''images/f''/

  Navigator ID=''19'' AncestorID=''19'' Layer=''0'' Title=''统计信息'' Childs=''0'' Url=''p'' Image=''images/f''/

  Navigator ID=''20'' AncestorID=''20'' Layer=''0'' Title=''ActiveCard'' Childs=''0'' Url=''activecard?fromgarden'' Image=''images/f''/

  /Navigation

  结合上面我讲的和花园左边的TOC, 仔细分析这个文件后, 找出元素间存在的关系是很容易的, 难的是怎么想到这么来创建XML文件的。 好了, 有了数据, 下一步就是如何MANUPILATE了。

  [下一页]

  我引用花园的TOC,一是让大家能有个初步印象,等文章完成后, 把几个文件CP加上几个图片, 在IE5以上的机器上象打开一个html文件一样打开l后,就会出现跟花园很类似的TOC了;二是希望大家根据它的层次结构来分析我的xml文件, 因为除顶层外, 我的层次安排和花园是一样的。 我来解释一下:Layer相同表示元素处在同一层次即兄弟关系, Childs的值表示该元素是否有子结点, 父子之间用AncestorID和ID联系, 依次类推可以扩充至无限次深。 在xsl文件中根据Layer的值用padding-left属性来实现树形,根据Layer的值用display:none或block来实现折叠。 原理即此, 好,来看看这个关键的l: ?xml version="1.0" encoding="gb2312" ?

  HTML

  HEAD

  TITLEXSLT树形导航栏/TITLE

  LINK rel="stylesheet" type="text/css" href="s"/

  SCRIPT src=""/SCRIPT

  /HEAD

  BODY

  DIV xmlns:xsl=""

  TABLE

  TR

  TDDIV noWrap="true" STYLE="padding-left:0em;"有座花园分类目录/DIV/TD

  /TR

  xsl:for-each select="Navigation/Navigator"

  TR

  xsl:attribute name="TITLE"xsl:value-of select="@Title" //xsl:attribute

  xsl:attribute name="Class"Navigatorxsl:if test="@Layer[.0]"-Hidden/xsl:if/xsl:attribute

  xsl:attribute name="ID"xsl:value-of select="@ID"//xsl:attribute

  xsl:attribute name="AncestorID"xsl:value-of select="@AncestorID"//xsl:attribute

  xsl:attribute name="Depth"xsl:value-of select="@Layer"//xsl:attribute

  xsl:if test="@Childs[.0]"

  xsl:attribute name="Expanded"no/xsl:attribute

  /xsl:if

  TD STYLE="cursor:hand"

  DIV noWrap="true"xsl:attribute name="STYLE"padding-left:xsl:value-of select="@Layer"/em;/xsl:attribute

  xsl:choose

  xsl:when test="@Childs[.0]"IMG src="images/f"/IMG/xsl:when

  xsl:otherwiseIMGxsl:attribute name="src"xsl:value-of select="@Image" //xsl:attribute/IMG/xsl:otherwise

  /xsl:choose

  Axsl:if test="@Childs[.0]"xsl:attribute name="onclick"toggle(''xsl:value-of select="@ID" /'')/xsl:attribute/xsl:ifxsl:attribute name="href"xsl:value-of select="@Url" //xsl:attributexsl:value-of select="@Title" //A/DIV/TD

  /TR

  /xsl:for-each

  /TABLE

  /DIV

  /BODY

  /HTML

  [下一页]

  当然, 少了s是不行的。

  s

  BODY

  {

  font-family:Verdana;

  cursor:default;

  font-size:9pt;

  }

  TABLE

  {

  font-size:110%;

  }

  A

  {

  color:"#003366";

  text-decoration:none;

  }

  A:hover

  {

  text-decoration:underline;

  color:#003366;

  }

  DIV IMG

  {

  MARGIN-BOTTOM: 0px;

  MARGIN-RIGHT: 5px;

  MARGIN-TOP: -3px;

  VERTICAL-ALIGN: middle

  }

  DIV A:hover

  {

  BACKGROUND-COLOR: greenyellow

  }

  DIV A

  {

  FONT-WEIGHT: normal;

  MARGIN-RIGHT: 5px;

  VERTICAL-ALIGN: middle

  }

  .Navigator

  {

  color: #003366;

  }

  .Navigator-Hidden

  {

  display:none;

  }

  现在运行l的话, 您就会看见所有Layer=0的Navigator了(因为那些Layer0的被Class="Navigator-Hidden"隐藏起来了), 当然现在还不能实现展开和折叠, 缺少toggle这个函数。

  [下一页]

  展开和折叠其实就是显示或不显示display:none or block)它与可见与不可见(visible or invisible)是有区别的, 前者不在页面预留空间。 这个toggle函数完成两个功能, 改变TR原来的Hidden属性, 使原来不显示的显示; 改变IMG的src属性, 更改图片。

  function toggle(id)

  {

  var thisRow = em(id);

  if (thisRow)

  {

  if (tAttribute("Expanded") == ''yes'')

  {

  tAttribute("Expanded", "no");

  ildren(0).children(0).children(0).src = "images/f";

  var allRows = gs("TR");

  for (var i=1; i ngth; i++)

  {

  var row = allRows[i];

  if (tAttribute("AncestorID") == id)

  {

  if (tAttribute("Expanded") == ''yes'') {

  toggle(tAttribute("id"));

  }

  assName = ''Navigator-Hidden'';

  }

  }

  assName = ''Navigator'';

  }

  else

  {

  tAttribute("Expanded", "yes");

  ildren(0).children(0).children(0).src = "images/f";

  var allRows = gs("TR");

  var depth = parseInt(tAttribute("Depth"));

  for (var i=1; i ngth; i++)

  {

  var row = allRows[i];

  if (tAttribute("AncestorID") == id

  parseInt(tAttribute("Depth")) == depth + 1 )

  {

  assName = ''Navigator'';

  }

  }

  }

  }

  }

  到此结束。

  诚然这个TOC的功能还是基本的, 例如我还未做内容和目录的同步,其中有的地方还可以修改, 对xml和xsl文件可以进一步瘦身。 不过对一般用户来讲, 这已经足够了。

  真诚希望这篇文章能对您有所启发、有所帮助, 以后做出更酷、更快、更方便、功能更强的TOC。

经期延长可以吃点什么
经期延长可以吃什么调理
经期延长量多吃什么药
猜你会喜欢的
猜你会喜欢的