package iiuf.dom;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
/**
(c) 2000, IIUF<p>
DOM Utilities
@author $Author: ohitz $
@version $Revision: 1.1 $
*/
public class DOMUtils {
/** Get all descendant elements.
@param element Element whose descendants we want to search for elements
@return List of elements */
public static NodeList getDescendantElements(Element element) {
ElementList list = new ElementList();
getDescendants(list, element);
return list;
}
private static void getDescendants(ElementList list, Element current) {
NodeList nl = getChildElements(current);
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
list.add(e);
getDescendants(list, e);
}
}
/** Get all descendant elements with a certain tag name.
@param element Element whose descendants we want to search for elements
@param tagname Desired tag name
@return List of elements */
public static NodeList getDescendantElements(Element element, String tagname) {
ElementList list = new ElementList();
getDescendants(list, element, tagname);
return list;
}
private static void getDescendants(ElementList list, Element current, String tagname) {
NodeList nl = getChildElements(current);
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
if (e.getTagName().equals(tagname)) {
list.add(e);
}
getDescendants(list, e, tagname);
}
}
/** Get all descendant elements with one of the tagnames.
@param element Element whose descendants we want to search for elements
@param tagnames list of desired tag names
@return List of elements */
public static NodeList getDescendantElements(Element element, LinkedList tagnames) {
ElementList list = new ElementList();
getDescendants(list, element, tagnames);
return list;
}
private static void getDescendants(ElementList list, Element current, LinkedList tagnames) {
NodeList nl = getChildElements(current);
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
if (tagnames.contains(e.getTagName())) {
list.add(e);
}
getDescendants(list, e, tagnames);
}
}
/** Remove all descendant elements with a certain tag name.
@param element Element whose descendants we want to search for elements
@param tagname Desired tag name
*/
public static void removeDescendantElements(Element element, String tagname) {
NodeList nl = getChildElements(element);
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
if (e.getTagName().equals(tagname)) {
element.removeChild(e);
}
else {
removeDescendantElements(e, tagname);
}
}
}
/** True if element has children elements
@param element element that we wanted to know if it has children
@return true if element has children elements
*/
public static boolean hasChildElements(Element element) {
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
return true;
}
}
return false;
}
/** Get all element children of an element.
@param element Element whose children we want to search for elements
@return List of elements */
public static NodeList getChildElements(Element element) {
NodeList childs = element.getChildNodes();
ElementList list = new ElementList();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
list.add(node);
}
}
return list;
}
public final static int TYPE_ATTRIBUTE = 0x0001;
public final static int TYPE_CDATA = 0x0002;
public final static int TYPE_COMMENT = 0x0004;
public final static int TYPE_DOCUMENT_FRAGMENT = 0x0008;
public final static int TYPE_DOCUMENT = 0x0010;
public final static int TYPE_DOCUMENT_TYPE = 0x0020;
public final static int TYPE_ELEMENT = 0x0040;
public final static int TYPE_ENTITY = 0x0080;
public final static int TYPE_NOTATION = 0x0100;
public final static int TYPE_PROCESSING_INSTRUCTION = 0x0200;
public final static int TYPE_TEXT = 0x0400;
private static HashMap nodeTypes = new HashMap();
static {
nodeTypes.put(new Integer(Node.ATTRIBUTE_NODE), new Integer(TYPE_ATTRIBUTE));
nodeTypes.put(new Integer(Node.CDATA_SECTION_NODE), new Integer(TYPE_CDATA));
nodeTypes.put(new Integer(Node.COMMENT_NODE), new Integer(TYPE_COMMENT));
nodeTypes.put(new Integer(Node.DOCUMENT_FRAGMENT_NODE), new Integer(TYPE_DOCUMENT_FRAGMENT));
nodeTypes.put(new Integer(Node.DOCUMENT_NODE), new Integer(TYPE_DOCUMENT));
nodeTypes.put(new Integer(Node.DOCUMENT_TYPE_NODE), new Integer(TYPE_DOCUMENT_TYPE));
nodeTypes.put(new Integer(Node.ELEMENT_NODE), new Integer(TYPE_ELEMENT));
nodeTypes.put(new Integer(Node.ENTITY_NODE), new Integer(TYPE_ENTITY));
nodeTypes.put(new Integer(Node.NOTATION_NODE), new Integer(TYPE_NOTATION));
nodeTypes.put(new Integer(Node.PROCESSING_INSTRUCTION_NODE), new Integer(TYPE_PROCESSING_INSTRUCTION));
nodeTypes.put(new Integer(Node.TEXT_NODE), new Integer(TYPE_TEXT));
}
/** Get all childs of an element matching one of the given types.
@param element Element whose children we want to search.
@param types Types of children we want to get.
@return List of nodes found. */
public static NodeList getChilds(Element element, int types) {
NodeList childs = element.getChildNodes();
ElementList list = new ElementList();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
Integer t = (Integer) nodeTypes.get(new Integer(node.getNodeType()));
if (t != null && ((types & t.intValue()) != 0)) {
list.add(node);
}
}
return list;
}
/** Get all children of an element having the specified tag name.
@param element Element whose children we want to search
@param tagname Desired tag name
@return List of elements having these tag name */
public static NodeList getChildsByTagName(Element element, String tagname) {
NodeList childs = element.getChildNodes();
ElementList list = new ElementList();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
if (tagname.equals(node.getNodeName())) {
list.add(node);
}
}
}
return list;
}
/** Get the first element child having the specified tag name.
@param element Element whose children we want to search
@param tagname Desired tag name
@return The first element having this tag name */
public static Element getFirstElement(Element element, String tagname) {
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
if (tagname.equals(node.getNodeName())) {
return (Element) node;
}
}
}
return null;
}
/** Get the first element child having the specified tag name.
@param element Element whose children we want to search
@param namespace Desired name space URI
@param tagname Desired tag name
@return The first element having this tag name */
public static Element getFirstElement(Element element, String namespace, String tagname) {
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
if (namespace.equals(node.getNamespaceURI()) &&
tagname.equals(node.getNodeName())) {
return (Element) node;
}
}
}
return null;
}
/** Get the first element descendant having the specified attribute
name and value.
@param element Element whose children we want to search
@param attribute Attribute name
@param value Attribute value
@return The first element having this attribute value */
public static Element getElementWithAttribute(Element element, String attribute, String value) {
String attr = element.getAttribute(attribute);
if (attr != null && (attr.compareTo(value)==0)) {
return element;
}
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
Element e = getElementWithAttribute((Element) node, attribute, value);
if (e != null) return e;
}
}
return null;
}
/** Get the elements descendant having the specified attribute
name and value.
@param element Element whose children we want to search
@param attribute Attribute name
@param value Attribute value
@return list of the elements having this attribute value */
public static LinkedList getElementsWithAttribute(Element element, String attribute, String value) {
LinkedList elements = new LinkedList();
if (element.hasAttribute(attribute)) {
String attr = element.getAttribute(attribute);
if (attr.equals(value)) {
elements.add(element);
}
}
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
elements = getElementsWithAttribute((Element) node, attribute, value, elements);
}
}
return elements;
}
private static LinkedList getElementsWithAttribute(Element element,
String attribute,
String value,
LinkedList elements) {
if (element.hasAttribute(attribute)) {
String attr = element.getAttribute(attribute);
if (attr.equals(value)) {
elements.add(element);
}
}
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
elements = getElementsWithAttribute((Element) node, attribute, value, elements);
}
}
return elements;
}
/** Get the elements descendant having the specified attribute
name.
@param element Element whose children we want to search
@param attribute Attribute name
@return list of the elements having this attribute value */
public static LinkedList getElementsWithAttribute(Element element, String attribute) {
LinkedList elements = new LinkedList();
if (element.hasAttribute(attribute)) {
// String attr = element.getAttribute(attribute);
// System.out.println("element : "+element+"; attribute : "+attr);
// System.out.println("attribute != null");
elements.add(element);
}
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
elements = getElementsWithAttribute((Element) node, attribute, elements);
}
}
return elements;
}
private static LinkedList getElementsWithAttribute(Element element,
String attribute,
LinkedList elements) {
// String attr = element.getAttribute(attribute);
// System.out.println("private : element : "+element+"; attribute : "+attr);
if (element.hasAttribute(attribute)) {
elements.add(element);
}
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
elements = getElementsWithAttribute((Element) node, attribute, elements);
}
}
return elements;
}
/** Get the first element descendant having the specified attribute
name and value.
@param element Element whose children we want to search
@param namespaceURI Attribute namespace URI
@param attribute Attribute name
@param value Attribute value
@return The first element having this attribute value */
public static Element getElementWithAttributeNS(Element element, String namespaceURI, String attribute, String value) {
String attr = element.getAttributeNS(namespaceURI, attribute);
if (attr != null && attr.equals(value)) {
return element;
}
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
Element e = getElementWithAttributeNS((Element) node, namespaceURI, attribute, value);
if (e != null) return e;
}
}
return null;
}
/** Remove all attributes with a certain namespace from this element.
@param element Element whose attributes we want to remove.
@param namespaceURI Namespace URI of the attributes to remove. */
public static void removeAttributes(Element e, String namespaceURI) {
NamedNodeMap attributes = e.getAttributes();
ArrayList list = new ArrayList();
for (int i = 0; i < attributes.getLength(); i++) {
Attr a = (Attr) attributes.item(i);
if (namespaceURI.equals(a.getNamespaceURI())) {
list.add(a);
}
}
Iterator i = list.iterator();
while (i.hasNext()) {
e.removeAttributeNode((Attr) i.next());
}
}
public static void removeAttributesFromDescendants(Element e, String namespaceURI) {
removeAttributes(e, namespaceURI);
NodeList childs = getChildElements(e);
for (int i = 0; i < childs.getLength(); i++) {
removeAttributesFromDescendants((Element) childs.item(i), namespaceURI);
}
}
/** Get the value of the first text child of an element.
@param element Element whose text element we want
@return String value or null. */
public static String getTextValue(Element element) {
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.TEXT_NODE == node.getNodeType()) {
return node.getNodeValue();
}
}
return null;
}
/** Replace the first text element of the given element with a new
text element containing the given text or just create a new text
element if there is none to replace.
@param element Element whose text element we want
@param text Text to set */
public static void setTextValue(Element element, String text) {
Node newTextNode = element.getOwnerDocument().createTextNode(text);
NodeList childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Node node = childs.item(i);
if (Node.TEXT_NODE == node.getNodeType()) {
element.replaceChild(newTextNode, node);
return;
}
}
element.appendChild(newTextNode);
}
/** Return subtree as a string, formatted as in XML
documents.
@param e Element's subtree.
@return String representation. */
public static String toString(Element e) {
return toString(e, "");
}
/** Return subtree as a string, formatted as in XML
documents.
NOTE: Does only handle elements. Support for text nodes
still needs to be done.
@param e Element's subtree.
@param indentation Indentation of first element.
@return String representation. */
public static String toString(Element e, String indentation) {
String result = indentation + "<";
result += e.getTagName();
NamedNodeMap attributes = e.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
result += " " +
((Attr) attributes.item(i)).getName() + "=\"" +
((Attr) attributes.item(i)).getValue() + "\"";
}
NodeList childs = getChildElements(e);
if (childs.getLength() == 0) {
result += "/>\n";
} else {
result += ">\n";
// Node n = e.getFirstChild();
// while (n != null) {
// switch (n.getNodeType()) {
// case Node.ELEMENT_NODE:
// result += toString((Element) n, indentation + " ");
// break;
// case Node.TEXT_NODE:
// result += indentation + " '" + n.getNodeValue() + "'\n";
// break;
// }
// n = n.getNextSibling();
// }
for (int i = 0; i < childs.getLength(); i++) {
result += toString((Element) childs.item(i), indentation+" ");
}
result += indentation + "</" + e.getTagName() + ">\n";
}
return result;
}
/** Return subtree as a string, formatted as in XML
documents.
@param e Element's subtree.
@return String representation. */
public static String toStringWithoutChild(Element e) {
return toStringWithoutChild(e, "");
}
/** Return subtree as a string, formatted as in XML
documents.
NOTE: Does only handle elements. Support for text nodes
still needs to be done.
@param e Element's subtree.
@param indentation Indentation of first element.
@return String representation. */
public static String toStringWithoutChild(Element e, String indentation) {
String result = indentation + "<";
result += e.getTagName();
NamedNodeMap attributes = e.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
result += " " +
((Attr) attributes.item(i)).getName() + "=\"" +
((Attr) attributes.item(i)).getValue() + "\"";
}
result += "/>\n";
return result;
}
}