| <HTML> | |
| <BODY BGCOLOR="#FFFFFF" onload="windowLoad()"> | |
| <H2>XML Tree Viewer</H2> | |
| <HR> | |
| <B>Enter the location of the XML file: </B> | |
| <INPUT ID="XMLFile" TYPE="text" SIZE="30" VALUE="sample.xml" | |
| onkeydown="loadEnter()"></INPUT> | |
| <INPUT ID="loadButton" TYPE="button" onClick="loadXML()" | |
| VALUE="Load XML and Display Tree"></INPUT> | |
| <HR> | |
| <BUTTON onClick="displayTree()">Refresh Tree Display</BUTTON> | |
| <BUTTON onClick="showXML()">Show XML</BUTTON> | |
| <HR> | |
| <B>Using the XML Object Model, navigate to an XML element, attribute, or node list (for | |
| example, enter xmldoc.documentElement in the text area to navigate to the root node). The | |
| node(s) you navigate to will be highlighted in blue: </B> | |
| <INPUT ID="selectionString" TYPE="text" SIZE="40" | |
| onkeydown="selectionEnter()" VALUE=""></INPUT> | |
| <INPUT ID="selectionButton" TYPE="button" | |
| onClick="genericSelect()" VALUE="Display Selection"></INPUT> | |
| <BR> | |
| <HR> | |
| Legend: <FONT COLOR="red">Text</FONT>, <FONT COLOR="green">Attribute</FONT>, <FONT COLOR="purple">Comment</FONT>, <FONT COLOR="blue">Highlighted node(s)</FONT> | |
| </BODY> | |
| <xml id=xmldoc></xml> | |
| <SCRIPT LANGUAGE="JScript"> | |
| // ********************************************************************* | |
| // * Constants declarations | |
| // ********************************************************************* | |
| var blue = "#0000FF"; | |
| var black = "#000000"; | |
| var attributeColor = "green"; | |
| var textColor = "red"; | |
| var commentColor = "purple"; | |
| var attID = "tv:TreeViewerID"; // Name of the attribute add to the | |
| // tree to point to the span id. | |
| var nsName = "msTreeViewer"; // Name of the namespace that will hold | |
| // the attribute that is added. | |
| var ELEMENT_NODE = 1; | |
| var ATTRIBUTE_NODE = 2; | |
| var NAMESPACE_NODE = 7; // 7 is for processing instruction. | |
| var TEXT_NODE = 3; | |
| var COMMENT_NODE = 8; | |
| var CDATA_NODE = 4; | |
| var ENTITYREF_NODE = 5; | |
| // ********************************************************************* | |
| // * Variable declarations | |
| // ********************************************************************* | |
| var strStruct; // string that holds the html version of the tree. | |
| var elementNum; // Counter to keep track of what to call the | |
| // span id in the html display version of | |
| // the tree. | |
| var code; // Array that holds information about whether | |
| // to display the | or not. | |
| var selectedNodes; // Keeps track of which nodes are highlighted. | |
| var selectedNodesType; | |
| var selectedNodesLength; // Keeps track of how many nodes are highlighted. | |
| var displayFrame; // display frame (displayFrame = parent.display) | |
| var treeViewNS = "urn:tv";// The Tree Viewer namespace node. | |
| var tempNode; // Used by user in executeString. | |
| // ********************************************************************* | |
| // * Helper functions | |
| // ********************************************************************* | |
| // Reset on reload. | |
| function windowLoad() | |
| { | |
| displayFrame = parent.display; | |
| displayFrame.document.open(); | |
| displayFrame.document.write(""); | |
| displayFrame.document.close(); | |
| selectionString.value = ""; | |
| XMLFile.focus(); | |
| } | |
| // Automatically click button when user presses enter. | |
| function loadEnter() | |
| { | |
| if (event.keyCode == 13) // 13 is keyCode for enter. | |
| { | |
| loadButton.click(); | |
| selectionString.focus(); | |
| } | |
| } | |
| // Automatically click button when user presses enter. | |
| function selectionEnter() | |
| { | |
| if (event.keyCode == 13) | |
| selectionButton.click(); | |
| } | |
| // *********************************************************************** | |
| // * Selection highlighting functions | |
| // *********************************************************************** | |
| // Called by the 'Display Selection' button. | |
| // Unhighlights the previously highlighted nodes. | |
| // Decides if the entry points to an attribute node, element node or node list and calls | |
| // the appropriate handler. | |
| function genericSelect() | |
| { | |
| if (xmldoc == null) | |
| { | |
| alert("No xml file has been loaded."); | |
| selectionString.value = ""; | |
| } | |
| else | |
| { | |
| // Only choices are nodeList, node or attributes. | |
| // This try...catch block needs JScript version 5 which comes with IE5. | |
| try | |
| { | |
| selection = eval(selectionString.value); | |
| } | |
| catch(e) | |
| { | |
| selection = null; | |
| } | |
| if (selection == null) | |
| alert("Only element nodes, attribute nodes and node lists can be specified."); | |
| else | |
| { | |
| // Unselect previously selected nodes. | |
| if (selectedNodesLength != 0) | |
| { | |
| for (var i = 0; i < selectedNodesLength; i++) | |
| { | |
| if (selectedNodesType[i] == "attribute") | |
| parent.display.document.all.item(selectedNodes[i]).style.color = attributeColor; | |
| else | |
| parent.display.document.all.item(selectedNodes[i]).style.color = black; | |
| } | |
| } | |
| selectedNodesLength = 0; | |
| // Call appropriate handler. | |
| if (selection.length != null) // Note this is also true for | |
| //strings and other non nodeLists. | |
| selectNodeList(selection); | |
| else if (selection.nodeTypeString == "element") | |
| selectNode(selection); | |
| else if (selection.nodeTypeString == "attribute") | |
| selectAtt(selection); | |
| else | |
| alert("Only element nodes, attribute nodes and node lists can be specified."); | |
| } | |
| } | |
| } | |
| // Highlight an attribute node. | |
| // | |
| // Since attributes can't have attributes, they are counted off | |
| // from the parent element. | |
| function selectAtt(att) | |
| { | |
| var elem = att.selectSingleNode("ancestor(.)"); | |
| attNum = elem.attributes.length; | |
| // Find the offset for the attribute. | |
| for (var i = 0; i < attNum; i++) | |
| if (elem.attributes.item(i).nodeName == att.nodeName) | |
| break; | |
| if (elem.attributes.getNamedItem(attID) != null) { | |
| var nodeID = elem.attributes.getNamedItem(attID).nodeValue + "_att_" + i; | |
| selectedNodes[selectedNodesLength] = nodeID; | |
| selectedNodesType[selectedNodesLength] = "attribute"; | |
| selectedNodesLength++; | |
| parent.frames("display").document.all(nodeID).style.color = blue; | |
| } | |
| } | |
| // Highlight an element node. | |
| function selectNode(node) | |
| { | |
| var nodeID; | |
| if (node.attributes.getNamedItem(attID) != null) { | |
| nodeID = node.attributes.getNamedItem(attID).nodeValue; | |
| selectedNodes[selectedNodesLength] = nodeID; | |
| selectedNodesType[selectedNodesLength] = "element"; | |
| selectedNodesLength++; | |
| parent.display.document.all(nodeID).style.color = blue; | |
| } | |
| } | |
| // Highlight a node list. | |
| function selectNodeList(list) | |
| { | |
| selectedNodesLength = list.length; | |
| for (var i = 0; i < list.length; i++) | |
| { | |
| // Only highlight elems and attrs (other stuff isn't in tree) | |
| if (list(i).nodeTypeString == "element") | |
| selectNode(list(i)); | |
| else if (list(i).nodeTypeString == "attribute") | |
| selectAtt(list(i)); | |
| } | |
| } | |
| // ******************************************************************** | |
| // * Tree loading and displaying functions | |
| // ******************************************************************** | |
| // Create the msxml object and load the specified xml file. | |
| function loadXML() | |
| { | |
| if (XMLFile.value == "") | |
| { | |
| alert("An xml file must be specified for loading to occur."); | |
| } | |
| else | |
| { | |
| xmldoc.async = false; | |
| xmldoc.load(XMLFile.value); | |
| if (xmldoc.parseError.errorCode != 0) | |
| { | |
| alert(errtxt); | |
| windowLoad(); | |
| } | |
| if (xmldoc.documentElement != null) | |
| { | |
| // Create the TreeViewer namespace here. | |
| //treeViewNS = xmldoc.createNode("attribute","xmlns:treeview", ""); | |
| //treeViewNS = nsName; // Setup the short name. | |
| //xmldoc.documentElement.attributes.setNamedItem(treeViewNS); | |
| //xmldoc.insertNode(treeViewNS); | |
| displayTree(); | |
| selectionString.value = "xmldoc."; | |
| } | |
| } | |
| } | |
| // This function isolates the process of add the xml to the tree view. | |
| function addhtml(text) | |
| { | |
| strStruct += text; | |
| } | |
| // Use the recursive function buildTree to build the html | |
| // version of the tree. Display the tree in a seperate frame. | |
| function displayTree() | |
| { | |
| if (xmldoc == null) | |
| { | |
| alert("No xml file has been loaded."); | |
| } | |
| else | |
| { | |
| selectedNodes = new Array(); | |
| selectedNodesType = new Array(); | |
| selectedNodesLength = 0; | |
| //displayFrame = parent.display; | |
| //displayFrame.document.open(); | |
| strStruct = ""; | |
| //addhtml("<HTML><BODY BGCOLOR=\"#FFFFFF\">"); // #FFFFFF is white. | |
| elementNum = 0; | |
| code = new Array(); | |
| //buildTree(xmldoc.documentElement, 0, ("XMLtree_" + elementNum),0); | |
| buildTree(xmldoc.documentElement, 0, 0); | |
| displayFrame.document.open(); | |
| displayFrame.document.write(strStruct); | |
| displayFrame.document.close(); | |
| } | |
| } | |
| // buildTree is recursive. | |
| // level is the depth of the tree. | |
| // last is a boolean to tell the element if it's the last one | |
| // in the list. 1=true, 0=false. The last one needs corner.gif. | |
| function buildTree(node, level, last) | |
| { | |
| if (level != 0) | |
| { | |
| // Add | and whitespace | |
| for (var j = 0; j < (level-1); j++) | |
| { | |
| if (code[j] == 0) | |
| addhtml("<IMG SRC=\"vertical.gif\" ALIGN=\"absbottom\"> "); | |
| else | |
| addhtml( "<IMG SRC=\"blank.gif\" ALIGN=\"absbottom\"> "); | |
| } | |
| // Add the appropriate corner piece. | |
| if (last == 1) | |
| addhtml("<IMG SRC=\"corner.gif\" ALIGN=\"absbottom\"> "); | |
| else | |
| addhtml("<IMG SRC=\"corner_continue.gif\" ALIGN=\"absbottom\"> "); | |
| } | |
| // Process a text node. | |
| if (node.nodeType == TEXT_NODE) | |
| addhtml("<FONT COLOR=\"" + textColor + "\">" + node.text + "</FONT>"); | |
| else if (node.nodeType == COMMENT_NODE) | |
| addhtml("<FONT COLOR=\"" + commentColor + "\">" + node.text + "</FONT>"); | |
| else | |
| { | |
| // Don't do the following on text nodes. Don't give them | |
| // spans or check for attributes. | |
| // Make a span with a unique ID for each element to be able to | |
| // access them later. | |
| var elementID = "TreeViewer_" + elementNum; | |
| addhtml("<SPAN ID=\"" + elementID + "\">" + node.nodeName + "</SPAN>"); | |
| elementNum++; // Increment ID counter. | |
| // Put an attribute on each element that acts as pointers to | |
| // their corresponding span tags. | |
| //node.setAttribute(attID, elementID, treeViewNS); | |
| var tvNode = xmldoc.createNode("attribute",attID,treeViewNS); | |
| tvNode.text = elementID; | |
| node.attributes.setNamedItem(tvNode); | |
| // Display attributes | |
| var attNum = node.attributes.length; | |
| if (attNum > 0) | |
| { | |
| for (var i = 0; i < attNum; i++) | |
| { | |
| // Don't display attributes from the Tree Viewer namespace. | |
| if (node.attributes.item(i).namespace != null) | |
| { | |
| if (node.attributes.item(i).namespace != treeViewNS) | |
| addhtml("<B> ; </B><SPAN ID=\"" + elementID + "_att_" + i + "\" STYLE=\"color:green\">" + node.attributes.item(i).nodeName + "</SPAN>"); | |
| //+ " = \"" + node.attributes.item(i).text + "\""; | |
| } | |
| else | |
| { | |
| addhtml("<B> ; </B><SPAN ID=\"" + elementID + "_att_" + i + "\" STYLE=\"color:green\" >" + node.attributes.item(i).nodeName + "</SPAN>"); // + " = \"" + node.attributes.item(i).text + "\""; | |
| } | |
| } | |
| } | |
| } | |
| addhtml("<BR>"); | |
| // If there are children under this node, call buildTree on them. | |
| var children = node.childNodes.length; | |
| if (children != 0) | |
| { | |
| for (var i = 0; i < children; i++) | |
| { | |
| if (i == (children - 1) ) | |
| { | |
| // This case means we are at the last element. | |
| code[level] = 1; | |
| buildTree(node.childNodes.item(i), (level + 1), 1); | |
| } | |
| else | |
| { | |
| code[level] = 0; | |
| buildTree(node.childNodes.item(i), (level + 1), 0); | |
| } | |
| } | |
| } | |
| } | |
| // ******************************************************************** | |
| // * Displaying XML in a seperate window functions | |
| // ******************************************************************** | |
| function showXML() | |
| { | |
| if (xmldoc == null) | |
| { | |
| alert("No xml file has been loaded."); | |
| } | |
| else | |
| { | |
| var txtToShow = dumpTree(xmldoc.documentElement, 0); | |
| var wNew = window.open(); | |
| wNew.document.body.innerHTML = "<B>"+txtToShow+"</B>"; | |
| } | |
| } | |
| // Format the XML into HTML | |
| function dumpTree(node, i) | |
| { | |
| var result = "<DL class=xml><DD>"; | |
| if (node != null) | |
| { | |
| if (node.nodeTypeString == "comment") | |
| { | |
| result += "<span class=comment><!--" + node.text + "--></span>" + "</DD></DL>"; | |
| return result; | |
| } | |
| result += "<span class=tag><" + node.nodeName + "</span>"; | |
| // determine if the tag has children or is empty | |
| var num; | |
| // process the attributes | |
| if (node.attributes.length > 0) | |
| { | |
| var a, i, l; | |
| l = node.attributes.length; | |
| for (i = 0; i < l; i++) | |
| { | |
| a = node.attributes.item(i); | |
| // Don't display attributes from the Tree Viewer namespace. | |
| if (a.namespace != treeViewNS) | |
| result += "<span class=attr> " + a.nodeName + "=\"" + a.text + "\"</span>" | |
| } | |
| } | |
| if (node.childNodes != null) | |
| num = node.childNodes.length; | |
| else | |
| num = 0; | |
| // close the element tag (if empty, use shorthand) | |
| if (num == 0) // tag is empty | |
| result += "<span class=tag>/></span>"; | |
| else | |
| result += "<span class=tag>></span>"; | |
| // process the children of the element if it has any | |
| if (num > 0) // tag has children | |
| { | |
| if (isMixed(node,num) > 0) | |
| { | |
| result += node.text; | |
| } | |
| else | |
| { | |
| var j; | |
| for (j = 0; j < num; j++) | |
| { | |
| result += "\n"; | |
| var child = node.childNodes.item(j); | |
| // uncommented following line | |
| result += dumpTree(child,i + 1); | |
| } | |
| } | |
| result += "<span class=tag></" + node.nodeName + "></span>\n"; | |
| } | |
| } | |
| result += "</DD></DL>" | |
| return result; | |
| } | |
| // checks to see if all children of the element are | |
| // the same node type | |
| function isMixed(node,num) | |
| { | |
| var j; | |
| for (j = 0; j < num; j++) | |
| { | |
| var child = node.childNodes.item(j); | |
| var type = child.nodeTypeString; | |
| if (type == "text" || type == "cdata_section" || | |
| type == "entity_reference") | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| </SCRIPT> | |
| </HTML> |