package uk.ac.lkl.common.util;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import uk.ac.lkl.common.util.restlet.RuntimeRestletException;
public class XMLUtilities {
// note: doesn't actually indent. Annoying Java bug it seems.
// See: http://forums.sun.com/thread.jspa?threadID=562510&start=0&tstart=0
public static void printDocument(Document document,
OutputStream outputStream) {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer serializer;
try {
serializer = factory.newTransformer();
// Setup indenting to "pretty print"
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
serializer.transform(new DOMSource(document), new StreamResult(
outputStream));
} catch (TransformerException e) {
System.out.println(e);
}
}
public static void printDocument(Document document) {
printDocument(document, System.out);
}
public static void printElement(Element element, OutputStream outputStream)
throws ParserConfigurationException {
Document document = createDocument();
// deep import
Node importedNode = document.importNode(element, true);
document.appendChild(importedNode);
printDocument(document, outputStream);
}
public static void printElement(Element element)
throws ParserConfigurationException {
printElement(element, System.out);
}
public static String nodeToString(Node node) {
try {
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"yes");
StringWriter stringWriter = new StringWriter();
transformer.transform(new DOMSource(node), new StreamResult(
stringWriter));
return stringWriter.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// This would disappear with a better XML layer that processed each child
// in turn.
public static Element getChildWithTagName(Node node, String tagName) {
ArrayList<String> tagNames = new ArrayList<String>();
tagNames.add(tagName);
return getChildWithTagNames(node, tagNames);
}
public static Element getChildWithTagNames(Node node, List<String> tagNames) {
NodeList childNodes = node.getChildNodes();
int size = childNodes.getLength();
for (int i = 0; i < size; i++) {
Node child = childNodes.item(i);
if (child instanceof Element) {
Element childElement = (Element) child;
if (tagNames.contains(childElement.getTagName())) {
return childElement;
}
}
}
return null;
}
public static Element getNextChildWithTagName(Element element,
String tagName, Node previousNode) {
ArrayList<String> tagNames = new ArrayList<String>();
tagNames.add(tagName);
return getNextChildWithTagNames(element, tagNames, previousNode);
}
public static Element getNextChildWithTagNames(Element element,
List<String> tagNames, Node previousNode) {
Node nextSibling = previousNode.getNextSibling();
while (nextSibling != null) {
if (nextSibling instanceof Element) {
Element nextSiblingElement = (Element) nextSibling;
if (tagNames.contains(nextSiblingElement.getTagName())) {
return nextSiblingElement;
}
}
nextSibling = nextSibling.getNextSibling();
}
return null;
}
/**
* @param element
* @return The contents of the first CDATA child node or null if there are
* none.
*/
public static String getFirstCData(Element element) {
NodeList childNodes = element.getChildNodes();
int size = childNodes.getLength();
for (int i = 0; i < size; i++) {
Node child = childNodes.item(i);
if (child.getNodeType() == Node.CDATA_SECTION_NODE) {
return child.getTextContent();
}
}
return null;
}
public static ArrayList<String> getAllCData(Element element) {
ArrayList<String> result = new ArrayList<String>();
NodeList childNodes = element.getChildNodes();
int size = childNodes.getLength();
for (int i = 0; i < size; i++) {
Node child = childNodes.item(i);
if (child.getNodeType() == Node.CDATA_SECTION_NODE) {
result.add(child.getTextContent());
}
}
return result;
}
public static Integer getIntegerAttribute(Element element, String name) {
String valueString = element.getAttribute(name);
try {
return Integer.parseInt(valueString);
} catch (NumberFormatException e) {
return null;
}
}
public static Boolean getBooleanAttribute(Element element, String name)
throws RuntimeRestletException {
String valueString = element.getAttribute(name);
if (valueString.equals("true")) {
return true;
} else if (valueString.equals("false")) {
return false;
} else {
throw new RuntimeRestletException(
"Expected attribute value to be true or false "
+ valueString);
}
}
public static Boolean getBooleanAttribute(Element element, String name,
Boolean defaultValue) {
String valueString = element.getAttribute(name);
if (valueString.equals("true")) {
return true;
} else if (valueString.equals("false")) {
return false;
} else {
return defaultValue;
}
}
public static Document createDocument() throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
return document;
}
public static Document createDocument(File file)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(file);
}
}
|