Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 15 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
15
Dung lượng
367,15 KB
Nội dung
Chapter 11 Displaying XML Documents Using Document Object Model Scripts 371 11 Document Object Model Scripts ■ childNodes is a property of the Element node for the root element. It contains a collection of all the nonattribute child nodes of the root Element node. In this example, it contains the Element nodes for the five child XML elements: TITLE, AUTHOR, BINDING, PAGES, and PRICE. The expression childNodes(0) references the first of these child nodes (the one for the TITLE element). note In the example page (Listing 11-3), you could use the expression Document.childNodes(2) to obtain the Element node for the root element. (Document.childNodes(0) is the node for the XML declaration and Document.childNodes(1) is the node for the comment.) However, an advan- tage of using the Document node’s documentElement property is that its value doesn’t depend on the position of the root element within the XML document. For example, if you were to remove the comment at the beginning of the docu- ment, or if you were to add a document type declaration, Document.childNodes(2) would no longer represent the root element. ■ text is a property of the Element node returned by childNodes(0). It provides the complete text content of this node as well as the text belonging to any descendent Element nodes it might have. In this ex- ample, TITLE has no descendent elements, so text contains only TITLE’s own text, The Adventures of Huckleberry Finn. note The childNodes and text properties are among the common node properties given in Table 11-2. 372 XML Step by Step Document node Description Example property async Assigning false to the Document.async = false; async property causes a subsequent call to the load method (described later in the table) to load the XML document synchronously (that is, the call won’t return until the document is fully loaded). The default property value is true. doctype The DocumentType DocumentType = Document.doctype; node representing the document type declaration documentElement The Element node RootElement = Document.documentElement; representing the root element of the XML document parseError An object that contains ErrorCode = information on the first Document.parseError.errorCode; well-formedness or validity if (ErrorCode ! = 0) error that the processor /* report and handle error */ encountered when it loaded else and processed the XML /* document is error-free */ document, or a code indicating that the document is error-free schemas If you assign an XML XMLSchemaCache = new ActiveXObject SchemaCache object to ("Msxml2.XML SchemaCache.4.0"); this property, the document XMLSchemaCache.add will be validated against the (XMLNamespaceName, associated XML schema "Book Schema.xsd"); when the load method Document.schemas = XMLSchemaCache; (described later in the table) is subsequently called. url The URL of the XML URL = Document.url; document Chapter 11 Displaying XML Documents Using Document Object Model Scripts 373 11 Document Object Model Scripts Document node Description Example method getElementsByTagName Returns a NodeList AuthorElementCollection = (type-name) collection of all elements Document.getElementsByTagName("AUTHOR"); in the document that have the specified type name. If you pass "*", it returns all elements. nodeFromID (id-value) Returns the node Element = representing the element Document.nodeFromID (“S021”); whose ID type attribute has the value that you pass. (For information on ID attributes, see “Specifying a Tokenized Type” in Chapter 5.) Table 11-3. Useful properties and methods provided by Document nodes. The available prop- erties also include the common node properties listed in Table 11-2. The TITLE element’s character data that derives from the expression on the right side of the equal sign (The Adventures of Huckleberry Finn) is assigned to the innerText property of the HTML SPAN element that has the identifier title: title.innerText= Document.documentElement.childNodes(0).text; This SPAN element is defined within the BODY of the HTML page, as follows: <SPAN ID=”title” STYLE=”font-weight:bold”></SPAN> Assigning the character data to the SPAN’s innerText property causes the SPAN to display that text, using the cascading style sheet property setting defined within its start-tag (font-weight:bold). tip In the Dynamic HTML (DHTML) model supported by Internet Explorer, each HTML element has a set of properties that you can use to set or retrieve various features of the element through script code. The innerText property sets or retrieves the text content of an HTML element. For information on working with DHTML as implemented in Internet Explorer, see the topic “HTML and Dynamic HTML” in the MSDN Library on the Web at http://msdn.microsoft.com/library/. 374 XML Step by Step Using a NodeList Object As I explained earlier in the chapter, the childNodes node property contains a collection of the current node’s nonattribute child nodes. (As you’ll learn later, you access attribute child nodes through the node’s attributes property.) The specific type of collection that childNodes contains is known as a NodeList object. To extract a specific child node from a NodeList object, you can call its item method, passing it the 0-based index of the child node you want to retrieve. For example, the following method call obtains the first child node belonging to Element: FirstNode = Element.childNodes.item(0); However, because item is the default method for a NodeList object, you can omit it, as you’ve seen in previous examples in this chapter: FirstNode = Element.childNodes(0); Table 11-4 lists the property and the methods provided by a NodeList object. NodeList property Description Example length The number of nodes NodeCount = contained in the collection Element.childNodes.length; NodeList method Description Example item (0-based-index) Returns the node at the SecondChild = (default method) position indicated by the Element.childNodes.item (1); index you pass, where 0 or indicates the first node SecondChild = Element.childNodes (1); reset () Sets the internal pointer Element.childNodes.reset (); to the position before the first node in the collection, so the next call to nextNode returns the first node nextNode () Returns the next node in Element.childNodes.reset (); the collection, as marked FirstNode = by the internal pointer Element.childNodes.nextNode (); Table 11-4. The property and methods provided by a NodeList collection object. A NodeList object is supplied by the childNodes node property. Chapter 11 Displaying XML Documents Using Document Object Model Scripts 375 11 Document Object Model Scripts Retrieving an Element’s Character Data The script in Listing 11-3 used the text property of each child element (TITLE, AUTHOR, BINDING, PAGES, and PRICE) as a shortcut for obtaining the element’s character data. For instance, here’s the statement used to retrieve the character data of the TITLE element: title.innerText= Document.documentElement.childNodes(0).text; The text property provides the text content of the element represented by the current node, plus the text content of any descendent elements. It works fine for extracting an element’s character data if the element has no child elements (such as TITLE). However, if the element contains one or more child elements as well as character data, as in the following example, the text property returns all the text (in this example, “Moby-Dick Or, The Whale”). <TITLE>Moby-Dick <SUBTITLE>Or, The Whale</SUBTITLE></TITLE> To obtain only the character data of the TITLE element, you need to access its child Text node. Recall from Table 11-1 that an Element node’s nodeValue property is always set to null. If the element contains character data, this text is stored in a child Text node and you can obtain it from the Text node’s nodeValue property. For ex- ample, if Element contains the node for the “Moby-Dick” TITLE element shown in the preceding example, the following expression would supply TITLE’s character data (Moby-Dick) without including the character data be- longing to SUBTITLE: Element.firstChild.nodeValue (Because TITLE’s character data comes before its subelement, it is represented by the first child node and you can therefore retrieve it using the firstChild property.) If an element’s character data is interspersed with child elements, comments, or processing instructions, each separate block of character data is represented by its own child Text node. For instance, the following ITEM element would have three child nodes that would occur in this order: a Text node representing the first block of character data, an Element node representing the child element SUB-ITEM, and another Text node representing the second block of character data. 376 XML Step by Step <ITEM> character data block 1 <SUB-ITEM>sub-item text</SUB-ITEM> character data block 2 </ITEM> Table 11-5 lists a useful property and method provided by Text nodes. Text node property Description Example length The number of characters CharacterCount = Text.length; in the node’s text Text node method Description Example substringData Returns a string SubString = Text.substringData (2, 3); (char-offset, num-chars) containing the specified (Returns the third, fourth, and fifth number of characters characters from the Text element’s from the node’s text content) content, starting at the specified character offset Table 11-5. A useful property and method provided by Text nodes. The available properties also include the common node properties listed in Table 11-2. Displaying a Variable Number of XML Elements So far, you’ve learned how to display an XML document that has a known num- ber of elements. If a document has an unknown number of elements, using the DOM to display it is a bit more complex. For example, with an XML document such as Inventory.xml (given in Listing 10-1 and on the companion CD) or Inventory Big.xml (given in Listing 10-3 and on the companion CD), you generally would not know in advance how many BOOK elements the document contains. And if the number of BOOK elements changes, you of course would like your script to keep working. Listing 11-4 presents an HTML page that uses the DOM to display Inventory.xml in a way that is independent of the number of BOOK elements contained in the document. (You’ll find this listing on the companion CD under the filename DomDemo Variable.htm.) Here’s how the page looks in Internet Explorer: Chapter 11 Displaying XML Documents Using Document Object Model Scripts 377 11 Document Object Model Scripts DomDemo Variable.htm <! File Name: DomDemo Variable.htm > <HTML> <HEAD> <TITLE>Book Inventory</TITLE> <SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="ONLOAD"> HTMLCode = ""; Document = dsoInventory.XMLDocument; for (i=0; i < Document.documentElement.childNodes.length; i++) { 378 XML Step by Step HTMLCode += "<SPAN STYLE='font-style:italic'>Title: </SPAN>" + Document.documentElement.childNodes(i).childNodes(0).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Author: </SPAN>" + Document.documentElement.childNodes(i).childNodes(1).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Binding: </SPAN>" + Document.documentElement.childNodes(i).childNodes(2).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Number of pages: " + "</SPAN>" + Document.documentElement.childNodes(i).childNodes(3).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Price: </SPAN>" + Document.documentElement.childNodes(i).childNodes(4).text + "<P>"; } DisplayDIV.innerHTML=HTMLCode; </SCRIPT> </HEAD> <BODY> <XML ID="dsoInventory" SRC="Inventory.xml"></XML> <H2>Book Inventory</H2> <DIV ID="DisplayDIV"></DIV> </BODY> </HTML> Listing 11-4. The script in the example page uses the length property to determine the number of BOOK elements contained within the root element. (The length property is a mem- ber of the NodeList collection object provided by the childNodes property of the root element node. See Table 11-4.) The script contains a for loop that is executed once for each BOOK element and includes the code to display each of these elements: Chapter 11 Displaying XML Documents Using Document Object Model Scripts 379 11 Document Object Model Scripts for (i=0; i < Document.documentElement.childNodes.length; i++) { /* code to display a BOOK element */ } Because the number of BOOK elements is unknown, the page can’t use a fixed set of SPAN elements in its BODY to display the data (as did the previous ex- ample page in Listing 11-3). Rather, for each BOOK element, the script dynami- cally generates the entire block of HTML markup necessary to display the element: for (i=0; i < Document.documentElement.childNodes.length; i++) { HTMLCode += "<SPAN STYLE='font-style:italic'>Title: </SPAN>" + Document.documentElement.childNodes(i).childNodes(0).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Author: </SPAN>" + Document.documentElement.childNodes(i).childNodes(1).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Binding: </SPAN>" + Document.documentElement.childNodes(i).childNodes(2).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Number of pages: " + "</SPAN>" + Document.documentElement.childNodes(i).childNodes(3).text + "<BR>" + "<SPAN STYLE='font-style:italic'>Price: </SPAN>" + Document.documentElement.childNodes(i).childNodes(4).text + "<P>"; } The script stores all of these blocks of HTML markup in the variable HTMLCode. After the for loop, when all blocks have been generated and stored in HTMLCode, the script assigns the HTML markup to the innerHTML prop- erty of the DIV element in the BODY of the page (this element has the ID DisplayDIV): DisplayDIV.innerHTML=HTMLCode; 380 XML Step by Step The DIV element then immediately renders the HTML and displays the results, which you saw in the previous figure. To convince yourself that the page works regardless of the number of BOOK elements the XML document contains, you might edit the data island in this page so that it displays Inventory Big.xml, which contains twice as many BOOK elements as Inventory.xml: <XML ID=”dsoInventory” SRC=”Inventory Big.xml”></XML> Using Other Ways to Access Elements The example scripts you’ve seen so far have accessed Element nodes by travers- ing the node hierarchy using the childNodes or the firstChild node property to move from one node to an adjoining node. Keep in mind that you can use the lastChild, previousSibling, nextSibling, and parentNode node properties in analogous ways. Table 11-2 describes all these properties. note The childNodes, firstChild, and lastChild properties allow you to access only nonattribute child nodes, while the previousSibling and nextSibling properties let you access any type of sibling node. For a Document or Attribute node, the parentNode property is always set to null. Another way to access XML elements is to use the getElementsByTagName property to extract all elements that have a particular type name (such as TITLE). This method is available for a Document node, as described in Table 11-3, as well as for an Element node, as described in Table 11-6. If you call the method for a Document node, it returns a collection of Element nodes for all el- ements in the document that have the specified type name. For example, the fol- lowing statement obtains a collection of nodes for all elements in the document that have the name BOOK: NodeList = Document.getElementsByTagName(“BOOK”); If you call getElementsByTagName for an Element node, as shown in the fol- lowing example, it returns a collection of nodes for all matching elements that are descendents of the Element node: NodeList = Element.getElementsByTagName(“AUTHOR”); [...]... the XML markup for each Element node in ResultHTML: */ ResultHTML = ""; for (i=0; i < NodeList.length; ++i) ResultHTML += NodeList(i) .xml + "\n\n"; 11 /* get a NodeList collection of all matching Element nodes in the document: */ Document = dsoXML.XMLDocument; NodeList = Document.getElementsByTagName (ElementName.value); 384 XML Step by Step < /XML> ... types of XML components that consist of name-value pairs—namely: I A name and a value in a processing instruction (such as version="1.0" in the XML declaration) I The keyword SYSTEM followed by a system identifier in a document type declaration, external entity declaration, or notation declaration I The keyword NDATA followed by a notation name in an unparsed entity declaration 386 XML Step by Step The... < /XML> Find Elements by Element Name Element name:   Show Elements Listing 11-5 Accessing and Displaying XML Document Attribute Values An attribute contained in an XML element is represented by a child Attribute node However, you... to retrieve includes a namespace prefix, you’ll need to include that prefix in the value you pass to getElementsByTagName, as in the following example: NodeList = Document.getElementsByTagName("inventory:BOOK"); For information on namespaces, see “Using Namespaces” on page 69 The getElementsByTagName method supplies the Element nodes in the form of a NodeList collection object You can therefore access... nextNode () Returns the next node Element.attributes.reset (); in the collection, as FirstAttribute = marked by the internal Element.attributes.nextNode (); pointer Table 11-7 The property and some useful methods provided by NamedNodeMap collection objects A NamedNodeMap object is supplied by the attributes node property You can use the NamedNodeMap object’s length property and its default item method...Chapter 11 Displaying XML Documents Using Document Object Model Scripts 381 tip If you pass the value “*” to getElementsByTagName, it returns a collection of nodes for all elements (all elements in the document if you call the method for a Document node and all descendent... any of the techniques discussed in “Using a NodeList Object” on page Document Object Model Scripts 11 Table 11-6 Useful methods provided by Element nodes With Element nodes you can also use any of the common node properties listed in Table 11-2 Chapter 11 Displaying XML Documents Using Document Object Model Scripts 383 GetElements.htm Element Finder... = Document.documentElement.childNodes(0).attributes A NamedNodeMap collection object is somewhat different from a NodeList collection object supplied by the childNodes node property Table 11-7 lists the property and some of the useful methods provided by NamedNodeMap objects NamedNodeMap property Description Example length The number of nodes contained in the collection AttributeCount = Element.attributes.length;... specified name Attribute = Element.getAttributeNode ("InStock"); getElementsByTagName (type-name) Returns a NodeList collection of Element nodes for all of this element’s descendent elements that have the specified type name If you pass "*", it returns nodes for all descendent elements AuthorElementCollection = Element.getElementsByTagName ("AUTHOR"); note If the type name of the elements you want to retrieve... that Attribute = has the specified name, Element.attributes.getNamedItem or null if the attribute ("Binding"); isn’t found item (0-based-index) (default method) Returns the node at the position indicated by the index, where 0 indicates the first node SecondAttribute = Element.attributes.item (1); or SecondAttribute = Element.attributes (1); reset () Sets the internal pointer Element.attributes.reset (); . ResultHTML; } 384 XML Step by Step </SCRIPT> </HEAD> <BODY> < ;XML ID="dsoXML" SRC="Inventory .xml& quot;>< /XML& gt; <H2>Find Elements by Element Name</H2> . HTMLCode = ""; Document = dsoInventory.XMLDocument; for (i=0; i < Document.documentElement.childNodes.length; i++) { 378 XML Step by Step HTMLCode += "<SPAN STYLE='font-style:italic'>Title:. ActiveXObject SchemaCache object to ("Msxml2 .XML SchemaCache.4.0"); this property, the document XMLSchemaCache.add will be validated against the (XMLNamespaceName, associated XML schema "Book Schema.xsd"); when