var g_myXML;
var g_sVisitOrder = "Nodes visited: ";

function loadXMLData() {
    var sMyTestData = "<a><b type='test'><c><f /><g type='test' /></c><d /><e /></b><h><i type='test' /><j type='blah' /></h></a>";
    var oParser = new DOMParser();
    g_myXML = oParser.parseFromString(sMyTestData, "application/xml");
}

function depthFirstTraversal(oNode) {
    if (oNode != null) {
        for (var theNode = oNode.firstChild; theNode != null; theNode = theNode.nextSibling) {
            depthFirstTraversal(theNode);
        }
        g_sVisitOrder += oNode.nodeName + ", ";
    }
}

function breadthFirstTraversal(oNode) {
    if (oNode != null && oNode.hasChildNodes()) {
        for (var theNode = oNode.firstChild; theNode != null; theNode = theNode.nextSibling) {
            g_sVisitOrder += theNode.nodeName + ", ";
        }
        for (var theNode = oNode.firstChild; theNode != null; theNode = theNode.nextSibling) {
            breadthFirstTraversal(theNode);
        }
    }
}

function isContainedBy(oNode, oTestNode) {
    if (typeof (oTestNode) == "string") {
        var oTmpNode = oNode.parentNode;
        while (oTmpNode != null) {
            if (oTmpNode.nodeName == oTestNode) {
                return true;
            }
            oTmpNode = oTmpNode.parentNode;
        }
        return false;
    } else if (typeof (oTestNode) == "object") {
        var oTmpNode = oNode.parentNode;
        while (oTmpNode != null) {
            if (oTmpNode == oTestNode) {
                return true;
            }
            oTmpNode = oTmpNode.parentNode;
        }
        return false;
    }
}

function containsNode (oNode, oTestNode) {
    var bFound = false;
    if (typeof (oTestNode) == "string") {
        if (oNode.nodeName == oTestNode) {
            return true;
        }
    } else if (typeof (oTestNode) == "object") {
        if (oNode == oTestNode) {
            return true;
        }
    }
    for (var theNode = oNode.firstChild; theNode != null && !bFound; theNode = theNode.nextSibling) {
        bFound = containsNode(theNode, oTestNode);
    }
    return bFound;
}

function hasSibling(oNode, oTestNode) {
    var oTmpNode = oNode.previousSibling;
    while (oTmpNode != null) {
        if (typeof (oTestNode) == "string") {
            if (oTmpNode.nodeName == oTestNode) {
                return true;
            }
        } else if (typeof (oTestNode) == "object") {
            if (oTmpNode == oTestNode) {
                return true;
            }
        }
        oTmpNode = oTmpNode.previousSibling;
    }
    oTmpNode = oNode.nextSibling;
    while (oTmpNode != null) {
        if (typeof (oTestNode) == "string") {
            if (oTmpNode.nodeName == oTestNode) {
                return true;
            }
        } else if (typeof (oTestNode) == "object") {
            if (oTmpNode == oTestNode) {
                return true;
            }
        }
        oTmpNode = oTmpNode.nextSibling;
    }
    return false;
}

function getElementsByAttrVal(oNode, sAttName, sAttVal) {
    var aNodes = [];
    function processNodes(oNode, aNodeList, sAttName, sAttVal) {
        if (oNode.nodeType == Node.ELEMENT_NODE) {
            var sAttr = oNode.getAttribute(sAttName);
            if (sAttr) {
                if (sAttr == sAttVal) {
                    aNodeList.push(oNode);
                }
            }
            for (var n = oNode.firstChild; n != null; n = n.nextSibling) {
                processNodes(n, aNodeList, sAttName, sAttVal);
            }
        }
    }
    processNodes(oNode, aNodes, sAttName, sAttVal);
    return aNodes;
}