Beginning XML with DOM and Ajax From Novice to Professional phần 7 doc

45 305 0
Beginning XML with DOM and Ajax From Novice to Professional phần 7 doc

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

IE acts a little differently from Mozilla, as it won’t display any XML content from a docu- ment that is not well formed. In IE, you wouldn’t see any XML output at all. XSLT Manipulation In Chapters 6 and 7, I worked through XSLT transformation techniques that allowed you to generate XHTML content from XML. MSXML includes the methods transformNode() and transformNodeToObject(). As these methods aren’t available in Mozilla, they’ve been added to the xDOM library. The transformNode() method returns the transformed content as a string, whereas transformNodeToObject() populates the DOMDocument object passed as a parameter. The MSXML transformNodeToObject() method can send the results to an IStream, which can stream information into Microsoft components. However, because this is Microsoft- specific, xDOM doesn’t support the feature. Applying Stylesheets to Documents The test page contains an example that uses transformNode() and transformNodeToObject(): function onLoad_XSLtdOM() { if (oXSLT.readyState == 4) { var strOutput; var oOutput = xDOM.createDOMDocument(); strOutput = oXMLFromURL.transformNode(oXSLT); oXMLFromURL.transformNodeToObject(oXSLT,oOutput); document.getElementById("divTransformNodeXSLT").innerHTML = ➥ doReplace(oXSLT.xml); document.getElementById("divTransformNodeResult").innerHTML = strOutput; strOutput = oXMLFromURL.getElementsByTagName("DVD")[1].transformNode(oXSLT); document.getElementById("divTransformNodePartOfTree").innerHTML = strOutput; } } CHAPTER 8 ■ SCRIPTING IN THE BROWSER 251 Figure 8-7. An XML document that isn’t well formed displayed in Firefox 6765CH08.qxd 5/19/06 11:40 AM Page 251 The code must make sure that the variable passed into transformNodeToObject() is ini- tialized. If you use the transformNodeToObject() method, you also need to make sure that the XSLT stylesheet generates valid XML. Note that the example XSLT file, test.xslt, uses a <div> tag to wrap the transformation output, thereby creating a single root element in the transfor- mation. Figure 8-8 shows the XSLT document and the transformation resulting from test.xslt. It also shows a single node transformation. MSXML Template and Processor Objects MSXML includes two objects that you can use together to compile an XSLT stylesheet for sev- eral transformations. This functionality increases efficiency and is most suited to a server-side environment, where the same stylesheet runs with each page request. I won’t cover these objects here, but you can find out more about the IXSLProcessor and IXSLTemplate interfaces in the MSXML documentation. DOM Manipulation and XSLT Combined Because the transformNode() methods are declared on the Node interface, you can combine the power of DOM iteration with XSLT by selecting a single node for transformation: strOutput = oXMLFromURL.getElementsByTagName("DVD")[0].transformNode(oXSLT); document.getElementById("divTransformNodePartOfTree").innerHTML = strOutput; In this case, I’ve matched the first DVD element using getElementsByTagName("DVD")[0]. The template matches this element: <DVD id="1"> <title>Breakfast at Tiffany's</title> <format>Movie</format> <genre>Classic</genre> </DVD> Only this node is transformed. CHAPTER 8 ■ SCRIPTING IN THE BROWSER252 Figure 8-8. The test.xslt document and transformation 6765CH08.qxd 5/19/06 11:40 AM Page 252 Extracting Raw XML One task for developers is retrieving XML content from the DOM as a string. The W3C DOM specification is silent on how to achieve this task. MSXML provides the read-only xml property on the Node interface. This returns the raw XML from a specific node as text. xDOM provides a Mozilla version of this property. There is no specific example in the test.htm document, but the property is used in many of the other examples. ■Note The xml property is provided within the Node interface. Because the Document interface inherits the Node interface, you can access this property on the DOM Document object: The following code sets the variable strXML to equal the serialized contents of the oXMLFromString DOM Document: var strXML = oXMLFromString.xml; Manipulating the DOM The test.htm document also includes examples of traversing, adding to, and editing the con- tents of a DOM Document. Traversing a DOM Document You can iterate through the DOM Document in much the same way as with other data structures such as arrays. The following example shows one way to loop through the collection of child nodes of an XML document: function doIterationExample() { var strOutput; strOutput = ""; for (var node=oXMLFromURL.documentElement.firstChild; node != null; ➥ node = node.nextSibling) { strOutput = strOutput + node.nodeName + "<br/>"; } document.getElementById("divIterateDOM").innerHTML = strOutput; } Figure 8-9 shows the output from this function. CHAPTER 8 ■ SCRIPTING IN THE BROWSER 253 6765CH08.qxd 5/19/06 11:40 AM Page 253 Figure 8-9. Iterating through the nodes in an XML document Note that the output shows text nodes as well as the <DVD> elements. However, if you look at the XML document, you can see that no text nodes exist between these elements. Text nodes appear because the parser treats white space as text when it falls within an element. In this case, the tabs and carriage returns inside the <library> element are treated as text nodes. This is not the default behavior for the MSXML parser. You need to tell the parser explic- itly to preserve the white space nodes when you create the ActiveX object in the xDOM library: oOutDOMDocument.preserveWhiteSpace = true; If you don’t do this, you’ll see different behavior in MSXML and Mozilla, and you won’t be able to write cross-browser code. Accessing Element Values You can access the text within elements by using the nodeValue property. Remember that text within an element is a child of that element. This example shows how to retrieve the title for each DVD: function doGetElementsExample(){ var strOutput; strOutput = ""; var oNodeList; oNodeList = oXMLFromURL.documentElement.getElementsByTagName("title"); for (var i=0; i < oNodeList.length; i++) { strOutput = strOutput + oNodeList[i].firstChild.nodeValue + "<br/>"; } document.getElementById("divElementDOM").innerHTML = strOutput; } Figure 8-10 shows the output from this function. Figure 8-10. Displaying the text within the elements in an XML document CHAPTER 8 ■ SCRIPTING IN THE BROWSER254 6765CH08.qxd 5/19/06 11:40 AM Page 254 Accessing Attributes You can access attributes within an element by name: oCityNode.attributes.getNamedItem("id").firstChild.nodeValue; This line retrieves the text from the first child of the id attribute node. The first child con- tains the text content of the attribute. The doGetAttributesExample() function shows an example: function doGetAttributesExample() { var strOutput; strOutput = ""; var oNodeList; oNodeList = oXMLFromURL.documentElement.getElementsByTagName("DVD"); for (var i=0; i < oNodeList.length; i++) { strOutput = strOutput + oNodeList[i].attributes.getNamedItem("id").value ➥ + "<br/>"; } document.getElementById("divAttributeDOM").innerHTML = strOutput; } Figure 8-11 shows how this appears. Figure 8-11. Iterating through the DVD id attributes Loading XML from a String Instead of loading an external XML document, you can load XML data from a string variable. As with the load() method, loading from a string variable uses an asynchronous loading process. The only difference is the following line, which uses the loadXML() method instead of load(): oXMLFromString.loadXML('<?xml version="1.0"?><library><DVD id="4"> ➥ <title>The Constant Gardener</title></DVD></library>'); CHAPTER 8 ■ SCRIPTING IN THE BROWSER 255 6765CH08.qxd 5/19/06 11:40 AM Page 255 ■Tip Because the XML string contains an attribute, I’ve used two types of quotation marks in the JavaScript line. The loadXML() method encloses the string XML content in a single quotation mark, while the attributes use double quotes. You could also use the quotation marks in the opposite way or escape the quotes within the loadXML string variable. Adding Elements and Attributes The test.htm document includes an example that adds a node to the DOM Document. The rele- vant portion of the onLoad_LoadXMLFromString() function follows: var oElement= oXMLFromString.createElement("DVD"); var oAttribute = oXMLFromString.createAttribute("id"); oAttribute.value = "5"; oElement.attributes.setNamedItem(oAttribute); oElement.appendChild(oXMLFromString.createTextNode("Pride and Prejudice")); oXMLFromString.documentElement.appendChild(oElement); The code starts by creating a new <DVD> element using createElement(): var oElement= oXMLFromString.createElement("DVD"); Then the code creates an attribute called id with the createAttribute() method and sets its value to 5: var oAttribute = oXMLFromString.createAttribute("id"); oAttribute.value = "5"; Next, the code uses appendChild() to add a new text node to the element: oElement.appendChild(oXMLFromString.createTextNode("Pride and Prejudice")); Finally, the code appends the new element to the documentElement of the DOM Document: oXMLFromString.documentElement.appendChild(oElement); Figure 8-12 shows the XML string after adding the new element. Figure 8-12. Manipulating an XML string CHAPTER 8 ■ SCRIPTING IN THE BROWSER256 6765CH08.qxd 5/19/06 11:40 AM Page 256 Deleting and Replacing Elements You’ll notice that Figure 8-12 also includes an example of removing and replacing a node. The following code removes the new element and replaces an existing element: var oRootNode = oXMLFromString.documentElement var oOldNode = oRootNode.removeChild(oRootNode.lastChild); oRootNode.replaceChild(oOldNode,oRootNode.firstChild); These lines use the removeChild() method to remove the last <DVD> child element, which is stored in the oOldNode variable. The code then uses the replaceChild() method to replace the first <DVD> child element. Figure 8-12 shows the effect of the replacement. You’ve seen the main aspects of using xDOM with an XML document. In the next section, let’s look at an example that puts these techniques into practice. Putting It into Practice In this section of the chapter, I’ll use the xDOM library with a real-world example. You can find the example in the contacts folder with the other resources for this chapter. This example provides a simple demonstration of some of the concepts discussed in this chapter. The example relies heavily on XSLT transformations. Because both IE and Mozilla work with stylesheets in a similar way, this approach provides a cross-browser solution. It’s too difficult to generate complex XHTML using DOM manipulation alone. Note that the example won’t work in Opera 8.5 and below. Understanding the Application The application loads an XML document containing information about contacts. It uses two XSLT stylesheets to display the content in a web browser dynamically. The first stylesheet cre- ates a link for each contact. Clicking the link displays the contact details. Figure 8-13 shows the process that I’ll work through in the application. In brief, the user requests an XHTML page that includes JavaScript. The page loads an XML document and two stylesheets. One stylesheet transforms the XML document to display a set of links. When the user clicks a link, the second stylesheet provides the details of the selected option. I’ll use parameters so that the same transformation displays details for each of the links. A key point of this application is that the user can display different contact details without the browser having to return to the server. All the relevant data is downloaded once, when the page first loads. CHAPTER 8 ■ SCRIPTING IN THE BROWSER 257 6765CH08.qxd 5/19/06 11:40 AM Page 257 Figure 8-13. The contacts application-processing example Examining the Code Let’s work through the application. First, the structure of the source XML document, contacts.xml, follows: <?xml version="1.0" encoding="UTF-8"?> <! This XML document describes a contacts list > <contacts> <person id="9407001" type="supplier"> <first_name>John</first_name> <last_name>Smith</last_name> CHAPTER 8 ■ SCRIPTING IN THE BROWSER258 6765CH08.qxd 5/19/06 11:40 AM Page 258 <company>Banana Computing</company> <address1>1 Fiction Street</address1> <address2>Imaginary Town</address2> <country>Strangeland</country> <postal_code>ABC 567</postal_code> <last_contact>2005-05-27</last_contact> </person> </contacts> Obviously, this XML file contains multiple contacts, but for brevity, I’ve only shown the structure of the first <person> element. The information is contained in a physical XML file, but it could just as easily be generated from a database with server-side code or consumed from a web service. The contacts_demo.htm page starts the process with an onload handler in the <body> tag: <body onLoad="runInit();"> The runInit() function checks that the xDOM library initializes successfully and calls the doLoadXMLFromURL() function to load the document: function runInit() { if (blnFailed){ alert(strFailedReason); } else { doLoadXMLFromURL(); } } The doLoadXMLFromURL() function is similar to the code you saw in the previous section: function doLoadXMLFromURL() { oXMLFromURL = xDOM.createDOMDocument(); oXMLFromURL.onreadystatechange = onLoad_LoadXMLFromURL; oXMLFromURL.load("contacts.xml"); } The function creates a DOM Document and sets the onreadystatechange handler. It then loads the contacts.xml file. The handler function follows: function onLoad_LoadXMLFromURL() { if (oXMLFromURL.readyState == 4) { oXSLT=xDOM.createDOMDocument(); oXSLT.onreadystatechange = onLoad_XSLTDOM; oXSLT.load("select.xslt"); oXSLTDisplay=xDOM.createDOMDocument(); oXSLTDisplay.onreadystatechange = onLoad_XSLTDOM; oXSLTDisplay.load("display.xslt"); } } CHAPTER 8 ■ SCRIPTING IN THE BROWSER 259 6765CH08.qxd 5/19/06 11:40 AM Page 259 This function checks that readyState is equal to 4—in other words, that the XML document loads successfully. The function then loads two stylesheets, select.xslt and display.xslt, setting the onreadystatechange handlers. The select.xslt stylesheet creates the list of links for the application: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <div> <xsl:apply-templates select="/contacts/person"/> </div> </xsl:template> <xsl:template match="person"> <a href="javascript:showPerson({@id});"> <xsl:value-of select="first_name"/><xsl:text> </xsl:text> <xsl:value-of select="last_name"/> </a><br/> </xsl:template> </xsl:stylesheet> This stylesheet creates the links in a <div> element. Each link calls the showPerson() function, passing the value of the id attribute. The second XSLT stylesheet, display.xslt, is also very simple. However, it contains a parameter that will be used to select which person to display: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="personid">0</xsl:param> <xsl:template match="/"> <xsl:if test="$personid > 0"> <div> <xsl:apply-templates select="/contacts/person[@id=$personid]"/> </div> </xsl:if> </xsl:template> <xsl:template match="person"> Name: <xsl:value-of select="first_name"/><xsl:text> </xsl:text> <xsl:value-of select="last_name"/><br/> Type: <xsl:value-of select="@type"/><br/> Company: <xsl:value-of select="company"/><br/> Address: <xsl:value-of select="address1"/>, <xsl:value-of select="address2"/>, <xsl:value-of select="country"/> <xsl:text> </xsl:text> <xsl:value-of select="postal_code"/> </xsl:template> </xsl:stylesheet> CHAPTER 8 ■ SCRIPTING IN THE BROWSER260 6765CH08.qxd 5/19/06 11:40 AM Page 260 [...]... processXML(){ if(xmlhttp.readyState == 4){ alert(xmlhttp.responseXML); } } It mimics the XSLTProcessor object to manipulate stylesheets in IE, and you can use Sarissa for other tasks such as creating a DOM Document: var oDomDoc = Sarissa.getDomDocument(); oDomDoc.onreadystatechange = processXML; oDomDoc.load("dvd .xml" ); function processXML { if(oDomDoc.readyState == 4) alert(Sarissa.serialize(oDomDoc));... Consortium (W3C) Document Object Model (DOM) to work with XML documents in a web browser I loaded an XML document and manipulated the structure using JavaScript and the DOM I used the xDOM library to create cross-browser JavaScript appropriate for both Internet Explorer (IE) and Mozilla In this chapter, I’ll show you another way to work with XML on the client—using Asynchronous JavaScript and XML (Ajax) Jesse... function twice—once from the loading of the XML document and once by the XSLT document The second call is made from the document that loads last By that time, both documents are loaded and available for scripting The doTransform() function follows: function doTransform(docElement, xmlDoc, xslDoc) { if (xmlDoc == null || xslDoc == null) return; if (window.ActiveXObject){ document.getElementById(docElement).innerHTML=➥... be to manipulate the content using JavaScript with DOM methods You’ll see that in the next example 676 5CH09.qxd 5/19/06 11:42 AM Page 275 CHAPTER 9 ■ THE AJAX APPROACH TO BROWSER SCRIPTING Using XMLHttpRequest with the DOM In the previous example, I used the responseText property to access the loaded XML as a string I can also use responseXML to return an XML document that I can manipulate with DOM. .. sendRequest('contacts_summary .xml' , 'display.xslt', xmlReady, xslReady); } I’ve also changed the sendRequest() function, because I can use Sarissa to create a new XMLHttpRequest object for either IE or Mozilla: function sendRequest(xmlURL, xslURL, xmlHandler, xslHandler) { xmlhttp = new XMLHttpRequest(); if (xmlhttp){ xmlhttp.onreadystatechange=xmlHandler; xmlhttp.open("GET", xmlURL, true); xmlhttp.send(null); } xslhttp = new XMLHttpRequest();... (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } else if (window.ActiveXObject){ 676 5CH09.qxd 5/19/06 11:42 AM Page 277 CHAPTER 9 ■ THE AJAX APPROACH TO BROWSER SCRIPTING try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { xmlhttp = false; } } } if (xmlhttp){ xmlhttp.onreadystatechange=checkNames; xmlhttp.open("GET", "usernames .xml" ,... sendRequest(xmlURL, xslURL, xmlHandler, xslHandler) { xmlhttp = setupXMLHR(); if (xmlhttp){ xmlhttp.onreadystatechange=xmlHandler; xmlhttp.open("GET", xmlURL, true); xmlhttp.send(null); } xslhttp = setupXMLHR(); if (xslhttp){ xslhttp.onreadystatechange=xslHandler; xslhttp.open("GET", xslURL, true); xslhttp.send(null); } } You’ll notice that the sendRequest() function uses the setupXMLHR() function to generate... "dvd .xml" ; function getHeaders() { if (window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); } else if (window.ActiveXObject){ try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { xmlhttp = false; } } } if (xmlhttp){ xmlhttp.onreadystatechange=onReadyState; xmlhttp.open("HEAD", toLoad, true); xmlhttp.send(null); } } 271 676 5CH09.qxd... I move on to some examples, it’s important to understand the XMLHttpRequest object Working with the XMLHttpRequest Object In IE, you can create the XMLHttpRequest ActiveX object using xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); or xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); depending on your MSXML version 2 67 676 5CH09.qxd 268 5/19/06 11:42 AM Page 268 CHAPTER 9 ■ THE AJAX APPROACH TO BROWSER... the responseXML example in the file getXMLDocument.htm Figure 9-4 shows the example in IE Figure 9-4 Traversing the dvd .xml document with the XML DOM Here, the main difference from the previous example is in the onReadyState function The changed lines appear in bold: function onReadyState(){ if (xmlhttp.readyState==4){ if (xmlhttp.status==200) { xmlDoc = xmlhttp.responseXML; var dvdList = xmlDoc.getElementsByTagName("title"); . the DOM Document object: The following code sets the variable strXML to equal the serialized contents of the oXMLFromString DOM Document: var strXML = oXMLFromString .xml; Manipulating the DOM The. { doLoadXMLFromURL(); } } The doLoadXMLFromURL() function is similar to the code you saw in the previous section: function doLoadXMLFromURL() { oXMLFromURL = xDOM.createDOMDocument(); oXMLFromURL.onreadystatechange. onLoad_LoadXMLFromURL; oXMLFromURL.load("contacts .xml& quot;); } The function creates a DOM Document and sets the onreadystatechange handler. It then loads the contacts .xml file. The handler

Ngày đăng: 14/08/2014, 10:22

Từ khóa liên quan

Mục lục

  • Beginning XML with DOM and Ajax: From Novice to Professional

    • CHAPTER 9 The Ajax Approach to Browser Scripting

    • CHAPTER 10 Using Flash to Display XML

Tài liệu cùng người dùng

Tài liệu liên quan