亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

XML卷之實戰錦囊(5):結構樹圖

2019-11-18 19:56:32
字體:
來源:轉載
供稿:網友

動機:
最初想起做二叉樹是因為需要做一個公司結構圖。 以前的做法都是直接用圖象軟件畫出來一個圖片。很好看,但每次有變動后都需要重新畫一個新的。 另一方面,網頁上對線條的顯示、布局相當局限。根據動態生成的數據進行排版、定位都相當困難, 而且在美觀上也差強人意。 做了各種嘗試以后,決定用xml+XSL作數據運算; 用VML來美化線條,用javaSCRipT來給對象定位。

材料:
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>
以上這些都是VML的基本格式,我就不詳細講解了。

 

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 //當前對象,是一個object
objOval_iProcess //當前對象的步驟值
objParentOval //當前對象的父節點,是一個object
objParentOval_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取得的是否為整數


(2)當前節點是父節點的左邊子節點

 

1)判斷的條件是: 當前對象父節點的名稱='iNextYes'

2)如果存在右邊子葉子,則公式為:
當前節點的left=父節點的left - 當前節點的右邊子葉子的總寬度- 當前節點的寬度

3)如果不存在右邊子葉子,但存在左邊子葉子,則公式為:
當前節點的left=父節點的left - 當前節點的左邊子葉子的總寬度

4)如果當前節點本身就是葉子,則公式為:
當前節點的left=父節點的left - 當前節點的寬度

 

(3)當前節點是父節點的右邊子節點

 

1)判斷的條件是: 當前對象父節點的名稱='iNextNo'

2)如果存在左邊子葉子,則公式為:
當前節點的left=父節點的left + 當前節點的左邊子葉子的總寬度 + 當前節點的寬度

3)如果不存在左邊子葉子,但存在右邊子葉子,則公式為:
當前節點的left=父節點的left + 當前節點的右邊子葉子的總寬度

4)如果當前節點本身就是葉子,則公式為:
當前節點的left=父節點的left + 當前節點的寬度

 


(2)和(3)的公式都是得到當前節點的left,我們還需要得到當前節點的top
很簡單的公式:當前節點的top=父節點的top + 偏移量(80)

 


二叉樹思路(3)
連接線條的定位思路:
(1)找到當前節點和父節點的位置
(2)判斷當前節點是父節點的左邊子節點,還是右邊子節點
(3)畫線條


這里定義了一些變量。

 

objOval //當前節點,是一個object
objParentOval //當前對象的父節點,是一個object
objLine //當前線條,是一個object


線條的定位公式:

 


from="x1,y1" to="x2,y2" 是 VML 里定位線條的方式

當前節點是父節點的左邊子節點,則公式為:
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"/>
比如我們想生成以下代碼
<div 名稱=“參數值”>內容</div>


我們假設名稱為“name”,參數值為XML數據中當前節點下面的子節點book的值


第一種寫法是先加屬性名稱,再加參數值
<div>
<xsl:attribute name="name">
<xsl:value-of select="./book/text()"/> </xsl:attribute>
內容
</div>

第二種寫法是直接加屬性名稱和參數值
<div name="{./book/text()}">內容</div>

具體的使用你可以看我寫的代碼中的例子。

XSL在正式的 xmlns:xsl="

<xsl:value-of select="./book/text()"/>
作用是:只是把他的文本值寫出來,而
<xsl:value-of select="./book"/>
是把他的文本值和他的所有子節點的內容顯示出來。
大家可以試驗一下,輸出一個有子節點的,一個無子節點的
看看顯示的結果是否相同。


(2)需要注意:

IE5 不支持 <tag att="{xpath}">
要用
<tag><xsl:attribute name="att"><xsl:value-of select="xpath"></xsl:attribute>

命名空間要用
xmlns:xsl="

<?xml version="1.0" encoding="gb2312" ?>
另外說一點:
在大多的XML教科書中所顯示的代碼中很少會加上encoding="gb2312" ,
因此我們在XML中用到中文的時候會報錯,原因就是沒有寫這個申明。

 


后記:
這里說的是一種思路。如果觸類旁通,自然能夠派上用場。 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品露脸国产偷人在视频| 中文字幕日韩欧美在线视频| 欧美黑人xxx| 一区二区av在线| 97人人做人人爱| 日日噜噜噜夜夜爽亚洲精品| 疯狂做受xxxx欧美肥白少妇| 久久综合久久美利坚合众国| 国产69精品99久久久久久宅男| 91精品在线一区| 亚洲色无码播放| 日韩在线一区二区三区免费视频| www日韩欧美| 欧美中文字幕在线视频| 欧美激情性做爰免费视频| 中文字幕av日韩| 日本精品视频在线观看| 精品一区二区电影| 亚洲天堂男人天堂女人天堂| 92国产精品久久久久首页| 在线精品国产欧美| 国产精品视频一区二区三区四| 亚洲欧洲xxxx| 成人免费在线视频网址| 久久精品视频99| www.日韩系列| 日本一区二区在线免费播放| 欧美野外猛男的大粗鳮| 欧美激情视频在线| 精品国产91久久久久久| 91高清视频免费观看| 欧美午夜丰满在线18影院| 国产国语刺激对白av不卡| 国产一区二区三区在线观看网站| 久久久99久久精品女同性| 久久99精品视频一区97| 精品偷拍各种wc美女嘘嘘| 亚洲影院污污.| 91精品视频一区| 国产日本欧美一区二区三区在线| 国产精品综合网站| 欧美性黄网官网| 成人免费视频网址| 亚洲电影免费观看高清完整版在线观看| 国产精品人成电影在线观看| 亚洲欧洲成视频免费观看| 精品国内亚洲在观看18黄| 米奇精品一区二区三区在线观看| 国产精品久久久久aaaa九色| 综合国产在线视频| 色与欲影视天天看综合网| 欧美在线视频播放| 色一情一乱一区二区| 一区二区三区动漫| 久久久亚洲精品视频| 亚洲欧美变态国产另类| 爽爽爽爽爽爽爽成人免费观看| 欧美麻豆久久久久久中文| 久久久久国产精品免费网站| 欧美激情视频播放| 国产一区二区动漫| 91久久中文字幕| 成人性生交大片免费看视频直播| 午夜精品一区二区三区视频免费看| 国语自产精品视频在线看一大j8| 91在线高清视频| 欧美激情小视频| 亚洲伊人第一页| 欧美日韩在线观看视频小说| 亚洲a中文字幕| 欧美精品电影免费在线观看| 中文字幕亚洲综合久久| 欧美在线一级va免费观看| 欧美性猛交xxxx黑人猛交| 欧美亚洲另类视频| 亚洲国产成人一区| 国产精品女人久久久久久| 日韩欧美中文免费| 色哟哟网站入口亚洲精品| 亚洲欧洲在线看| 欧美国产乱视频| 4444欧美成人kkkk| 中文字幕日韩专区| 日韩av成人在线观看| 亚洲欧美日韩一区二区三区在线| 亚洲欧美国内爽妇网| 91午夜在线播放| 欧美老少配视频| 国产精品羞羞答答| 亚洲国产精品久久久久秋霞蜜臀| 欧美另类69精品久久久久9999| 亚洲国产精品成人va在线观看| 国产999精品久久久影片官网| 亚洲影视中文字幕| 国产精品视频网站| 亚洲三级黄色在线观看| 懂色av影视一区二区三区| 国产一区私人高清影院| www.欧美三级电影.com| 日韩av男人的天堂| 中文字幕日韩高清| 亚洲精品一区二区三区不| 亚洲欧洲一区二区三区在线观看| 国产精品久久久久久久久久小说| 日本久久91av| 亚洲女人初尝黑人巨大| 久久人人爽人人爽人人片av高清| 欧美黄色片免费观看| 色99之美女主播在线视频| 永久免费毛片在线播放不卡| 最新的欧美黄色| 国内成人精品一区| 日韩精品视频在线| 亚洲一区二区在线播放| 久久免费视频网| 国产美女91呻吟求| 国产成人短视频| 国产精品成人免费视频| 亚洲精品久久视频| 影音先锋欧美精品| 欧美精品videos性欧美| 亚洲欧美中文日韩在线| 亚洲成人在线网| 久久精品青青大伊人av| 欧美精品少妇videofree| 久久久久久噜噜噜久久久精品| 国产精品一二三视频| 成人激情综合网| 欧美激情videos| 久久不射热爱视频精品| 久久99久久久久久久噜噜| 日韩成人性视频| 欧美网站在线观看| 久久久噜噜噜久久| 亚洲高清不卡av| 欧美色视频日本版| 精品无人区乱码1区2区3区在线| 国产97色在线| 久久国产色av| 国产xxx69麻豆国语对白| 亚洲国产精品福利| 日韩在线精品视频| 欧美日韩亚洲高清| 性欧美办公室18xxxxhd| 国内精品中文字幕| 另类视频在线观看| 成人网页在线免费观看| 成人日韩在线电影| 国产美女精品免费电影| 91高清在线免费观看| 欧美精品免费播放| 欧美国产视频日韩| 亚洲国产欧美日韩精品| 久久综合伊人77777尤物| 中文字幕亚洲欧美在线| 欧美日韩第一视频| 97香蕉超级碰碰久久免费的优势| 国产精品成人播放| 欧美激情精品在线| 国模精品系列视频| 国产精品户外野外| 亚洲最大激情中文字幕| 欧美—级a级欧美特级ar全黄| 亚洲综合大片69999|