XML卷之实战锦囊(5):结构树图
材料: XML卷之结构树图有2个文件:flow2.xml 和 flow2.xsl 效果: 浏览这里 讲解: 二叉树思路(1)
<html xmlns:v="urn:schemas-microsoft-com:vml"> <STYLE> v\:* { BEHAVIOR: url(#default#VML) } </STYLE> <v:group id="group1" name="group1" coordsize = "100,100"> … </v:group>
XML是树型结构,我们读取每个数据就需要对这个XML数据树进行遍历。而递归运算是XSL优势之一。我也是在用其它多种方法进行遍历运算失败后才决定使用XSL的。
<FlowRoot> <vcTitle>二叉树--结构图</vcTitle> <Author>Sailflying</Author> <Email>sailflying@163.net</Email> <FlowNode> <iProcess>1</iProcess> <vcCourse>第一个节点</vcCourse> <iNextYes> <FlowNode> <iProcess>2</iProcess> <vcCourse>第二个节点</vcCourse> <iNextYes>…</iNextYes> <iNextNo>…</iNextNo> </FlowNode> </iNextYes> <iNextNo> <FlowNode> <iProcess>3</iProcess> <vcCourse>第三个节点</vcCourse> <iNextYes>…</iNextYes> <iNextNo>…</iNextNo> </FlowNode> </iNextNo> </FlowNode> </FlowRoot>
逻辑上很简单,当前节点(1)下面有两个子节点(2,3)。只需要将节点2和节点3定位在节点1的左下方和右下方就可以了。这里我将左右节点的连接线分别用了绿色和红色,方便显示。
前面我们说到了XSL的递归功能,为了更清楚的看到每一个详细的显示步骤,只需要仿照下面的代码,加一个alert语句就可以了。
<xsl:template match="FlowNode">…<SCRIPT language="JavaScript1.2">…alert('逐步显示');…</SCRIPT>…</xsl:template>二叉树思路(2) 我的思路很简单:(1)读取当前节点的资料,用VML生成一个新的对象。给对象赋初始数值(如 name,id,style样式等)(2)用脚本控制来给当前对象定位(3)当前节点和它的父亲节点之间加箭头,线条。(4)继续找当前节点的子节点,一直循环定位到结束。也就是所有节点都遍历完毕,已经生成好了树。
<xsl:template match="FlowNode">…<xsl:apply-templates />…</xsl:template> <xsl:template match="iNextYes"><xsl:apply-templates select="./FlowNode" /></xsl:template> <xsl:template match="iNextNo"><xsl:apply-templates select="./FlowNode" /></xsl:template>
整个递归过程就是靠上面这三个模块(template)来完成的。第一个template在匹配当前节点中每一个子节点的模板的时候调用了后面两个template; 而后面两个template又在具体执行的时候调用了第一个template ,这就相当于一个递归函数。
语法:
要依次匹配当前节点中的每个子节点的模板,应使用该元素的基本形式 <xsl:apply-templates />。否则,匹配的节点由 select 参数中 XPath 表达式的值决定,如 <xsl:apply-templates select="./FlowNode" />
(1)和(2)的作用都是返回由 select 参数给出的表达式的字符串值。他们的搜索条件相同,所以返回的值也一样。只不过是使用的场合不同,他们的书写形式也就不一样。
(1) <xsl:value-of select="./iProcess/text()" />(2) {./iProcess/text()}
root_left //根的左边距=所有叶子的分配宽度(y*10) + 所有叶子的宽度(y*50) + 左边距基本值(10)root_top //根的上边距=上边距基本值(10)objOval //当前对象,是一个objectobjOval_iProcess //当前对象的步骤值objParentOval //当前对象的父节点,是一个objectobjParentOval_iProcess //当前对象父节点的步骤值objParent_name //当前对象父节点的名称Leaf_left //当前对象的所有子节点中的左边叶子数 Leaf_right //当前对象的所有子节点中的右边叶子数Leaf_sum //当前对象的所有子节点中叶子数
叶子:是指当前节点没有子节点
(1) 当前节点是根节点
//根的位置 SobjOval.style.left=parseInt(root_left); SobjOval.style.top=parseInt(root_top); //parseInt() 函数的作用是取整数值,如果不是则为NAN //isNaN()函数的作用是判断parseInt取得的是否为整数
1)判断的条件是: 当前对象父节点的名称='iNextYes'…2)如果存在右边子叶子,则公式为:当前节点的left=父节点的left - 当前节点的右边子叶子的总宽度- 当前节点的宽度
4)如果当前节点本身就是叶子,则公式为:当前节点的left=父节点的left - 当前节点的宽度 …
(3)当前节点是父节点的右边子节点
1)判断的条件是: 当前对象父节点的名称='iNextNo'…2)如果存在左边子叶子,则公式为:当前节点的left=父节点的left + 当前节点的左边子叶子的总宽度 + 当前节点的宽度
4)如果当前节点本身就是叶子,则公式为:当前节点的left=父节点的left + 当前节点的宽度 …
二叉树思路(3) 连接线条的定位思路: (1)找到当前节点和父节点的位置(2)判断当前节点是父节点的左边子节点,还是右边子节点(3)画线条
这里定义了一些变量。
objOval //当前节点,是一个objectobjParentOval //当前对象的父节点,是一个objectobjLine //当前线条,是一个object
当前节点是父节点的左边子节点,则公式为:from = 父节点的left + 偏移量(15) , 父节点的top + 偏移量(32)to = 父节点的left + 偏移量(30) , 父节点的top - 偏移量(2)
当前节点是父节点的右边子节点,则公式为:from = 父节点的left + 偏移量(35) ,父节点的top + 偏移量(32) to = 父节点的left + 偏移量(20) ,父节点的top - 偏移量(2)
首先计算最下层节点个数,得出宽度,然后应该根据节点的从属关系计算其上层节点位置,递归。每一层级的节点要按从属关系先排序首先设“基本值”=节点应向右偏移量每个包含子节点的节点的left值等于它所拥有的节点所占宽度的一半加上基本值
后话:
最近不知为何,网络一直都不好。断线的时间比在线的时间多。 所以没对代码简化,其实,要完善的功能还有很多,比如:需要加右键菜单右键菜单内含新建节点、修改节点名称、改变关联关系等在每一个节点上都可右键打开这个节点的右键菜单
讲解: 1)flow2.xml 是数据文件,相信大家都不会有问题。2)flow2.xsl 是格式文件,有几个地方要注意。 (1)脚本中:
(1) <xsl:value-of select="./iProcess/text()" /> ;(2) {./iProcess/text()}(1)和(2)的作用都是返回由 select 参数给出的表达式的字符串值。他们的搜索条件相同,所以返回的值也一样。只不过是使用的场合不同,他们的书写形式也就不一样。
<xsl:apply-templates select="team" order-by="blue_ID"/>
比如我们想生成以下代码<p 名称=“参数值”>内容</p>
第一种写法是先加属性名称,再加参数值
<p> <xsl:attribute name="name"> <xsl:value-of select="./book/text()"/> </xsl:attribute> 内容 </p>
<p name="{./book/text()}">内容</p>具体的使用你可以看我写的代码中的例子。
XSL在正式的 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 的标准里
<xsl:value-of select="./book/text()"/>
作用是:只是把他的文本值写出来,而
<xsl:value-of select="./book"/>
是把他的文本值和他的所有子节点的内容显示出来。大家可以试验一下,输出一个有子节点的,一个无子节点的看看显示的结果是否相同。
IE5 不支持 <tag att="{xpath}">要用
<tag><xsl:attribute name="att"><xsl:value-of select="xpath"></xsl:attribute>
xmlns:xsl="http://www.w3.org/TR/WD-xsl" <?xml version="1.0" encoding="gb2312" ?>
另外说一点:在大多的XML教科书中所显示的代码中很少会加上encoding="gb2312" ,因此我们在XML中用到中文的时候会报错,原因就是没有写这个申明。
后记: 这里说的是一种思路。如果触类旁通,自然能够派上用场。
以上就是XML卷之实战锦囊(5):结构树图的内容,更多相关内容请关注PHP中文网(www.php.cn)!
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场