import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Few simple utils to read DOM
*
* @author Costin Manolache
*/
public class DomUtil {
// -------------------- DOM utils --------------------
/**
* Get the trimed text content of a node or null if there is no text
*/
public static String getContent(Node n) {
if (n == null)
return null;
Node n1 = DomUtil.getChild(n, Node.TEXT_NODE);
if (n1 == null)
return null;
String s1 = n1.getNodeValue();
return s1.trim();
}
/**
* Get the first element child.
*
* @param parent
* lookup direct childs
* @param name
* name of the element. If null return the first element.
*/
public static Node getChild(Node parent, String name) {
if (parent == null)
return null;
Node first = parent.getFirstChild();
if (first == null)
return null;
for (Node node = first; node != null; node = node.getNextSibling()) {
// System.out.println("getNode: " + name + " " + node.getNodeName());
if (node.getNodeType() != Node.ELEMENT_NODE)
continue;
if (name != null && name.equals(node.getNodeName())) {
return node;
}
if (name == null) {
return node;
}
}
return null;
}
public static String getAttribute(Node element, String attName) {
NamedNodeMap attrs = element.getAttributes();
if (attrs == null)
return null;
Node attN = attrs.getNamedItem(attName);
if (attN == null)
return null;
return attN.getNodeValue();
}
public static void setAttribute(Node node, String attName, String val) {
NamedNodeMap attributes = node.getAttributes();
Node attNode = node.getOwnerDocument().createAttribute(attName);
attNode.setNodeValue(val);
attributes.setNamedItem(attNode);
}
public static void removeAttribute(Node node, String attName) {
NamedNodeMap attributes = node.getAttributes();
attributes.removeNamedItem(attName);
}
/**
* Set or replace the text value
*/
public static void setText(Node node, String val) {
Node chld = DomUtil.getChild(node, Node.TEXT_NODE);
if (chld == null) {
Node textN = node.getOwnerDocument().createTextNode(val);
node.appendChild(textN);
return;
}
// change the value
chld.setNodeValue(val);
}
/**
* Find the first direct child with a given attribute.
*
* @param parent
* @param elemName
* name of the element, or null for any
* @param attName
* attribute we're looking for
* @param attVal
* attribute value or null if we just want any
*/
public static Node findChildWithAtt(Node parent, String elemName, String attName, String attVal) {
Node child = DomUtil.getChild(parent, Node.ELEMENT_NODE);
if (attVal == null) {
while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
&& DomUtil.getAttribute(child, attName) != null) {
child = getNext(child, elemName, Node.ELEMENT_NODE);
}
} else {
while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
&& !attVal.equals(DomUtil.getAttribute(child, attName))) {
child = getNext(child, elemName, Node.ELEMENT_NODE);
}
}
return child;
}
/**
* Get the first child's content ( ie it's included TEXT node ).
*/
public static String getChildContent(Node parent, String name) {
Node first = parent.getFirstChild();
if (first == null)
return null;
for (Node node = first; node != null; node = node.getNextSibling()) {
// System.out.println("getNode: " + name + " " + node.getNodeName());
if (name.equals(node.getNodeName())) {
return getContent(node);
}
}
return null;
}
/**
* Get the first direct child with a given type
*/
public static Node getChild(Node parent, int type) {
Node n = parent.getFirstChild();
while (n != null && type != n.getNodeType()) {
n = n.getNextSibling();
}
if (n == null)
return null;
return n;
}
/**
* Get the next sibling with the same name and type
*/
public static Node getNext(Node current) {
String name = current.getNodeName();
int type = current.getNodeType();
return getNext(current, name, type);
}
/**
* Return the next sibling with a given name and type
*/
public static Node getNext(Node current, String name, int type) {
Node first = current.getNextSibling();
if (first == null)
return null;
for (Node node = first; node != null; node = node.getNextSibling()) {
if (type >= 0 && node.getNodeType() != type)
continue;
// System.out.println("getNode: " + name + " " + node.getNodeName());
if (name == null)
return node;
if (name.equals(node.getNodeName())) {
return node;
}
}
return null;
}
public static class NullResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) throws SAXException,
IOException {
return new InputSource(new StringReader(""));
}
}
/**
* Read XML as DOM.
*/
public static Document readXml(InputStream is) throws SAXException, IOException,
ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setIgnoringComments(false);
dbf.setIgnoringElementContentWhitespace(true);
// dbf.setCoalescing(true);
// dbf.setExpandEntityReferences(true);
DocumentBuilder db = null;
db = dbf.newDocumentBuilder();
db.setEntityResolver(new NullResolver());
// db.setErrorHandler( new MyErrorHandler());
Document doc = db.parse(is);
return doc;
}
public static void writeXml(Node n, OutputStream os) throws TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
// identity
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(n), new StreamResult(os));
}
}