(一) 載入
現在的瀏覽器都支援XMLHttpRequest 對象,我們可以通過該對象來載入XML文檔,來建立一個XML文檔對象。我們使用一個XML檔案作為例子:
<?xml version="1.0" encoding="utf-8" ?> <Customers> <Customer id="01" city="Beijing" country="China" name="Lenovo"> <Contact gender="female" title="Support">Li Li</Contact> </Customer> <Customer id="02" city="Amsterdam" country="The Netherlands" name="Shell"> <Contact gender="male" title="Sales Person">Aaron Babbitt</Contact> <Contact gender="female" title="Sales Manager">Daisy Cabell</Contact> <Contact gender="male" title="Sales Person">Gabriel Eads</Contact> </Customer> </Customers>
載入的代碼:
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "XMLFile1.xml", false); xmlhttp.send(); xmlDoc = xmlhttp.responseXML; alert(xmlDoc.xml); // 只有IE支援 alert(xmlhttp.responseText); // IE Chrome FireFox 都支援}
這裡注意,XMLHttpRequest.open的方法中,第三個參數設定了是同步載入還是非同步載入。如果是同步為false,非同步為true。如果是非同步話,你需要設定回呼函數。
如果你有一個xml字串,也可以解析(parse)該字串:
var str = "<book>";str = str + "<title>Javascript Tutorial</title>";str = str + "<author>Daisy Abbey</author>";str = str + "</book>";if (window.DOMParser) { // code for IE9+, Firefox, Chrome parser = new DOMParser(); xmlDoc = parser.parseFromString(str, "text/xml"); }else { xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async = false; xmlDoc.loadXML(str);}alert(xmlDoc.childNodes[0].childNodes[0].textContent);// result: Javascript Tutorial
(二) 查詢
對XML的元素、屬性、文本的查詢可以使用XPath。具體的定義可以參看w3school。
首先應該瞭解一下XPath運算式:
運算式 |
描述 |
nodename |
選取此節點的所有子節點。 |
/ |
從根節點選取。 |
// |
從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。 |
. |
選取當前節點。 |
.. |
選取當前節點的父節點。 |
@ |
選取屬性。 |
我們主要使用兩個方法來查詢XML文檔,selectNodes(xpath expression)和selectSingleNode(xpath expression)。
selectNodes返回一個NodeList對象,也就是所有符合xpath運算式的xml節點都將會被返回,你需要對返回的結果進行遍曆。
selectSingleNode只返回第一個符合xpath運算式的節點,或者返回null。
但是由於selectSingleNode和selectNodes只有IE才支援,Chrome和Firefox都使用evaluate方法來查詢XML,所以如果需要對多瀏覽器支援,需要使用封裝庫。下面是Microsoft Dynamics CRM SDK中提供好的一個封裝庫,可以拿來使用:
if (typeof (MyLibrary) == "undefined") { MyLibrary = { __namespace: true };}MyLibrary = { Name: "MyLibrary", _selectNodes: function (node, XPathExpression) { if (typeof (node.selectNodes) != "undefined") { return node.selectNodes(XPathExpression); } else { var output = []; var XPathResults = node.evaluate(XPathExpression, node, MyLibrary._NSResolver, XPathResult.ANY_TYPE, null); var result = XPathResults.iterateNext(); while (result) { output.push(result); result = XPathResults.iterateNext(); } return output; } }, _selectSingleNode: function (node, xpathExpr) { if (typeof (node.selectSingleNode) != "undefined") { return node.selectSingleNode(xpathExpr); } else { var xpe = new XPathEvaluator(); var xPathNode = xpe.evaluate(xpathExpr, node, MyLibrary._NSResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null); return (xPathNode != null) ? xPathNode.singleNodeValue : null; } }, _selectSingleNodeText: function (node, xpathExpr) { var x = MyLibrary._selectSingleNode(node, xpathExpr); if (MyLibrary._isNodeNull(x)) { return null; } if (typeof (x.text) != "undefined") { return x.text; } else { return x.textContent; } }, _getNodeText: function (node) { if (typeof (node.text) != "undefined") { return node.text; } else { return node.textContent; } }, _getNodeXml: function (node) { if (typeof (node.xml) != "undefined") { return node.xml; } else { return (new XMLSerializer()).serializeToString(node); } }, _isNodeNull: function (node) { if (node == null) { return true; } if ((node.attributes.getNamedItem("i:nil") != null) && (node.attributes.getNamedItem("i:nil").value == "true")) { return true; } return false; }, _NSResolver: function (prefix) { var ns = { "s": "http://schemas.xmlsoap.org/soap/envelope/", "a": "http://schemas.microsoft.com/xrm/2011/Contracts", "i": "http://www.w3.org/2001/XMLSchema-instance", "b": "http://schemas.datacontract.org/2004/07/System.Collections.Generic", "c": "http://schemas.microsoft.com/xrm/2011/Metadata" }; return ns[prefix] || null; }}
下面舉幾個例子:
1. 返回所有Contact節點:
var nodelist = MyLibrary._selectNodes(xmlDoc, "/Customers/Customer/Contact");for (var i = 0; i < nodelist.length; i++) { alert(MyLibrary._getNodeXml(nodelist[i])); // get the xml }
返回的結果為:
<Contact gender="female" title="Support">Li Li</Contact>
<Contact gender="male" title="Sales Person">Aaron Babbitt</Contact>
<Contact gender="female" title="Sales Manager">Daisy Cabell</Contact>
<Contact gender="male" title="Sales Person">Gabriel Eads</Contact>
2. 返回id為02的customer:
MyLibrary._selectSingleNode(xmlDoc, "/Customers/Customer[@id='02']")
返回結果為:
<Customer id="02" city="Amsterdam" country="The Netherlands" name="Shell">
<Contact gender="male" title="Sales Person">Aaron Babbitt</Contact>
<Contact gender="female" title="Sales Manager">Daisy Cabell</Contact>
<Contact gender="male" title="Sales Person">Gabriel Eads</Contact>
</Customer>
3. 返回含有contact名為Li Li的contact:
MyLibrary._selectSingleNode(xmlDoc, "/Customers/Customer/Contact[text()='Li Li']")
返回結果為:
<Contact gender="female" title="Support">Li Li</Contact>
4. 返回含有contact名為 Li Li 的customer。注意和3的區別:
MyLibrary._selectSingleNode(xmlDoc, "/Customers/Customer[Contact/text()='Li Li']")
<Customer id="01" city="Beijing" country="China" name="Lenovo">
<Contact gender="female" title="Support">Li Li</Contact>
</Customer>
5. 如何擷取xml、text、以及屬性(attribute)
(1) 擷取xml:
var node = MyLibrary._selectSingleNode(xmlDoc, "/Customers/Customer/Contact[text()='Li Li']");
var nodeXml = MyLibrary._getNodeXml(node);
結果為: <Contact gender="female" title="Support">Li Li</Contact>
(2) 擷取text:
MyLibrary._selectSingleNode(xmlDoc, "/Customers/Customer/Contact[text()='Li Li']")
結果為: Li Li
(3) 擷取屬性使用 getAttribute 方法:
MyLibrary._selectSingleNode(xmlDoc, "/Customers/Customer/Contact[text()='Li Li']").getAttribute("gender")