JavaScript 中的 XPath,第 3 部分
在我之前的兩篇文章中,我談到了 Firefox、Safari、Chrome 和 Opera 中可用的 DOM Level 3 XPath JavaScript 實現。 Internet Explorer 版本 8 還沒有實現這個功能集,但它確實對 XPath 有一些支持。與其他瀏覽器不同,Internet Explorer 的 XPath 功能可用於 XML 文檔,但不能用於 document
對象。
創建 XML 文檔
在 Internet Explorer 中創建 XML 文檔有三種基本方法。第一種是直接創建一個 XML DOM 文檔對象。 Internet Explorer 使用一個名為 MSXML 的 ActiveX 庫來實現 JavaScript 中的 XML 支持,因此您需要創建一個 ActiveXObject
實例並傳入正確的標識符。 Microsoft 建議使用以下三種之一:MSXML2.DOMDocument.6.0
, MSXML2.DOMDocument.3.0
, 和 MSXML2.DOMDocument
.當然,沒有辦法直接檢測出哪個是正確的版本,所以你需要嘗試創建每個。當 ActiveX 對象創建失敗時,它會拋出一個錯誤,必須捕獲該錯誤才能知道這不是要使用的版本。最終,你會得到一個看起來像這樣的函數(摘自 Professional JavaScript, 2nd Edition):
function createDocument(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.DOMDocument.6.0",
"MSXML2.DOMDocument.3.0",
"MSXML2.DOMDocument"];
for (var i=0,len=versions.length; i < len; i++){
try {
var xmldom = new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
return xmldom;
} catch (ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
}
一旦你有了一個 XML DOM 文檔實例,你可以使用 loadXML()
用 XML 填充它 並傳入一個 XML 字符串或使用 load()
並傳入一個 XML 文件的 URL。後者應避免使用 XMLHttpRequest
對象。
var xmldoc = createDocument();
xmldoc.loadXML("");
創建 XML 文檔的第二種方法是通過 XMLHttpRequest
請求 XML 並訪問 responseXML
財產。只要服務器的響應具有 text/xml
的內容類型,此屬性就包含一個 DOM 文檔 . DOM 文檔是使用最新(和適當的)MSXML 版本為您創建的。
var xhr = new XMLHttpRequest(),
xmldoc;
xhr.open("get", "data.xml", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status >= 200 && xhr.status < 300){
xmldoc = xhr.responseXML;
}
};
xhr.send(null);
這是將 XML 加載到 JavaScript 對像中最常用的方法,主要是因為它在所有瀏覽器中都受支持。
在 Internet Explorer 中創建 XML 文檔的第三種方法是使用 <xml>
標籤。這個專有擴展允許您將 XML 嵌入 HTML 頁面中; Microsoft 稱這些 XML 數據孤島。使用 <xml>
標籤要求您設置它的 src
屬性到 XML 文件或包含 XML 數據內聯。例子:
<xml id="myXML" src="data.xml"></xml>
<xml id="books">
<books>
<book>
<title>Professional JavaScript</title>
<edition>2nd</edition>
<author>Nicholas C. Zakas</author>
</book>
<book>
<title>Professional Ajax</title>
<edition>2nd</edition>
<author>Nicholas C. Zakas</author>
<author>Jeremy McPeak</author>
<author>Joe Fawcett</author>
</book>
</books>
</xml>
使用 <xml>
頁面中的標籤,您可以使用 XMLDocument
獲取對其 DOM 文檔對象的引用 屬性:
var xmldoc = document.getElementById("myXML").XMLDocument;
與 XMLHttpRequest
一樣 對象,這種方法將自動創建正確的 ActiveX 版本的 XML 文檔。 XML 數據島很少使用,因為它們是特定於 IE 的。
XPath 支持
Internet Explorer 中的所有 XML DOM 文檔對像都通過兩種方法內置了對 XPath 的支持:selectSingleNode()
和 selectNodes()
.每個方法都接受一個 XPath 表達式作為參數並返回第一個匹配節點和一個 NodeSet
的所有匹配節點,分別。如果沒有匹配的節點,selectSingleNode()
返回 null
而 selectNodes()
返回一個空的 NodeList
目的。文檔中的每個元素都有這兩種方法,從而可以輕鬆地在正確的上下文中執行 XPath 查詢。但是,在使用這些方法之前,建議將 XML DOM 文檔的選擇語言設置為 XPath。這對於避免微軟的第一個 XPath 實現(在規範最終定稿之前出現)和 W3C 建議之間的一些細微差別是必要的:
xmldoc.setProperty("SelectionLanguage", "XPath");
XPath 將在不設置此屬性的情況下工作,但是如果沒有它,可能會出現一些小的差異。設置好屬性後,就可以像其他瀏覽器一樣使用XPath查詢了:
var books = xmldoc.documentElement.selectNodes("//book");
var secondBook = xmldoc.documentElement.selectSingleNode("//book[2]");
var secondAuthor = secondBook.selectSingleNode("author[2]");
請注意,與 W3C 的 XPath 接口不同,Internet Explorer 只會返回單個節點或 NodeSet
;沒有其他可能的返回類型,因此您不能運行返回非節點值的查詢,例如使用 count()
的查詢 .
命名空間支持
默認情況下,Internet Explorer 的 XPath 引擎不適用於命名空間(與 DOM Level 3 XPath 實現相同)。命名空間信息必須提前指定為 XML DOM 文檔對象本身的屬性。考慮以下 XML 代碼:
<books xmlns:wrox="http://www.wrox.com/" xmlns="http://www.amazon.com/">
<wrox:book>Professional JavaScript</book>
</books>
為了在本文檔中使用 XPath 查詢,您首先需要為 wrox
定義命名空間信息 和默認命名空間。您可以通過 setProperty()
執行此操作 方法,傳入 "SelectionNamespaces"
以及以空格分隔的命名空間聲明字符串。示例:
xmldoc.setProperty("SelectionNamespaces",
"xmlns:wrox='http://www.wrox.com/' xmlns='http://www.amazon.com/'");
var book = xmldoc.documentElement.selectSingleNode("wrox:book");
請注意,名稱空間聲明的格式與它們在 XML 中出現的格式相同。不幸的是,沒有自動方法可以從文檔中提取名稱空間信息以用於 XPath 查詢。
結論
Internet Explorer 確實支持 XPath,但它帶有幾個警告。首先是 XPath 查詢僅適用於 XML 文檔,而不適用於 HTML 文檔,因此不能用於 document
幫助查找頁面上的元素。其次,XPath 實現非常基礎,只允許基本的返回類型(節點和 NodeSet
對象)。儘管如此,如果您正在處理 XML 數據,XPath 仍然是一種快速便捷的方式來查找特定元素,而無需手動遍歷 DOM。