XML和XSL生成类PowerPoint组织结构图

近日我正在潜心初学XML和XSL的相关技术,一日,漫漫长夜,无心睡眠,突心血来潮,想一试自己这段时间所学。因有感每日所用XML数据格式的层次性,总觉和树状结构的有相似之处,同时,受工作中要实现一组织结构图的鼓惑,故就尝试用XML和XSL来实现一个自己已用ASP实现的类似PowerPoint中的组织结构图,功成之时,不亦乐乎,掩饰不住的暗爽,真是不吐不快。故欲将其中的艰辛和喜悦,困难和收获一并拿出,希望能和象我一样初学XML的、或是已是高手高手高高手的各位分享之。好,口说无凭,列位上眼呐!

实现的组织结构如下图所示:

此主题相关图片如下:

该组织结构图实现的主要功能为:

无层数限制的显示各个层之间的相关关系。

通过点击各节点旁边的“+”,“-”图标来展开或收缩该节点的下属层。

首先先来看一下相关的文件结构

Organize .xml数据文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet type="text/xsl" href="Organize.xsl"?>

<Root>

<Layer>

<id/>

<text/>

</Layer>

<Layer>

<id>01</id>

<text>XX集团</text>

</Layer>

<Layer>

<id>0101</id>

<text>上海分公司</text>

</Layer>

……

<Layer>

<id>0103</id>

<text>北京分公司</text>

</Layer>

<Layer>

<id>010101</id>

<text>人事部</text>

</Layer>

……

<Layer>

<id>010302</id>

<text>财务部</text>

</Layer>

<Layer>

<id>01030101</id>

<text>人事部经理</text>

</Layer>

<Layer>

<id>01030102</id>

<text>人事部助理</text>

</Layer>

……

<Layer>

<id>01010301</id>

<text>技术经理</text>

</Layer>

……

</Root>

Organize.xsl文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

<html>

<head>

<title>组织结构图</title>

</head>

<style type="text/css">

……

</style>

<body>

<center>

</br>

<span>组织结构图</span>

<div>

<xsl:call-template name="getLayer">

<xsl:with-param name="LayerID" select="/Root/Layer[1]/id"/>

</xsl:call-template>

</div>

</center>

</body>

</html>

</xsl:template>

<xsl:template name="getLayer">

<xsl:param name="LayerID"/>

<xsl:for-each select="//Layer[substring(id,1,string-length($LayerID))=$LayerID

and string-length(id)=string-length($LayerID)+2]">

<span>

……   ------ 省略了div的样式表

<img src="close.gif" alt="">

……   ------ 省略了img图标的相关操作

</img>

<span>

<a href="#" target="newWindow">

<xsl:value-of select="./text"/>

</a>

</span>

<div>

……   ------ 省略了div的样式表

<xsl:call-template name="getLayer">

<xsl:with-param name="LayerID" select="id"/>

</xsl:call-template>

</div>
        </span>
       </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

设计的思路为:

首先想到的是,组织结构在表现形式上是各个组织部门之间为:上层(权且以父层代替)以包含下层(权且以子层代替),同时各个同被父层包含的子层之间是并列平等的。

这样,我就想到对于每一层而言,都有相同的结构:对自己描述,和包含子层的容器,即为:

此主题相关图片如下:

   想到这点,我就想到用

<SPAN>
              <SPAN></SPAN> --------对自己的描述
              <DIV></DIV>   --------包含子层的容器
       </SPAN>
结构来表示一个节点。因为这样既可保证各个相同层的节点是并列的,同时也实现了对每一节点,对自己的描述和所包含的子层在表现形式上是上下的。

确定了节点的表现结构后,再来考虑组织结构的数据表现格式,为保证获得组织结构数据结构的通用性和易获得性,我没有考虑按实际组织结构关系那样组织XML文件中各节点之间的关系。因为考虑到我的XML文件是从数据库中动态的生成的,如生成的XML文件格式为:

<Layer>

<id>01</id>

<text>aaaa</text>

<children>

<Layer>

<id>0101</id>

<text>bbbb</text>

<children>

……

</children>

</Layer>

</children>

</Layer>

虽然看上去挺明白,但小弟认为即不是很通用,同时,也是最关键的,用SQL语句从数据库中获得这样的数据结构,嘿嘿,小弟自觉的虽有些经纶,但还真的实现不了:),所以放弃了。选自认为最简单的实现方法,就是象上文Organize .xml中的那样,从各个节点看去,虽相互平等,但他们通过id来关联,子节点的id=父节点的id+序号,通过id来建立彼此的相互关系(即为:0101,0102,….010N都是01的子节点)。这样,小弟认为,即使一个初学者,掰一会的书,也会搞定生成这个数据结构的SQL语句来。看到此,暂且按住不表,俗话说,“真正为用户考虑的开发者,才是好的开发者”,在这字里行间,所显露的小弟的伟大和用心良苦之处,请大家暂停手中的一切事务,为小弟努力的呱唧呱唧。呵呵,终于,掌声四起。。。。。。

确定好了组织结构的数据表现格式,接下来所要考虑的最关键的XSL,就有了针对性了。因为,小弟所设想的流程是:

当检索到某一个节点时,首先要考虑的是提取该节点的对自己的描述,也即该节点的title,

同时对该节点,肯定还要查找是否有所属的子节点并提取之。对于每个节点依次进行相同的操作。

既然是这样,那根据小弟多年在编程中摸打滚爬,碰了东墙磕西墙历练出来的直觉,首先隐约感觉到的就是递归!。哈哈哈哈哈哈。。。。小弟自以为找到的解决的方案,各位看官意下如何?呵呵,暗爽呀。以下就是小弟根据所想的,实际的解决方案:

首先从根节点开始:<xsl:template match="/">

然后调用模板getLayer,将当前根节点的第一个子节点的id作为变参传入模板:

<xsl:call-template name="getLayer">

<xsl:with-param name="LayerID" select="/Root/Layer[1]/id"/>

</xsl:call-template>

在模板getLayer中,当检索到某一个节点,首先是提取该节点的对自己的描述。这可以通过XSLT语句

<xsl:value-of select="./text"/>

获得。(以下相关的XSLT语句更详细准确的描述,请查阅相关的资料和书籍)

同时,通过自身的id,在XML数据中检索出自己相关的所属子节点。这个是通过:

<xsl:for-each select="//Layer[substring(id,1,string-length($LayerID))=$LayerID

and string-length(id)=string-length($LayerID)+2]">

语句搞定的。在这个语句中,LayerID既为传入的父节点的id,通过该语句,可以检索出所有id前string-length($LayerID)位的内容=$LayerID并且总长度= string-length($LayerID) + 2 位序号长度的节点(这里,小弟暂定的每一节点的子节点的长度为该节点的长度+2位序号长度,可根据实际需要改动)。通过这个语句,也实现了另外一个功能,既:不需要考虑各个节点的顺序或位置。在XML文件中,子节点和父节点之间的顺序是可以跳跃的,各个Layer的顺序可以随意放置。我想,这应该也方便了在实际应用中的运用。

然后,依次根据每个检索到的子节点,递归调用模板getLayer。由此取得每个子节点的内容,填充到包含子层的容器中。

通过以上的设计思想和解决方案,生成了类PowerPoint组织结构图。而且,通过进一步的考虑,只改动XSL,利用同一个原XML文件,小弟还实现了类资源管理器的树状结构。如下图:

此主题相关图片如下:

实现的思想就是将同一层的节点布局由现在的水平排列改为上下的竖直排列,每一节点的文本方向由竖直改为水平,同时增加相应的缩进平即可。呵呵,是不是很简单!

通过这个学习和实践的过程,小弟虽稍有愚钝,却也感觉到了XML和XSL的灵活和强大功能。小弟以为,XML提供了数据的存储,XSL则提供了数据的操作和表现。XSL一如XML的外挂,内在的内容始终如一,而通过配合相应的不同的XSL,则可构造多样的表现形式和应用出来。不知各位意下如何。

以上是小弟初试所学,水平所限,当然其中会可能需要推敲和完善的地方,小弟之所以献丑,就是希望能与大家分享之余,能得到各位看官的赐教,能在各位看官的指点和批评中进步,这就是小弟的所希望的最大的收获了。

XML和XSL生成类PowerPoint组织结构图相关推荐

  1. 使用XML及XSL生成简单HTML

    某些时候需要生成HTML展现数据,考虑过XML加XSL方法吗?比如,以html邮件的方式发送一些数据. 本文通过两个已经存在的文件,xml文件和xsl文件演示如何将其转换成HTML. 首先,准备XML ...

  2. XML之自动生成类,添加,修改,删除类的属性

    1. class ClassHelperDemo{public static void Main(){#region 演示一:动态生成类.//生成一个类t.Type t = ClassHelper.B ...

  3. anychart java实例_结合AnyChart做报表:一个生成AnyChart图形XML数据的工具类

    今天头有点痛,所以不能详细地写了,先把代码贴上来,等身体状况稍微好一点,再继续完善. 1.(主角)一个使用XML模板生成Anychart XML数据的工具类 /** * */ package com. ...

  4. html+注释格式化,使用xml注释来生成格式化的html输出

    我试图从我在xml文件中的注释中生成一个格式良好的html文档.目前我有一个xml文件,用于生成xml表格的html列表.为了让我添加有关表格的评论,我手动将注释添加到输出html文件中.使用xml注 ...

  5. XML通过XSL格式化的那点事(XML到自定义节点折叠显示)

    引言 有时我们想看下系统生成的XML文件(如XML格式的Project文件),如果文件结构简单,我们浏览器看起来还比较方便,但是随着XML schema复杂后就变得让人头疼啦,单独写一个程序去做展现又 ...

  6. C#实现TreeView向XML的绝对转换类

    从第一次接触XML开始就想写一个能实现tree和XML灵活转换的类了. 写这个类大概用去了将近半天的时间,花的时间有些长了.呵呵..好在收获颇多,熟练了XML的读写类,对C#中的foreach循环也有 ...

  7. XML命名空间和相关类简介

    在深入进行.Net框架下的XML文档的操作之前,我想很有必要向大家介绍.Net框架中与XML技术有关的命名空间和其中一些重要的类..Net 框架为我们提供了以下一些命名空间:System.Xml.Sy ...

  8. C#中XML、JSON、类T数据格式之间的转换

    在C#中,XML与JSON之间可以相互转化 XML与T类型也可以相互转化[XML有且只有一个根节点] JSON与T类型也可以相互转化. 新建控制台应用程序JsonToXmlToClassDemo,(. ...

  9. PHP网站地图生成类

    这篇文章,给大家介绍一个php网站地图生成类. 做网站的朋友们都有过这样的经历,在一个新站刚刚开始运营时,最希望的就是百度.google这样的搜索引擎来索引自己的页面,恨不得让蜘蛛不停地爬,赶快把自己 ...

最新文章

  1. HOG 特征计算实现
  2. 改进C#代码之24:通过定义并实现接口替代继承
  3. BZOJ1208[HNOI2004]宠物收养场——treap
  4. oracle asm 异机挂载,oracle 异机恢复 从asm到文件系统成功实例
  5. Lines色线halcon算子,持续更新
  6. s5pv210——SDRAM的初始化
  7. linux内核网络raw_cpu_add,深入理解Linux网络技术内幕-设备注册和初始化(四)
  8. python爬虫避免重复数据_No.2﹣Python﹣scan﹣anti-crawler(随机请求头和IP代理)取消链接和重复数据消除,NO2pythonscrapy,反,爬虫,去...
  9. 1043 幸运号码 数位DP
  10. grafana将自己的数据库(hbase)设置为数据源
  11. No toolchains found in the NDK toolchains folder for ABI with prefix:XXX
  12. word文档可以压缩大小吗,详细压缩步骤
  13. CVPR 2021 Oral | 妙啊!不怕遮挡的图像线段匹配 SOLD2,还能联合自监督线段检测
  14. linux后门rootkit程序介绍
  15. JDK 1.4 中打印,
  16. slogan - 构建认知价值
  17. oracle 授予 sequence,Oracle中的角色和权限授予
  18. 破解某助手刺探功能---第二篇smali代码实现
  19. 慕课网——MySQL优化
  20. 在江西景德镇,连垃圾桶都是青花瓷的。。。

热门文章

  1. 期货交易时间怎么规定(股指期货交易时间)
  2. Java中将数组转成List
  3. ABP5.x框架T4模板代码生成器
  4. zynq配置成jtag模式_Zynq-7000 MiZ701 SOC硬件使用手册
  5. python拼写_Python拼写游戏
  6. 记录一次由屁股决定研发的狗血经历
  7. 《开运斗地主》隐私政策
  8. 使用Oh my Posh设置Windows PowerShell主题要点
  9. Anaconda怎么用
  10. leela zero 在amd显卡使用