FileDocCategorySizeDatePackage
DOMUtil.javaAPI DocApache Ant 1.708691Wed Dec 13 06:16:22 GMT 2006org.apache.tools.ant.taskdefs.optional.junit

DOMUtil

public final class DOMUtil extends Object
Some utilities that might be useful when manipulating DOM trees.

Fields Summary
Constructors Summary
private DOMUtil()
unused constructor

    
Methods Summary
public static org.w3c.dom.ElementgetChildByTagName(org.w3c.dom.Node parent, java.lang.String tagname)
Iterate over the children of a given node and return the first node that has a specific name.

param
parent the node to search child from. Can be null.
param
tagname the child name we are looking for. Cannot be null.
return
the first child that matches the given name or null if the parent is null or if a child does not match the given name.

        if (parent == null) {
            return null;
        }
        NodeList childList = parent.getChildNodes();
        final int len = childList.getLength();
        for (int i = 0; i < len; i++) {
            Node child = childList.item(i);
            if (child != null && child.getNodeType() == Node.ELEMENT_NODE
                && child.getNodeName().equals(tagname)) {
                return (Element) child;
            }
        }
        return null;
    
public static java.lang.StringgetNodeAttribute(org.w3c.dom.Node node, java.lang.String name)
return the attribute value of an element.

param
node the node to get the attribute from.
param
name the name of the attribute we are looking for the value.
return
the value of the requested attribute or null if the attribute was not found or if node is not an Element.

        if (node instanceof Element) {
            Element element = (Element) node;
            return element.getAttribute(name);
        }
        return null;
    
public static org.w3c.dom.NodeimportNode(org.w3c.dom.Node parent, org.w3c.dom.Node child)
Simple tree walker that will clone recursively a node. This is to avoid using parser-specific API such as Sun's changeNodeOwner when we are dealing with DOM L1 implementations since cloneNode(boolean) will not change the owner document. changeNodeOwner is much faster and avoid the costly cloning process. importNode is in the DOM L2 interface.

param
parent the node parent to which we should do the import to.
param
child the node to clone recursively. Its clone will be appended to parent.
return
the cloned node that is appended to parent

        Node copy = null;
        final Document doc = parent.getOwnerDocument();

        switch (child.getNodeType()) {
        case Node.CDATA_SECTION_NODE:
            copy = doc.createCDATASection(((CDATASection) child).getData());
            break;
        case Node.COMMENT_NODE:
            copy = doc.createComment(((Comment) child).getData());
            break;
        case Node.DOCUMENT_FRAGMENT_NODE:
            copy = doc.createDocumentFragment();
            break;
        case Node.ELEMENT_NODE:
            final Element elem = doc.createElement(((Element) child).getTagName());
            copy = elem;
            final NamedNodeMap attributes = child.getAttributes();
            if (attributes != null) {
                final int size = attributes.getLength();
                for (int i = 0; i < size; i++) {
                    final Attr attr = (Attr) attributes.item(i);
                    elem.setAttribute(attr.getName(), attr.getValue());
                }
            }
            break;
        case Node.ENTITY_REFERENCE_NODE:
            copy = doc.createEntityReference(child.getNodeName());
            break;
        case Node.PROCESSING_INSTRUCTION_NODE:
            final ProcessingInstruction pi = (ProcessingInstruction) child;
            copy = doc.createProcessingInstruction(pi.getTarget(), pi.getData());
            break;
        case Node.TEXT_NODE:
            copy = doc.createTextNode(((Text) child).getData());
            break;
        default:
            // this should never happen
            throw new IllegalStateException("Invalid node type: " + child.getNodeType());
        }

        // okay we have a copy of the child, now the child becomes the parent
        // and we are iterating recursively over its children.
        try {
            final NodeList children = child.getChildNodes();
            if (children != null) {
                final int size = children.getLength();
                for (int i = 0; i < size; i++) {
                    final Node newChild = children.item(i);
                    if (newChild != null) {
                        importNode(copy, newChild);
                    }
                }
            }
        } catch (DOMException ignored) {
            // Ignore
        }

        // bingo append it. (this should normally not be done here)
        parent.appendChild(copy);
        return copy;
    
public static org.w3c.dom.NodeListlistChildNodes(org.w3c.dom.Node parent, org.apache.tools.ant.taskdefs.optional.junit.DOMUtil$NodeFilter filter, boolean recurse)
list a set of node that match a specific filter. The list can be made recursively or not.

param
parent the parent node to search from
param
filter the filter that children should match.
param
recurse true if you want the list to be made recursively otherwise false.
return
the node list that matches the filter.

        NodeListImpl matches = new NodeListImpl();
        NodeList children = parent.getChildNodes();
        if (children != null) {
            final int len = children.getLength();
            for (int i = 0; i < len; i++) {
                Node child = children.item(i);
                if (filter.accept(child)) {
                    matches.addElement(child);
                }
                if (recurse) {
                    NodeList recmatches = listChildNodes(child, filter, recurse);
                    final int reclength = recmatches.getLength();
                    for (int j = 0; j < reclength; j++) {
                        matches.addElement(recmatches.item(i));
                    }
                }
            }
        }
        return matches;