XML卷之實戰(zhàn)錦囊(5):結(jié)構(gòu)樹圖_Xml教程
推薦:采用XML數(shù)據(jù)來填充ASP表單在本篇文章里,我們會使用一個簡單的Web表單,它會列出某個目錄下的一些XML文件。然后,我們會從這個目錄里選擇一個文件,將它發(fā)送到另一個Web表單里,后 者會使用被選中的XML文件來填充某些
最初想起做二叉樹是因為需要做一個公司結(jié)構(gòu)圖。 以前的做法都是直接用圖象軟件畫出來一個圖片。很好看,但每次有變動后都需要重新畫一個新的。 另一方面,網(wǎng)頁上對線條的顯示、布局相當局限。根據(jù)動態(tài)生成的數(shù)據(jù)進行排版、定位都相當困難, 而且在美觀上也差強人意。 做了各種嘗試以后,決定用XML XSL作數(shù)據(jù)運算; 用VML來美化線條,用JAVASCRIPT來給對象定位。
材料:
XML卷之結(jié)構(gòu)樹圖
有2個文件:flow2.xml 和 flow2.xsl
講解:
二叉樹思路(1)
| 以下為引用的內(nèi)容: <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是樹型結(jié)構(gòu),我們讀取每個數(shù)據(jù)就需要對這個XML數(shù)據(jù)樹進行遍歷。而遞歸運算是XSL優(yōu)勢之一。我也是在用其它多種方法進行遍歷運算失敗后才決定使用XSL的。
| 以下為引用的內(nèi)容: <FlowRoot> |
邏輯上很簡單,當前節(jié)點(1)下面有兩個子節(jié)點(2,3)。只需要將節(jié)點2和節(jié)點3定位在節(jié)點1的左下方和右下方就可以了。這里我將左右節(jié)點的連接線分別用了綠色和紅色,方便顯示。
前面我們說到了XSL的遞歸功能,為了更清楚的看到每一個詳細的顯示步驟,只需要仿照下面的代碼,加一個alert語句就可以了。
| 以下為引用的內(nèi)容: <xsl:template match="FlowNode"> |
二叉樹思路(2)
我的思路很簡單:
(1)讀取當前節(jié)點的資料,用VML生成一個新的對象。給對象賦初始數(shù)值(如 name,id,style樣式等)
(2)用腳本控制來給當前對象定位
(3)當前節(jié)點和它的父親節(jié)點之間加箭頭,線條。
(4)繼續(xù)找當前節(jié)點的子節(jié)點,一直循環(huán)定位到結(jié)束。
也就是所有節(jié)點都遍歷完畢,已經(jīng)生成好了樹。
| 以下為引用的內(nèi)容: <xsl:template match="FlowNode"> <xsl:template match="iNextNo"> |
整個遞歸過程就是靠上面這三個模塊(template)來完成的。第一個template在匹配當前節(jié)點中每一個子節(jié)點的模板的時候調(diào)用了后面兩個template; 而后面兩個template又在具體執(zhí)行的時候調(diào)用了第一個template ,這就相當于一個遞歸函數(shù)。
語法:
要依次匹配當前節(jié)點中的每個子節(jié)點的模板,應(yīng)使用該元素的基本形式 <xsl:apply-templates />。否則,匹配的節(jié)點由 select 參數(shù)中 XPath 表達式的值決定,如 <xsl:apply-templates select="./FlowNode" />
(1)和(2)的作用都是返回由 select 參數(shù)給出的表達式的字符串值。他們的搜索條件相同,所以返回的值也一樣。只不過是使用的場合不同,他們的書寫形式也就不一樣。
(1) <xsl:value-of select="./iProcess/text()" />
(2) { ./iProcess/text()}
這里定義了一些變量,節(jié)點的定位就是根據(jù)這些變量來調(diào)用運算公式的。
| 以下為引用的內(nèi)容: root_left //根的左邊距=所有葉子的分配寬度(y*10) 所有葉子的寬度(y*50) 左邊距基本值(10) |
葉子:是指當前節(jié)點沒有子節(jié)點
節(jié)點的定位公式:
(1) 當前節(jié)點是根節(jié)點
| 以下為引用的內(nèi)容: //根的位置 |
(2)當前節(jié)點是父節(jié)點的左邊子節(jié)點
1)判斷的條件是:當前對象父節(jié)點的名稱='iNextYes'
2)如果存在右邊子葉子,則公式為:當前節(jié)點的left=父節(jié)點的left - 當前節(jié)點的右邊子葉子的總寬度- 當前節(jié)點的寬度
3)如果不存在右邊子葉子,但存在左邊子葉子,則公式為:當前節(jié)點的left=父節(jié)點的left - 當前節(jié)點的左邊子葉子的總寬度
4)如果當前節(jié)點本身就是葉子,則公式為:當前節(jié)點的left=父節(jié)點的left - 當前節(jié)點的寬度
(3)當前節(jié)點是父節(jié)點的右邊子節(jié)點
1)判斷的條件是: 當前對象父節(jié)點的名稱='iNextNo'
2)如果存在左邊子葉子,則公式為:
當前節(jié)點的left=父節(jié)點的left 當前節(jié)點的左邊子葉子的總寬度 當前節(jié)點的寬度
3)如果不存在左邊子葉子,但存在右邊子葉子,則公式為:
當前節(jié)點的left=父節(jié)點的left 當前節(jié)點的右邊子葉子的總寬度
4)如果當前節(jié)點本身就是葉子,則公式為:
當前節(jié)點的left=父節(jié)點的left 當前節(jié)點的寬度
(2)和(3)的公式都是得到當前節(jié)點的left,我們還需要得到當前節(jié)點的top很簡單的公式:當前節(jié)點的top=父節(jié)點的top 偏移量(80)
二叉樹思路(3)
連接線條的定位思路:
(1)找到當前節(jié)點和父節(jié)點的位置
(2)判斷當前節(jié)點是父節(jié)點的左邊子節(jié)點,還是右邊子節(jié)點
(3)畫線條
這里定義了一些變量。
objOval //當前節(jié)點,是一個object
objParentOval //當前對象的父節(jié)點,是一個object
objLine //當前線條,是一個object
線條的定位公式:
from="x1,y1" to="x2,y2" 是 VML 里定位線條的方式
當前節(jié)點是父節(jié)點的左邊子節(jié)點,則公式為:
from = 父節(jié)點的left 偏移量(15) , 父節(jié)點的top 偏移量(32)
to = 父節(jié)點的left 偏移量(30) , 父節(jié)點的top - 偏移量(2)
當前節(jié)點是父節(jié)點的右邊子節(jié)點,則公式為:
from = 父節(jié)點的left 偏移量(35) ,父節(jié)點的top 偏移量(32)
to = 父節(jié)點的left 偏移量(20) ,父節(jié)點的top - 偏移量(2)
我所能想到的也就這么多了。
如果只是單純的做一個公司結(jié)構(gòu)圖的話,會更簡單很多。下面是賽揚的思路,我也是在他的基礎(chǔ)上深入一點而已。
首先計算最下層節(jié)點個數(shù),得出寬度,然后應(yīng)該根據(jù)節(jié)點的從屬關(guān)系計算其上層節(jié)點位置,遞歸。
每一層級的節(jié)點要按從屬關(guān)系先排序首先設(shè)“基本值”=節(jié)點應(yīng)向右偏移量每個包含子節(jié)點的節(jié)點的left值等于它所擁有的節(jié)點所占寬度的一半加上基本值
后話:
最近不知為何,網(wǎng)絡(luò)一直都不好。斷線的時間比在線的時間多。所以沒對代碼簡化,其實,要完善的功能還有很多,比如:需要加右鍵菜單
右鍵菜單內(nèi)含新建節(jié)點、修改節(jié)點名稱、改變關(guān)聯(lián)關(guān)系等
在每一個節(jié)點上都可右鍵打開這個節(jié)點的右鍵菜單
講解:
1)flow2.xml 是數(shù)據(jù)文件,相信大家都不會有問題。
2)flow2.xsl 是格式文件,有幾個地方要注意。
(1)腳本中:
(1) <xsl:value-of select="./iProcess/text()" /> ;
(2) { ./iProcess/text()}
(1)和(2)的作用都是返回由 select 參數(shù)給出的表達式的字符串值。他們的搜索條件相同,所以返回的值也一樣。只不過是使用的場合不同,他們的書寫形式也就不一樣。
<xsl:apply-templates select="team" order-by="blue_ID"/>
比如我們想生成以下代碼
<div 名稱=“參數(shù)值”>內(nèi)容</div>
我們假設(shè)名稱為“name”,參數(shù)值為XML數(shù)據(jù)中當前節(jié)點下面的子節(jié)點book的值
第一種寫法是先加屬性名稱,再加參數(shù)值
| 以下為引用的內(nèi)容: <div> |
內(nèi)容
</div>
第二種寫法是直接加屬性名稱和參數(shù)值
<div name="{ ./book/text()}">內(nèi)容</div>
具體的使用你可以看我寫的代碼中的例子。
XSL在正式的 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 的標準里
<xsl:value-of select="./book/text()"/>
作用是:只是把他的文本值寫出來,而
<xsl:value-of select="./book"/>
是把他的文本值和他的所有子節(jié)點的內(nèi)容顯示出來。
大家可以試驗一下,輸出一個有子節(jié)點的,一個無子節(jié)點的看看顯示的結(jié)果是否相同。
(2)需要注意:
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 的開發(fā)環(huán)境學(xué)習(xí) XML 的最佳途經(jīng)是從簡單的開發(fā)入手,大膽實踐,循序漸進。XML 的妙處只有在開發(fā)過程中才能深入體會,離開了開發(fā)是學(xué)不好 XML 的。因此學(xué)習(xí) XML 首先應(yīng)該建立一個 XML 的開發(fā)環(huán)境。我給大家
- 相關(guān)鏈接:
- 教程說明:
Xml教程-XML卷之實戰(zhàn)錦囊(5):結(jié)構(gòu)樹圖
。