| <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> |
| |
| |
| <SCRIPT LANGUAGE="JScript"> |
| |
| //<xml id=xmldoc></xml> |
| var xmldoc = new ActiveXObject("IBMXML.XMLDOMDocument"); |
| // ********************************************************************* |
| // * 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; |
| } |
| |
| if (node.nodeTypeString != "text") |
| result += "<span class=tag><" + node.nodeName + "</span>"; |
| |
| // determine if the tag has children or is empty |
| |
| var num; |
| |
| // process the attributes |
| if (node.attributes != null && 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; |
| |
| if (node.nodeTypeString != "text") { |
| // 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"; |
| } |
| else |
| if (node.nodeTypeString == "text" || node.nodeTypeString == "cdata_section" || |
| node.nodeTypeString == "entity_reference") |
| result += node.text; |
| } |
| |
| 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> |