麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發 > XML > 正文

用XML數據島解決用戶界面問題

2024-09-05 20:46:55
字體:
來源:轉載
供稿:網友

從屬列表問題(dependent list problem)"的問題時常被提出。問題時常出現于當你有兩個以上的選擇列表時,一個主列表有若干個選項,你希望當用戶選擇主列表中的某個選項時,在其他的從屬列表中顯示相關的選項。你可以通過eXtensible Markup Language(XML)的數據島(data islands)來實現這一功能,把XML內嵌到你的HTML中。這一結果對在客戶端的XML應用具有實踐意義。

假設你為一家名為"CheapPc"的公司工作,你負責讓訪問公司網站的用戶找到用戶所在州的"CheapPc"商店。在公司網站上你列出了州名的列表。當一個顧客在主列表中點擊選擇一個州時,你希望在從屬列表中顯示相關的商店列表。

問題在于:你怎樣填充從屬列表而不用刷新該頁面或不用每次用戶在主列表中選擇時都向服務器發送消息?XML數據島完美地解決這一問題。當用戶發出請求,所有商店的數據都連接成一個XML字符串(Listing 1)。返回的結果是一個鑲嵌在HTML頁面中的數據島。該數據島使用以下XML結構:

根元素包含州名的列表,每個州名的列表依次包含商店的列表。每個商店都有一個相應的ID和城市名。為了生成這一XML字符串,你得用ActiveX Data Object(ADO)查詢數據庫,并用XML標記符格式化查詢結果。把記錄集數據格式化成HTML表格和把記錄集數據格式化成XM文件之間有一些不同。在本文的后半部分,我將向你展示如何避免過多的串聯工作以提高響應時間。你可以點擊這里下載例程。

把處理過程移到客戶端

當Web服務器返回網頁后,所有進一步的操作處理都在客戶端進行。我原先認為如果向客戶端發送一個大的數據ji hui使程序的速度放慢。但后來我卻發現一次性發送所有數據比在客戶與服務器之間來回地進行數據交換快得多。唯一可被注意到的停頓只是在IE5的XML解析器讀取數據時的一個短暫的初始化停頓。

HTML文件本身包含有4個元素:一個保存州名數據的選擇列表(主列表),XML數據,一個從屬列表的div標記占位符,和兩個腳本。當州名選擇列表的選項發生變化時,第二個腳本就執行(Listing 2)。

你希望每次用戶選擇一個州時都能從數據島重新得到相應的商店列表。所以你需要一個腳本去處理州名選擇列表的onChange事件:

在這個腳本中重新得到了州名選擇列表的值:

Dim stateCode
        stateCode=document.all.State.value

接著重新得到所選定州的商店列表。你可以通過兩個方法得到這個列表。第一個辦法就是獲得<XML>標記符的記錄集屬性的引用:

Dim R
        Set R = xmldata.recordset

通過這個方法得到的記錄集是一個標準的ADO記錄集對象,字段名都與標記符相對應。這個方法只有在每個記錄都有同樣的字段的"簡單"XML數據文件中才能很好地工作。

第二個方法就比較強大和普遍。IE5把XML數據島象其他HTML元素一樣對待。為了在客戶端訪問XML數據,你只需通過ID來引用該元素。IE5將返回XML樹的根元素(document元素):

set xml = document.all("xmldata")

你用這個document元素可以執行Extensible Stylesheet Language (XSL)查詢語句。使用XSL查詢語句,你可以得到某個給定層次上的節點列表,包含指定屬性的節點列表,或以上兩者的任意組合。例如,以下的查詢語句返回所有符合用戶所選州的商店節點:

Dim nodes
        set nodes = xml.selectNodes ("locations/state[@code='" & stateCode & "']/store")

XSL搜索字符串看起來很象一個文件路徑;它有XML樹相應各層次的值。用"/"分隔每個層次。以"節點=數值"的匹配方式加到相關節點的"[]"中搜索指定數值的節點,在屬性名前加上"@"來搜索包含指定屬性的節點。運行selectNodes方法將返回一個IXMLDOMNodes集合對象。最后,顯示從屬列表。最簡單的方法:根據XSL查詢語句返回的節點列表來改變從屬列表的標記符的值:

set aList = document.all("cities")
        aList.options.length = 0

  i = 0

  For Each N In nodes

   anID = N.selectSingleNode("id").text

   aCity = N.selectSingleNode _("city").text

   aList.options.length = _aList.options.length + 1

   aList.options(i).id = anID

   aList.options(i).value = aCity

   aList.options(i).innerText = aCity

   i = i + 1

  Next

現在你知道了如何利用XML數據島來解決從屬列表問題。注意:這一技巧不適合于大規模的數據-如那些成千上萬的記錄-但如果那樣的話,那主要還是一個如何顯示的問題,而非技術上的問題。如果你發現一個查詢語句可能返回不適合的大組記錄,你即可以限制返回記錄的數目(例如為用戶提供一個"More Record"按鈕),又可以修改用戶界面使用戶可以點擊下一層次的內容,因此而限制了用戶必須選擇的記錄數目。

把數據庫的表數據保存到文件中

我曾答應向你展示如何避免每次請求都要讀取數據庫和串聯成XML字符串的步驟。答案就是把數據庫的表數據保存到文件中;這樣做有幾個好處。讀取文件比查詢數據庫并把記錄集格式化成XML要快。這樣做也可以簡化你的HTML文件,因為你只需在HTML中包含對XML的引用。最后這樣做使數據對于客戶端來說是透明的。如果你以Listing 1中的方式發送XML標記符的話,用戶可以通過IE的"查看/源文件"看到數據。使用文件引用的話,用戶只能看到引用標記符,而非數據。

只要你的數據庫記錄不是永不改變的,你就還得在數據改變時查詢數據庫。例如,你可以在sql server中寫一個觸發器,當"Location"表發生改變時更新"LastChanged"表中的日期和時間(Listing 3)。對于每一次請求,你可以比較Location"表與保存數據的XML文件的日期和時間。本文使用的Access數據庫不支持觸發器,但你可以編寫代碼來實現當"Location"表發生改變時更新"LastChanged"表的功能。你也可以每隔一段時間,如一天或一個小時就重新生成文件。

用Scripting.FileSystemObject 和 Scripting.TextStream對象寫XML文件到硬盤中。為了能寫XML文件,你必須給IUSR_MacHINENAME匿名用帳戶足夠的權限以打開、讀、寫和刪除文件(如果你使用的是NTFS格式的分區硬盤的話)。如果你只想利用XML數據重新在客戶端建立一個記錄集的話,你可以用adPersistXML方法保存記錄集到硬盤中。如果你這樣做的話,必須注意ADO為了能從XML數據重新建立記錄集而把記錄集保存成優化的格式。這樣生成的XML對于XSL查詢語句而言即不美觀又不方便:

Dim fs

  Dim ts

  dim aFilename

  aFilename = Server.MapPath _("/XMLDataIslands") & _"/locations.xml"

  set fs = Server.CreateObject _("Scripting.FileSystemObject")

  set ts = fs.OpenTextFile _(aFilename, ForWriting)

  ts.Write s

現在,當你收到一個請求時,查看"LastChanged"表中日期和時間:

  Dim SQL

  Dim R

  Dim conn

  dim tableModifyDate

  set conn = Server.CreateObject _("ADODB.Connection")

  conn.mode = adModeRead

  conn.open "DSN=CheapPC;UID=sa;PWD="

  SQL = "SELECT " & _"LastChanged.LastChanged " & _"FROM Locations WHERE " & _"Tablename='Locations'"

  set R = conn.execute(SQL,,adCmdText)

  tableModifyDate = R("LastChanged")

接下來,通過獲取一個File對象來比較XML文件與tableModifyDate的日期和時間,并查看它的FileCreatedOn屬性值:

  dim fs

  dim aFile

  dim rewriteFile

  rewriteFile=False

  set fs = Server.CreateObject _("Scripting.FileSystemObject")

  if fs.FileExists(aFilename) then

    Set aFile = fs.GetFile(aFilename)

    If aFile.DateCreated < _LocationsModifiedDate Then

     rewriteFile=True

    end if

  else

    rewriteFile=true

  end if

如果XML文件不存在或需要更新時,你必須寫文件(Listing 4)。這樣就重新從數據庫讀取數據并格式化成XML,但你只需覆蓋舊的XML文件而不必把XML發送到瀏覽器。現在在你的HTML文件中,你只需引用該XML文件即可。當你的XML文件不需要更新,你的服務器會略過數據的讀取與格式化,只是簡單地讀取XML數據到瀏覽器。從整體上看,讀取XML數據為你的服務器節省了大量的處理能力,使你的頁面更有效率。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久草在线资源观看 | 欧美人xx | 一级一级一级毛片 | 日本在线视频二区 | 日韩精品久久久久久久九岛 | 精品国产91久久久久久浪潮蜜月 | 国产成人精品免费视频大全最热 | 亚洲午夜电影 | 精品国产一区二区三区四区在线 | 成人免费一区二区三区视频网站 | 欧美成人精品欧美一级 | 久久久久北条麻妃免费看 | 韩国精品视频在线观看 | 国产精品美女久久久久久不卡 | 日本一区视频在线观看 | 一级毛片大片 | 色悠悠久久久久 | 中文欧美日韩 | 99精品视频99 | 国产精品视频一区二区三区四区国 | 爱福利视频网 | 懂色av懂色aⅴ精彩av | 午夜a狂野欧美一区二区 | 日本搞逼视频 | 日日碰日日操 | 中文在线观看视频 | 免费看日产一区二区三区 | 啊~用cao嗯力cao烂我视频 | 国产精品成人免费一区久久羞羞 | 久久久久一区二区三区四区五区 | 国产免费黄网 | 久久婷婷一区二区三区 | 欧美成人一级片 | 91精品老司机 | 91丝袜| 精品国产乱码久久久久久久 | 99国产精成人午夜视频一区二区 | 免费看成人av | 特片网久久| 精品国产一区二 | 亚洲va久久久噜噜噜久牛牛影视 |