Firefox 1.5 中的 XML,第 3 部分: 利用 JavaScript 處理 Firefox 中的 XML

來源:互聯網
上載者:User

瞭解了 XML 在 Firefox 瀏覽器中的基本顯示和樣式後,下一個要關注的功能就是指令碼。本文中,我將展示利用 JavaScript 代碼處理 XML 這一基本概念。本文包含的所有程式碼範例和螢幕都是在 Ubuntu Linux 系統中使用 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 之後的瀏覽器顯示
 

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

圖2. 載入清單 2 並單擊連結之後的瀏覽器顯示
 

對 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 的瀏覽器顯示
 



回頁首

調用 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 處理。可以將學過的各種指令碼編製技術,例如動態超文字標記語言(DHTML),應用到 XML 處理中。ECMAScript for XML (E4X) 是一組對 JavaScript 的語言增強(從技術上講,是 ECMAScript),使 JavaScript 的 XML 處理更容易。這個新標準為 XML 處理添加了專門的用法。Firefox 1.5 支援 E4X,我將在以後的文章中對它進行介紹。不用犧牲 XML 的強大的結構特性,適度和精心設計的指令碼可以展現現代 Web 應用程式的全部魅力。

參考資料

學習

  • 您可以參閱本文在 developerWorks 全球網站上的 英文原文。

  • Firefox 1.5 中的 XML,第 1 部分: XML 屬性概述(2005 年 9月)和 Firefox 1.5 中的 XML,第 2 部分: 基本 XML 處理(2006 年 3 月):回顧該 developWorks 系列的前兩篇文章。
  • 瞭解 CSS 和使用 CSS 顯示 XML 的基本概念。查看這些教程:
    • 階層式樣式表顯示 XML:使用階層式樣式表顯示 XML,第 1 部分:在 網頁瀏覽器中顯示 XML 的基本技術(2004 年 11 月)。
    • 然後是 階層式樣式表顯示 XML:使用階層式樣式表顯示 XML,第 2 部分:在 網頁瀏覽器中顯示 XML 進階技術(2005 年 2 月)介紹在瀏覽器中使用 CSS 修飾 XML 的進階主題,包括指令碼技術的討論。
    • 如果您熟悉 XSLT,可以直接查看 階層式樣式表顯示 XML:使用階層式樣式表顯示 XML,第 3 部分:XSLT 與 CSS 結合處理 XML(2005 年 6 月)討論對 XML 摘要應用 XSLT,包括使用 XSLT 技術處理 CSS 獲得 HTML 或 XML 輸出。

  • JavaScript 和 DOM:將這些方便的 Mozilla 參考資料添加為書籤。
  • Javascript MIME 類型:通過 Anne van Kesteren 的文章瞭解選擇 JavaScript 媒介類型的複雜性。
  • IBM XML 1.1 認證: 瞭解如何才能成為一名 IBM 認證的 XML 1.1 和相關技術的開發人員。
  • XML:訪問 developerWorks XML 專區,獲得廣泛的技術文章和技巧、教程、標準和 IBM 紅皮書。
  • developerWorks 技術活動和網路廣播:隨時關注技術的最新進展。

獲得產品和技術

  • Firefox:獲得基於 Mozilla 的 網頁瀏覽器,該瀏覽器提供標準遵從性、高效能和安全性,以及穩定的 XML 屬性。目前的版本為 1.5.0.4。

討論

  • XML 專區討論論壇:參與和 XML 相關的討論。

關於作者

Uche Ogbuji 是 Fourthought Inc. 的顧問和創立者之一,這是一家專門從事企業知識管理 XML 解決方案的軟體供應商和諮詢公司。Fourthought 開發了 4Suite,這是一個用於 XML、RDF 和知識管理應用程式的開放源碼平台。Ogbuji 先生還是 Versa RDF 查詢語言的主要開發人員。他是一位出生在尼日利亞的電腦工程師和作家,目前在美國科羅拉多州博耳得定居和工作。您可以通過他的 Weblog Copia 進一步瞭解 Ogbuji 先生。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.