日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

XML卷之實(shí)戰(zhàn)錦囊(5):結(jié)構(gòu)樹圖_Xml教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:采用XML數(shù)據(jù)來填充ASP表單
在本篇文章里,我們會(huì)使用一個(gè)簡單的Web表單,它會(huì)列出某個(gè)目錄下的一些XML文件。然后,我們會(huì)從這個(gè)目錄里選擇一個(gè)文件,將它發(fā)送到另一個(gè)Web表單里,后 者會(huì)使用被選中的XML文件來填充某些

最初想起做二叉樹是因?yàn)樾枰鲆粋(gè)公司結(jié)構(gòu)圖。 以前的做法都是直接用圖象軟件畫出來一個(gè)圖片。很好看,但每次有變動(dòng)后都需要重新畫一個(gè)新的。 另一方面,網(wǎng)頁上對(duì)線條的顯示、布局相當(dāng)局限。根據(jù)動(dòng)態(tài)生成的數(shù)據(jù)進(jìn)行排版、定位都相當(dāng)困難, 而且在美觀上也差強(qiáng)人意。 做了各種嘗試以后,決定用XML XSL作數(shù)據(jù)運(yùn)算; 用VML來美化線條,用JAVASCRIPT來給對(duì)象定位。

材料:

XML卷之結(jié)構(gòu)樹圖

有2個(gè)文件: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的基本格式,我就不詳細(xì)講解了。

XML是樹型結(jié)構(gòu),我們讀取每個(gè)數(shù)據(jù)就需要對(duì)這個(gè)XML數(shù)據(jù)樹進(jìn)行遍歷。而遞歸運(yùn)算是XSL優(yōu)勢(shì)之一。我也是在用其它多種方法進(jìn)行遍歷運(yùn)算失敗后才決定使用XSL的。

以下為引用的內(nèi)容:

<FlowRoot>
<vcTitle>二叉樹--結(jié)構(gòu)圖</vcTitle>
<Author>Sailflying</Author>
<Email>[email protected]</Email>
<FlowNode>
<iProcess>1</iProcess>
<vcCourse>第一個(gè)節(jié)點(diǎn)</vcCourse>
<iNextYes>
<FlowNode>
<iProcess>2</iProcess>
<vcCourse>第二個(gè)節(jié)點(diǎn)</vcCourse>
<iNextYes>…</iNextYes>
<iNextNo>…</iNextNo>
</FlowNode>
</iNextYes>
<iNextNo>
<FlowNode>
<iProcess>3</iProcess>
<vcCourse>第三個(gè)節(jié)點(diǎn)</vcCourse>
<iNextYes>…</iNextYes>
<iNextNo>…</iNextNo>
</FlowNode>
</iNextNo>
</FlowNode>
</FlowRoot>

邏輯上很簡單,當(dāng)前節(jié)點(diǎn)(1)下面有兩個(gè)子節(jié)點(diǎn)(2,3)。只需要將節(jié)點(diǎn)2和節(jié)點(diǎn)3定位在節(jié)點(diǎn)1的左下方和右下方就可以了。這里我將左右節(jié)點(diǎn)的連接線分別用了綠色和紅色,方便顯示。

前面我們說到了XSL的遞歸功能,為了更清楚的看到每一個(gè)詳細(xì)的顯示步驟,只需要仿照下面的代碼,加一個(gè)alert語句就可以了。

以下為引用的內(nèi)容:

<xsl:template match="FlowNode">

<SCRIPT language="JavaScript1.2">

alert('逐步顯示');

</SCRIPT>

</xsl:template>

看了上面的慢動(dòng)作,是否能讓大家了解到我的思路。

二叉樹思路(2)

我的思路很簡單:

(1)讀取當(dāng)前節(jié)點(diǎn)的資料,用VML生成一個(gè)新的對(duì)象。給對(duì)象賦初始數(shù)值(如 name,id,style樣式等)

(2)用腳本控制來給當(dāng)前對(duì)象定位

(3)當(dāng)前節(jié)點(diǎn)和它的父親節(jié)點(diǎn)之間加箭頭,線條。

(4)繼續(xù)找當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn),一直循環(huán)定位到結(jié)束。

也就是所有節(jié)點(diǎn)都遍歷完畢,已經(jīng)生成好了樹。

以下為引用的內(nèi)容:

<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>

整個(gè)遞歸過程就是靠上面這三個(gè)模塊(template)來完成的。第一個(gè)template在匹配當(dāng)前節(jié)點(diǎn)中每一個(gè)子節(jié)點(diǎn)的模板的時(shí)候調(diào)用了后面兩個(gè)template; 而后面兩個(gè)template又在具體執(zhí)行的時(shí)候調(diào)用了第一個(gè)template ,這就相當(dāng)于一個(gè)遞歸函數(shù)。

語法:

要依次匹配當(dāng)前節(jié)點(diǎn)中的每個(gè)子節(jié)點(diǎn)的模板,應(yīng)使用該元素的基本形式 <xsl:apply-templates />。否則,匹配的節(jié)點(diǎn)由 select 參數(shù)中 XPath 表達(dá)式的值決定,如 <xsl:apply-templates select="./FlowNode" />

(1)和(2)的作用都是返回由 select 參數(shù)給出的表達(dá)式的字符串值。他們的搜索條件相同,所以返回的值也一樣。只不過是使用的場合不同,他們的書寫形式也就不一樣。

(1) <xsl:value-of select="./iProcess/text()" />

(2) { ./iProcess/text()}

這里定義了一些變量,節(jié)點(diǎn)的定位就是根據(jù)這些變量來調(diào)用運(yùn)算公式的。

以下為引用的內(nèi)容:

root_left //根的左邊距=所有葉子的分配寬度(y*10) 所有葉子的寬度(y*50) 左邊距基本值(10)
root_top //根的上邊距=上邊距基本值(10)
objOval //當(dāng)前對(duì)象,是一個(gè)object
objOval_iProcess //當(dāng)前對(duì)象的步驟值
objParentOval //當(dāng)前對(duì)象的父節(jié)點(diǎn),是一個(gè)object
objParentOval_iProcess //當(dāng)前對(duì)象父節(jié)點(diǎn)的步驟值
objParent_name //當(dāng)前對(duì)象父節(jié)點(diǎn)的名稱
Leaf_left //當(dāng)前對(duì)象的所有子節(jié)點(diǎn)中的左邊葉子數(shù)
Leaf_right //當(dāng)前對(duì)象的所有子節(jié)點(diǎn)中的右邊葉子數(shù)
Leaf_sum //當(dāng)前對(duì)象的所有子節(jié)點(diǎn)中葉子數(shù)

葉子:是指當(dāng)前節(jié)點(diǎn)沒有子節(jié)點(diǎn)

節(jié)點(diǎn)的定位公式:

(1) 當(dāng)前節(jié)點(diǎn)是根節(jié)點(diǎn)

以下為引用的內(nèi)容:

//根的位置
SobjOval.style.left=parseInt(root_left);
SobjOval.style.top=parseInt(root_top);
//parseInt() 函數(shù)的作用是取整數(shù)值,如果不是則為NAN
//isNaN()函數(shù)的作用是判斷parseInt取得的是否為整數(shù)

(2)當(dāng)前節(jié)點(diǎn)是父節(jié)點(diǎn)的左邊子節(jié)點(diǎn)

1)判斷的條件是:當(dāng)前對(duì)象父節(jié)點(diǎn)的名稱='iNextYes'

2)如果存在右邊子葉子,則公式為:當(dāng)前節(jié)點(diǎn)的left=父節(jié)點(diǎn)的left - 當(dāng)前節(jié)點(diǎn)的右邊子葉子的總寬度- 當(dāng)前節(jié)點(diǎn)的寬度

3)如果不存在右邊子葉子,但存在左邊子葉子,則公式為:當(dāng)前節(jié)點(diǎn)的left=父節(jié)點(diǎn)的left - 當(dāng)前節(jié)點(diǎn)的左邊子葉子的總寬度

4)如果當(dāng)前節(jié)點(diǎn)本身就是葉子,則公式為:當(dāng)前節(jié)點(diǎn)的left=父節(jié)點(diǎn)的left - 當(dāng)前節(jié)點(diǎn)的寬度

(3)當(dāng)前節(jié)點(diǎn)是父節(jié)點(diǎn)的右邊子節(jié)點(diǎn)

1)判斷的條件是: 當(dāng)前對(duì)象父節(jié)點(diǎn)的名稱='iNextNo'

2)如果存在左邊子葉子,則公式為:

當(dāng)前節(jié)點(diǎn)的left=父節(jié)點(diǎn)的left 當(dāng)前節(jié)點(diǎn)的左邊子葉子的總寬度 當(dāng)前節(jié)點(diǎn)的寬度

3)如果不存在左邊子葉子,但存在右邊子葉子,則公式為:

當(dāng)前節(jié)點(diǎn)的left=父節(jié)點(diǎn)的left 當(dāng)前節(jié)點(diǎn)的右邊子葉子的總寬度

4)如果當(dāng)前節(jié)點(diǎn)本身就是葉子,則公式為:

當(dāng)前節(jié)點(diǎn)的left=父節(jié)點(diǎn)的left 當(dāng)前節(jié)點(diǎn)的寬度

(2)和(3)的公式都是得到當(dāng)前節(jié)點(diǎn)的left,我們還需要得到當(dāng)前節(jié)點(diǎn)的top很簡單的公式:當(dāng)前節(jié)點(diǎn)的top=父節(jié)點(diǎn)的top 偏移量(80)

二叉樹思路(3)

連接線條的定位思路:

(1)找到當(dāng)前節(jié)點(diǎn)和父節(jié)點(diǎn)的位置

(2)判斷當(dāng)前節(jié)點(diǎn)是父節(jié)點(diǎn)的左邊子節(jié)點(diǎn),還是右邊子節(jié)點(diǎn)

(3)畫線條

這里定義了一些變量。

objOval //當(dāng)前節(jié)點(diǎn),是一個(gè)object

objParentOval //當(dāng)前對(duì)象的父節(jié)點(diǎn),是一個(gè)object

objLine //當(dāng)前線條,是一個(gè)object

線條的定位公式:

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

當(dāng)前節(jié)點(diǎn)是父節(jié)點(diǎn)的左邊子節(jié)點(diǎn),則公式為:

from = 父節(jié)點(diǎn)的left 偏移量(15) , 父節(jié)點(diǎn)的top 偏移量(32)

to = 父節(jié)點(diǎn)的left 偏移量(30) , 父節(jié)點(diǎn)的top - 偏移量(2)

當(dāng)前節(jié)點(diǎn)是父節(jié)點(diǎn)的右邊子節(jié)點(diǎn),則公式為:

from = 父節(jié)點(diǎn)的left 偏移量(35) ,父節(jié)點(diǎn)的top 偏移量(32)

to = 父節(jié)點(diǎn)的left 偏移量(20) ,父節(jié)點(diǎn)的top - 偏移量(2)

我所能想到的也就這么多了。

如果只是單純的做一個(gè)公司結(jié)構(gòu)圖的話,會(huì)更簡單很多。下面是賽揚(yáng)的思路,我也是在他的基礎(chǔ)上深入一點(diǎn)而已。

首先計(jì)算最下層節(jié)點(diǎn)個(gè)數(shù),得出寬度,然后應(yīng)該根據(jù)節(jié)點(diǎn)的從屬關(guān)系計(jì)算其上層節(jié)點(diǎn)位置,遞歸。

每一層級(jí)的節(jié)點(diǎn)要按從屬關(guān)系先排序首先設(shè)“基本值”=節(jié)點(diǎn)應(yīng)向右偏移量每個(gè)包含子節(jié)點(diǎn)的節(jié)點(diǎn)的left值等于它所擁有的節(jié)點(diǎn)所占寬度的一半加上基本值

后話:

最近不知為何,網(wǎng)絡(luò)一直都不好。斷線的時(shí)間比在線的時(shí)間多。所以沒對(duì)代碼簡化,其實(shí),要完善的功能還有很多,比如:需要加右鍵菜單

右鍵菜單內(nèi)含新建節(jié)點(diǎn)、修改節(jié)點(diǎn)名稱、改變關(guān)聯(lián)關(guān)系等

在每一個(gè)節(jié)點(diǎn)上都可右鍵打開這個(gè)節(jié)點(diǎn)的右鍵菜單

講解:

1)flow2.xml 是數(shù)據(jù)文件,相信大家都不會(huì)有問題。

2)flow2.xsl 是格式文件,有幾個(gè)地方要注意。

(1)腳本中:

(1) <xsl:value-of select="./iProcess/text()" /> ;

(2) { ./iProcess/text()}

(1)和(2)的作用都是返回由 select 參數(shù)給出的表達(dá)式的字符串值。他們的搜索條件相同,所以返回的值也一樣。只不過是使用的場合不同,他們的書寫形式也就不一樣。

<xsl:apply-templates select="team" order-by="blue_ID"/>

比如我們想生成以下代碼

<div 名稱=“參數(shù)值”>內(nèi)容</div>

我們假設(shè)名稱為“name”,參數(shù)值為XML數(shù)據(jù)中當(dāng)前節(jié)點(diǎn)下面的子節(jié)點(diǎn)book的值

第一種寫法是先加屬性名稱,再加參數(shù)值

以下為引用的內(nèi)容:

<div>
<xsl:attribute name="name">
<xsl:value-of select="./book/text()"/> </xsl:attribute>

內(nèi)容

</div>

第二種寫法是直接加屬性名稱和參數(shù)值

<div name="{ ./book/text()}">內(nèi)容</div>

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

XSL在正式的 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 的標(biāo)準(zhǔn)里

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

作用是:只是把他的文本值寫出來,而

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

是把他的文本值和他的所有子節(jié)點(diǎn)的內(nèi)容顯示出來。

大家可以試驗(yàn)一下,輸出一個(gè)有子節(jié)點(diǎn)的,一個(gè)無子節(jié)點(diǎn)的看看顯示的結(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" ?>

另外說一點(diǎn):

在大多的XML教科書中所顯示的代碼中很少會(huì)加上encoding="gb2312" ,因此我們?cè)赬ML中用到中文的時(shí)候會(huì)報(bào)錯(cuò),原因就是沒有寫這個(gè)申明。

分享:如何建立一個(gè) XML 的開發(fā)環(huán)境
學(xué)習(xí) XML 的最佳途經(jīng)是從簡單的開發(fā)入手,大膽實(shí)踐,循序漸進(jìn)。XML 的妙處只有在開發(fā)過程中才能深入體會(huì),離開了開發(fā)是學(xué)不好 XML 的。因此學(xué)習(xí) XML 首先應(yīng)該建立一個(gè) XML 的開發(fā)環(huán)境。我給大家

來源:模板無憂//所屬分類:Xml教程/更新時(shí)間:2008-08-22
相關(guān)Xml教程