Each BOOK element in the example XML document contains an ENTITY type attribute named Review, which is assigned the name of an unparsed entity that contains a review of the particular bo
Trang 1388 XML Step by Step
Accessing XML Entities and Notations
As I explained in Chapter 6, you use an unparsed entity declaration to incorpo-rate an external data file into an XML document (All unparsed entities are of the general external type.) The way you use an unparsed entity is to assign its name to an attribute that has the ENTITY or ENTITIES type, as a means of as-sociating the external entity file with a particular XML element The XML pro-cessor doesn’t access an unparsed entity file Rather, it merely makes the
description of the entity and its notation available to the application, which can obtain and use the information appropriately
This section presents an XML document and an HTML page that demonstrate the basic steps for using the DOM to extract from an XML document the infor-mation on an entity as well as the notation that describes the entity’s format Listing 11-7 contains the example XML document and Listing 11-8 contains the example HTML page (You’ll find copies of these two listings on the companion
CD under the filenames Inventory Entity.xml and Inventory Entity.htm.)
Inventory Entity.xml
<?xml version="1.0"?>
<! File Name: Inventory Entity.xml >
<!DOCTYPE INVENTORY
[
<!NOTATION TXT SYSTEM "plain text file">
<!ENTITY rev_huck SYSTEM "Review of Huckleberry Finn.txt"
NDATA TXT>
<!ENTITY rev_leaves SYSTEM "Review of Leaves of Grass.txt"
NDATA TXT>
<!ENTITY rev_legend SYSTEM "Review of Sleepy Hollow.txt"
NDATA TXT>
<!ELEMENT INVENTORY (BOOK)*>
<!ELEMENT BOOK (TITLE, AUTHOR, BINDING, PAGES, PRICE)>
<!ATTLIST BOOK Review ENTITY #IMPLIED>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ELEMENT BINDING (#PCDATA)>
<!ELEMENT PAGES (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>
]
>
Trang 2Chapter 11 Displaying XML Documents Using Document Object Model Scripts 389
<INVENTORY>
<BOOK Review="rev_huck">
<TITLE>The Adventures of Huckleberry Finn</TITLE>
<AUTHOR>Mark Twain</AUTHOR>
<BINDING>mass market paperback</BINDING>
<PAGES>298</PAGES>
<PRICE>$5.49</PRICE>
</BOOK>
<BOOK Review="rev_leaves">
<TITLE>Leaves of Grass</TITLE>
<AUTHOR>Walt Whitman</AUTHOR>
<BINDING>hardcover</BINDING>
<PAGES>462</PAGES>
<PRICE>$7.75</PRICE>
</BOOK>
<BOOK Review="rev_legend">
<TITLE>The Legend of Sleepy Hollow</TITLE>
<AUTHOR>Washington Irving</AUTHOR>
<BINDING>mass market paperback</BINDING>
<PAGES>98</PAGES>
<PRICE>$2.95</PRICE>
</BOOK>
</INVENTORY>
Listing 11-7.
Inventory Entity.htm
<! File Name: Inventory Entity.htm >
<HTML>
<HEAD>
<TITLE>Get Entity Information</TITLE>
<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="ONLOAD">
Document = dsoInventory.XMLDocument;
Attribute =
Document.documentElement.childNodes(0).attributes(0);
if (Attribute.dataType == "entity")
{
DisplayText = "'" + Attribute.nodeName
+ "' attribute has ENTITY type" + "\n";
DisplayText += "attribute value = "
Trang 3390 XML Step by Step
+ Attribute.nodeValue + "\n";
Entity =
Document.doctype.entities.getNamedItem(Attribute.nodeValue); DisplayText += "entity file = "
+ Entity.attributes.getNamedItem("SYSTEM").nodeValue
+ "\n";
NotationName =
Entity.attributes.getNamedItem("NDATA").nodeValue;
DisplayText += "entity notation = " + NotationName + "\n"; Notation =
Document.doctype.notations.getNamedItem(NotationName); DisplayText += "notation URI or description = "
+ Notation.attributes.getNamedItem("SYSTEM").nodeValue + "\n";
alert (DisplayText);
location.href =
Entity.attributes.getNamedItem("SYSTEM").nodeValue;
}
</SCRIPT>
</HEAD>
<BODY>
<XML ID="dsoInventory" SRC="Inventory Entity.xml"></XML>
</BODY>
</HTML>
Listing 11-8.
Each BOOK element in the example XML document contains an ENTITY type
attribute named Review, which is assigned the name of an unparsed entity that
contains a review of the particular book The example HTML page includes a script that demonstrates the basic steps a DOM script must perform to extract all of the information about an entity when it encounters an attribute that has the ENTITY or ENTITIES type Specifically, the script extracts information on
the unparsed entity assigned to the Review attribute within the first BOOK
ele-ment It displays this information in an “alert” message box that looks like this:
Trang 4Chapter 11 Displaying XML Documents Using Document Object Model Scripts 391
Here’s a brief explanation of the basic steps that the script performs:
1 The script obtains the Attribute node for the Review attribute in the first
BOOK element:
Attribute Document.documentElement.childNodes(0).attributes(0);
2 The script uses the dataType node property (see Table 11-2) to determine
whether the attribute has the ENTITY type:
if (Attribute.dataType == “entity”) {
/* obtain entity information */
} The script performs the remaining steps only if the attribute does have the
ENTITY type That is, the remaining steps are included in the if statement, and are executed only when the if condition is true.
3 The script obtains the Entity node for the DTD declaration of the entity as-signed to the attribute:
Entity = Document.doctype.entities.getNamedItem(Attribute.nodeValue);
The Document property doctype (explained in Table 11-3) provides a
DocumentType node representing the document type declaration The
DocumentType property entities provides a NamedNodeMap collection of
Entity nodes for all entity declarations in the DTD The Entity node for the specific entity assigned to the attribute is obtained by passing the entity’s
name (Attribute.nodeValue) to the NamedNodeMap’s getNamedItem
method, which you saw in Table 11-7
4 The script obtains the entity’s system identifier, which specifies the URI of
the file containing the entity data The system identifier is stored as the value of an Attribute node named SYSTEM:
DisplayText += “entity file = “ + Entity.attributes.getNamedItem(“SYSTEM”).nodeValue + “\n”;
Trang 5Chapter 11 Displaying XML Documents Using Document Object Model Scripts 393
Create the Node-Traversing Page
1 Open a new, empty text file in your text editor, and type in the HTML page shown in Listing 11-9 (You’ll find a copy of this listing on the companion CD under the filename ShowNodes.htm)
2 Use your text editor’s Save command to save the document on your hard
disk, assigning it the filename ShowNodes.htm
ShowNodes.htm
<! File Name: ShowNodes.htm >
<HTML>
<HEAD>
<TITLE>Show DOM Nodes</TITLE>
<SCRIPT LANGUAGE="JavaScript" FOR="window" EVENT="ONLOAD"> /* get Document node: */
Document = dsoXML.XMLDocument;
/* start by passing the Document node to DisplayNodes: */ DisplayDIV.innerText = DisplayNodes (Document, 0);
function DisplayNodes (Node, IndentLevel) {
/* declare local variables for recursion: */
var i;
var DisplayString = "";
/* build up the indentation for this level: */
Indent = "";
IndentDelta = " ";
for (i=0; i < IndentLevel; ++i) Indent += IndentDelta;
/* display the current node's properties: */
DisplayString += Indent + "nodeName: "
+ Node.nodeName + "\n"
+ Indent + "nodeTypeType: "
+ Node.nodeType + "\n"
Trang 6394 XML Step by Step
+ Indent + "nodeTypeString: "
+ Node.nodeTypeString + "\n"
+ Indent + "nodeValue: "
+ Node.nodeValue + "\n\n";
/* display each of the node's attribute child nodes: */
Indent += IndentDelta;
for (i=0;
Node.attributes != null && i < Node.attributes.length;
++i) DisplayString += Indent + "nodeName: "
+ Node.attributes(i).nodeName + "\n"
+ Indent + "nodeTypeType: " + Node.attributes(i).nodeType + "\n"
+ Indent + "nodeTypeString: " + Node.attributes(i).nodeTypeString + "\n"
+ Indent + "nodeValue: "
+ Node.attributes(i).nodeValue + "\n\n";
/* display each of the node's nonattribute child nodes: */
for (i=0; i < Node.childNodes.length; ++i) DisplayString +=
DisplayNodes (Node.childNodes(i), IndentLevel + 1);
/* return the string containing the results: */ return DisplayString;
} </SCRIPT>
</HEAD>
<BODY>
<XML ID="dsoXML" SRC="Inventory Dom.xml"></XML>
Trang 7396 XML Step by Step
+ Indent + “nodeTypeString: “ + Node.nodeTypeString + “\n”
+ Indent + “nodeValue: “ + Node.nodeValue + “\n\n”;
tip
If you want to see additional properties for each node, you can add them to the preceding block of code You can use any of the common node properties given in Table 11-2 However, don’t use any of the node-specific properties (such as those given in Table 11-3 for Document nodes) because they aren’t available for all node types
■ It stores display information on the current node’s child Attribute nodes The indentation is increased by one level to indicate that these are child nodes of the current node:
/* display each of the node’s attribute child nodes: */ Indent += IndentDelta;
for (i=0;
Node.attributes != null && i < Node.attributes.length;
++i) DisplayString += Indent + “nodeName: “ + Node.attributes(i).nodeName + “\n” + Indent + “nodeTypeType: “
+ Node.attributes(i).nodeType + “\n” + Indent + “nodeTypeString: “
+ Node.attributes(i).nodeTypeString + “\n”
+ Indent + “nodeValue: “ + Node.attributes(i).nodeValue + “\n\n”;
note
DisplayNodes doesn’t display the superfluous child Text node of an Attribute
node, because it’s more convenient to obtain the attribute’s value directly from
the nodeValue property of the Attribute node itself.
Trang 8398 XML Step by Step
4 To view the node structure of other XML documents, edit the page’s data island For example, to view the nodes in Inventory Valid Entity.xml (given
in Listing 6-1 and provided on the companion CD), you would edit the data island so that it reads like this:
<XML ID=”dsoXML” SRC=”Inventory Valid Entity.xml”></XML>
Checking an XML Document for Validity
The final sections of this chapter present two HTML pages that you can use to check the validity of your XML documents The first page checks an XML document’s validity against a document type definition (DTD) contained in or referenced by the document The second page checks a document’s validity against an XML schema contained in a separate file Creating valid XML docu-ments using DTDs was covered in Chapters 5 and 6, and creating valid XML documents using XML schemas was covered in Chapter 7 The topic of check-ing documents for validity was postponed until the current chapter because the techniques require using a script and the Document object of the DOM
Checking an XML Document for Validity Using a DTD
The DTD validity-testing HTML page contains a script that opens an XML document and uses DOM properties to report any errors that it contains
If the document doesn’t have a document type declaration, the page reports only well-formedness errors If the document includes a document type declara-tion, the page reports both well-formedness and validity errors You can use this page to test any XML document (But keep in mind that if you want to check merely the well-formedness of a document—perhaps one without a DTD—you can do so by simply opening the document directly in Internet Explorer.)
How to Use the DTD Validity-Testing Page
1 In your text editor, open the DTD validity-testing page, Validity Test
DTD.htm (You’ll find this file on the companion CD and in Listing 11-10 in the next section.)
2 Edit the data island in the BODY of the page so that its SRC attribute is assigned the URL of the XML document you want to test For example,
to test the document Raven.xml, you would edit the data island to read like this:
<XML ID=”dsoTest” SRC=”Raven.xml”></XML>
Typically, the XML document is contained in the same folder as the validity-testing page, so you need enter only the XML document’s filename, as in the example above
Trang 9Chapter 11 Displaying XML Documents Using Document Object Model Scripts 399
3 Use your text editor’s Save command to save the modified page
4 Open the page in Internet Explorer:
The page will display a message box indicating the error status of the docu-ment If the document contains no well-formedness or validity errors, the message box appears like this:
If, however, the document contains one or more well-formedness or validity errors, the message box will display the first error encountered, like this:
How the DTD Validity-Testing Page Works
When Internet Explorer loads an XML document that’s contained in or refer-enced by a data island in an HTML page, the processor automatically checks the document for well-formedness and—if the document contains a document type declaration—for validity After the processor loads the document (or at-tempts to load the document; it will quit if it encounters an error), it assigns
information on the document’s error status to the parseError property of the Document node for that document The parseError property will contain either
a code indicating that the document is error-free, or complete information on the first well-formedness or validity error that was encountered The DTD
validity-testing page presented here contains a script that uses parseError to
display error information on the XML document that’s linked to the page
through the data island
Trang 10Chapter 11 Displaying XML Documents Using Document Object Model Scripts 401
<! set SRC to the URL of the XML document you want to
check: >
<XML ID="dsoTest" SRC="Inventory Valid.xml"></XML>
<H2>DTD Validity Tester</H2>
</BODY>
</HTML>
Listing 11-10.
The HTML page contains a script that it runs when the browser first opens the window for the page:
<SCRIPT LANGUAGE=”JavaScript” FOR=”window” EVENT=”ONLOAD”>
/* script code */
</SCRIPT>
The script first obtains the Document node for the XML document that is linked through the data island:
Document = dsoTest.XMLDocument;
By the time the script receives control, the Internet Explorer XML processor has already loaded—or attempted to load—the XML document, and the document’s
error status is contained in the Document node’s parseError property The
parseError property is a programming object with its own set of properties The script concludes by displaying all of the parseError properties:
message = "parseError.errorCode: "
+ Document.parseError.errorCode + "\n"
+ "parseError.filepos: "
+ Document.parseError.filepos + "\n"
+ "parseError.line: " + Document.parseError.line
+ "\n"
+ "parseError.linepos: "
+ Document.parseError.linepos + "\n"
+ "parseError.reason: "
+ Document.parseError.reason + "\n"
+ "parseError.srcText: "
+ Document.parseError.srcText + "\n"
+ "parseError.url: " + Document.parseError.url;
alert (message);