DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> Firefox 1.5 中的 XML,第 3 部分: 利用 JavaScript 處理 Firefox 中的 XML
Firefox 1.5 中的 XML,第 3 部分: 利用 JavaScript 處理 Firefox 中的 XML
編輯:XML詳解     

這是 “Firefox 1.5 中的 XML” 系列中的第三篇文章,您將學習在 Mozilla Firefox 中使用 JavaScript 實現處理 XML。在前兩篇文章 Firefox 1.5 中的 XML,第 1 部分:XML 特性概述 和 Firefox 1.5 中的 XML,第 2 部分:基本 XML 處理 中,我們了解了 Mozilla Firefox 中各種與 XML 相關的工具,以及 XML 解析的基本概念、級聯樣式表(CSS)和 XSLT 樣式表調用。

  了解了 XML 在 Firefox 浏覽器中的基本顯示和樣式後,下一個要關注的功能就是腳本。本文中,我將展示利用 JavaScript 代碼處理 XML 這一基本概念。本文包含的所有代碼示例和屏幕截圖都是在 UbuntuLinux® 系統中使用 Firefox 1.5.0.4 創建和測試的,配置文件沒有修改過(即沒有擴展,保留了安裝時的默認選項)。如果要編寫用於 XML 處理的跨浏覽器代碼,可能必須使用其他的浏覽器嗅探技術,但是,我沒有在本文介紹這些技術。

  加載 XML 文件

  您可以使用 Web 頁面內嵌的 JavaScript 代碼加載 XML 文檔。我將從一個 Html Web 頁面示例入手,該頁面加載一個簡單的 XML 郵件列表格式用於動態更新,要加載的 XML 文檔如 清單 1 所示(labels.XML)。


清單 1.(labels.xml)地址標簽 XML

  <?XML version="1.0" encoding="iso-8859-1"?> 
<labels> 
 <label id='ep' added="2003-06-10"> 
  <name>Ezra Pound</name> 
  <address> 
   <street>45 Usura Place</street> 
   <city>Hailey</city> 
   <province>ID</province> 
  </address> 
 </label> 
 <label id='tse' added="2003-06-20"> 
  <name>Thomas Eliot</name> 
  <address> 
   <street>3 Prufrock Lane</street> 
   <city>Stamford</city> 
   <province>CT</province> 
  </address> 
 </label> 
 <label id="lh" added="2004-11-01"> 
  <name>Langston Hughes</name> 
  <address> 
   <street>10 Bridge Tunnel</street> 
   <city>Harlem</city> 
   <province>NY</province> 
  </address> 
 </label> 
 <label id="co" added="2004-11-15"> 
  <name>Christopher Okigbo</name> 
  <address> 
   <street>7 Heaven's Gate</street> 
   <city>Idoto</city> 
   <province>Anambra</province> 
  </address> 
 </label> 
</labels> 

 

 清單 2 是僅包括一個鏈接的 Html 頁面,鏈接顯示 “Click here to load addresses”。單擊鏈接,地址標簽的信息被添加到頁面中。


清單 2. Html 頁面利用 JavaScript 加載 XML 用於動態更新

  <!DOCTYPE html PUBLIC "-//W3C//DTD Html 4.01//EN" 
 "http://www.w3.org/TR/Html4/strict.dtd"> 
<Html> 
 <head> 
  <meta content="text/Html; charset=iso-8859-1" http-equiv="Content-Type"> 
  <title>Address book</title> 
  <script type="application/Javascript"> 
var ELEMENT_NODE = 1 
//TEXT_NODE 
 
function loadAddresses() 
{ 
 XMLDoc = document.implementation.createDocument("", "", null); 
 XMLDoc.onload = writeList; 
 xmlDoc.load("labels.XML"); 
} 
 
function writeList() 
{ 
 var labels = XMLDoc.getElementsByTagName('label'); 
 var ol = document.createElement('OL'); 
 
 for (i=0; i < labels.length; i++) 
 { 
  var li = document.createElement('LI'); 
  for (j=0; j < labels[i].childNodes.length; j++) 
  { 
   if (labels[i].childNodes[j].nodeType != ELEMENT_NODE) continue; 
   var cdata = document.createTextNode( 
    labels[i].childNodes[j].firstChild.nodeValue); 
   li.appendChild(cdata); 
  } 
  var labelId = document.createTextNode('(' + 
   labels[i].getAttribute('id') + ')'); 
  li.appendChild(labelId); 
  ol.appendChild(li); 
 } 
 document.getElementById('updateTarget').appendChild(ol); 
} 
  </script> 
 </head> 
 <body id='updateTarget'> 
  <p> 
   <a href="Javascript:loadAddresses()">Click here to load addresses</a> 
  </p> 
 </body> 
</Html> 


script 元素體現動態特性,定義一個 JavaScript 函數 loadAddresses,這個函數將被 HTML 中的鏈接調用。該函數創建一個空文檔實例,然後使用 load 函數讀入 清單 1(labels.xml)。load 函數是異步執行的,因此,在 XML 文檔讀入的同時,腳本可跳到下一行執行,使您能夠在 XML 加載開始後就使用一個觸發函數開始運行。因此,我為一個獨立的函數 writeList 設置 onload 屬性。該函數使用方便的文檔對象模型(Document Object Model, DOM)的 getElementsByTagName 方法遍歷標簽。如果 XML 文檔使用名稱空間,那麼要使用 getElementsByTagNameNS 表單而不是上面的方法,並將名稱空間指定為第一個參數。在下一節中,您將會看到一個這樣的例子。在 清單 2 中,只使用 DOM 的基本層(叫做 DOM Level 1)進行 XML 處理。對於支持名稱空間的應用程序,需要使用 DOM Level 2,它擴展了許多 Level 1 方法,可以支持名稱空間。清單 2 創建了一個表示有序列表的子樹,將 HTML 主文檔作為工廠(factory)來創建節點。這樣,生成的子樹可以插入到 HTML 主文檔中。清單 2 使用普通模式讀取源 XML 樹,然後將相應的節點添加到輸出 Html 子樹中。

  對每個 label 元素執行循環語句 labels[i].childNodes,查找 name 和 address 子節點。為避免對文本節點的子節點執行操作,使用 nodeType 測試。使用 firstChild.nodeValue 方法進行訪問獲得 name 元素的子文本。對 address 元素來說,第一個子節點是空格。您不能訪問 address 的子節點的任何文本內容。使用 getAttribute 方法可以訪問 ID。將收集到的所有文本添加到列表項中。編譯完所有的列表項元素之後,使用 appendChild 方法更新包含子樹的 HTML 文檔。可以使用 updateTarget ID 標記將添加該子樹的元素(body)。當第一次在 Firefox 中加載該 Html 時,只能看到如 圖 1 所示的鏈接。

圖 1. 加載清單 2 之後的浏覽器顯示
Firefox 1.5 中的 XML,第 3 部分: 利用 JavaScript 處理 Firefox 中的 XML

  單擊鏈接,就立刻獲得最新的顯示,如 圖 2 所示。


圖2. 加載清單 2 並單擊鏈接之後的浏覽器顯示
Firefox 1.5 中的 XML,第 3 部分: 利用 JavaScript 處理 Firefox 中的 XML

  對 XML 主文檔使用腳本

  在本系列的第一部分中,我介紹了如何在 Firefox 中浏覽 XML 文件。要在這種情況下使用 Javascript,需要在腳本文件中嵌套一個引用。清單 3(designers.xml)顯示的示例 XML 文件是一個設計師列表。XML 引用獨立的 CSS 文件來顯示 XML,引用獨立的 JavaScript 文件來創建鏈接元素。


清單 3.(designers.xml)表示時裝設計師鏈接的 XML 格式

  <?XML version='1.0' encoding='utf-8'?> 
<?XML-stylesheet type="text/css" href="designers.CSS"?> 
<designers> 
 <blurb> 
  <designer homepage="http://doria.co.uk">Doria Ltd.</designer> 
  of London 
 </blurb> 
 <blurb> 
  <designer homepage="http://samsara.biz">Samsara Saris</designer> 
  of Mumbai 
 </blurb> 
 <blurb> 
  <designer homepage="http://pcp.co.uk">Pikeman Camouflage, Plc.</designer> 
  of London 
 </blurb> 
 <blurb> 
  <designer homepage="http://mandalay.co.jp">Mandalay</designer> 
  of Tokyo 
 </blurb> 
 <xhtml:script XMLns:xhtml="http://www.w3.org/1999/xHtml" 
        src="designers.JS" 
        type="application/Javascript"/> 
</designers> 


樣式表處理指令提供顯示 XML 的基本指令。清單 4(designers.css)顯示 CSS。


清單 4.(designers.css)修飾清單 3 中 XML 格式基本顯示的 CSS

  * { display: inherit; } 
 
designers { display: block; } 
 
blurb { 
 margin: 1em; 
 width: 20em; 
} 
 
a { 
 display: inline; 
 text-decoration: none; 
 color: green; 
 border: thin blue solid; 
} 
 
script { display: none; } 
 

  樣式表通知浏覽器把 designers 和 blurb 作為塊區域,而忽略用於顯示的 script 元素。通過將鏈接(a 元素)和可見的提示一同顯示,可以更容易識別出鏈接。您將注意到在 XML 源文件中不存在 a 元素。因此,這裡要用到腳本。Javascript 代碼使用 XHTML 鏈接元素代替 designer 元素。XHTML 鏈接元素通過一個 XHtml 腳本元素提供,因此只要使用到 Firefox,就可以嵌入任何 XML(當然,您可能會遇到模式兼容性的問題)。Firefox 在載入的文檔中遇到腳本後就運行它們,因此要把腳本放在所有待處理的元素之後。清單 5(designers.JS)顯示了 JavaScript 代碼。


清單 5.(designers.JS)將 XML 元素從清單 3 轉換為 XHtml 鏈接的腳本

  //Save the XHtml namespace for when you need it 
var xhtmlns = "http://www.w3.org/1999/xHtml"; 
//get all elements named "blurb" in the document 
//The first "" indicates no namespace for the element we're seeking 
var blurbs = document.getElementsByTagNameNS("", "blurb"); 
//Loop over each element we found 
for (var i=0; i < blurbs.length; i++) 
{ 
  //retrIEve the blurb element from the collection 
  var blurb = blurbs[i]; 
  //Get the designer element within the blurb 
  //Assumes only one designer element per blurb 
  var designer = blurb.getElementsByTagNameNS("", "designer").item(0); 
  //In DOM the text in designer is actually a text node object child 
  //of blurb. The link title is the value of this text node 
  //Assumes the text node is normalized 
  var link_title = designer.firstChild.nodeValue; 
  //Link URL is the homepage attribute of designer, in no namespace 
  var link_url = designer.getAttributeNS("", "homepage"); 
  //Create a new XHtml namespace link element 
  var xhtml_link = document.createElementNS(xHtmlns, "a"); 
  //Create a new text node with the link title 
  var new_text_node = document.createTextNode(link_title); 
  //Set the href attribute to the link URL 
  xHtml_link.setAttributeNS("", "href", link_url); 
  //Attach the text node with the link title to the XHtml link 
  xHtml_link.appendChild(new_text_node); 
  //Replace the designer element with the new XHtml link element 
  blurb.replaceChild(xHtml_link, designer); 
} 


 因為 清單 5 中的腳本可以支持名稱空間(尤其是其中的 XHtml 名稱空間),所以我使用支持名稱空間的 DOM 方法。圖 3 顯示查看 清單 3 的結果。可以看到,浏覽器立即應用 CSS 和腳本。


圖 3. 加載清單 3 的浏覽器顯示
Firefox 1.5 中的 XML,第 3 部分: 利用 JavaScript 處理 Firefox 中的 XML 

  調用 XSLT

  使用 JavaScript 可以訪問大多數的浏覽器功能,其中包括 XSLT 引擎。清單 6 是一個執行 XSLT 轉換的腳本片段。


清單 6. 加載 XML 文檔和 XSLT 轉換並執行轉換的 JavaScript 代碼
//Create an XSLT processor instance 
var processor = new XSLTProcessor(); 
//Create an empty XML document for the XSLT transform 
var transform = document.implementation.createDocument("", "", null); 
//Load the XSLT 
transform.onload = loadTransform; 
transform.load("display.xslt"); 
 
//Triggered once the XSLT document is loaded 
function loadTransform(){ 
 //Attach the transform to the processor 
 processor.importStylesheet(transform); 
 source = document.implementation.createDocument("", "", null); 
 source.load("source.XML"); 
 source.onload = runTransform; 
} 
 
//Triggered once the source document is loaded 
function runTransform(){ 
 //Run the transform, creating a fragment output subtree that 
 //can be inserted back into the main page document object (given 
 //in the second argument) 
 var frag = processor.transformToFragment(source, document); 
 //insert the result subtree into the document, using the target element ID 
 document.getElementById('updateTarget').appendChild(frag); 
} 

  如果想創建整個輸出文檔,而不是創建插入到其他文檔的子樹,使用 transformToDocument 方法代替 transformToFragment 方法。

  結束語

  首先是一份重要的免責聲明:XML 的 Web 腳本語言還沒有完全標准化。文中涉及的很多內容並不是跨浏覽器標准化的。由於本系列主要關注 Firefox,文中沒有介紹其他浏覽器需要做的修改,但是您可以繼續了解如何修改以適合各種用戶界面。XML 甚至是 XSLT 的 JavaScript 操作都可使用跨浏覽器庫。如果不能專門針對基於 Mozila 的浏覽器進行開發,那麼可以使用跨浏覽器庫。處理 Web 腳本時,必須要考慮可訪問性。同時,要注意內容、處理和顯示的分離,避免在最後一刻才將引用嵌入到腳本中。另外,也可以保存和管理不包含這類引用的 XML,在將 XML 傳送給浏覽器之前,插入這些引用。

  現在,您已經了解如何在 Web 腳本中加載和處理一個獨立的 XML 文件,如何從 XML 主文檔中調用腳本,以及如何從腳本中調用 XSLT 處理器。因為 Javascript 支持所有浏覽器特性,因此可以使用它進行更多 XML 處理。可以將學過的各種腳本編制技術,例如動態 HTML(DHtml),應用到 XML 處理中。ECMAScript for XML (E4X) 是一組對 Javascript 的語言增強(從技術上講,是 ECMAScript),使 JavaScript 的 XML 處理更容易。這個新標准為 XML 處理添加了專門的用法。Firefox 1.5 支持 E4X,我將在以後的文章中對它進行介紹。不用犧牲 XML 的強大的結構特性,適度和精心設計的腳本可以展現現代 Web 應用程序的全部魅力。



   
 

 

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved