/**
* XMLUtilities.java
*
* Mar 22, 2013
*/
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
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;
/**
* @author Adrian McGrath, APMSoftware
*
*/
public class XMLUtilities {
static {
Properties systemProperties = System.getProperties();
systemProperties.remove("javax.xml.parsers.DocumentBuilderFactory");
System.setProperties(systemProperties);
}
/**
* Creates a Text Node with the given name and value
* @param document The Document to use to create the node
* @param name The name of the node
* @param value The value of the node
* @return The created Text Node
*/
public static Element createNode(Document document, String name, String value) {
Element node = document.createElement(name);
node.setTextContent(value);
return node;
}
/**
* Gets the String value of a node
* @param node The parent node
* @param key The key for the child node whose value is desired
* @return The String value of a node
*/
public static String getValueOfNode(Node node, String key) {
Element element = getChildElement(node,key);
if(element!=null)
return element.getTextContent();
return null;
}
/**
* @param node The node to look in
* @param key The attribute key
* @return The attribute value, or an empty String if not able to
*/
public static String getAttributeValue(Node node, String key) {
if(node instanceof Element) {
Element element = (Element)node;
return element.getAttribute(key);
}
return "";
}
/**
* Gets the Child Element of the node
* @param node The parent node
* @param key The key for the child
* @return The child as an Element
*/
public static Element getChildElement(Node node, String key) {
if(node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
NodeList list = element.getElementsByTagName(key);
if(list.getLength()==0)
return null;
Node toReturn = list.item(0);
if(toReturn.getNodeType() == Node.ELEMENT_NODE) {
return (Element)toReturn;
}
}
else if(node.getNodeType() == Node.DOCUMENT_NODE) {
Document document = (Document)node;
NodeList list = document.getElementsByTagName(key);
if(list.getLength()==0)
return null;
Node toReturn = list.item(0);
if(toReturn.getNodeType() == Node.ELEMENT_NODE) {
return (Element)toReturn;
}
}
return null;
}
/**
* Gets the Node in the NodeList that has the desired key and value
* @param list The node list to search through
* @param key The name of the child node
* @param value The value of the child node
* @return The node being searched for
*/
public static Node getElementWithChild(NodeList list, String key, String value) {
for(int i=0;i<list.getLength();i++) {
Node item = list.item(i);
String child = getValueOfNode(item,key);
if(value.equals(child))
return item;
}
return null;
}
/**
* Method that simply prints the document for debugging purposes
* @param doc The document to print
* @param out The output stream to print to
* @return <b>true</b> is successful, <b>false</b> otherwise
*/
public static boolean printDocument(Document doc, OutputStream out) {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = null;
try {
transformer = tf.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
return false;
}
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
try {
transformer.transform(new DOMSource(doc),new StreamResult(new OutputStreamWriter(out, "UTF-8")));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return false;
} catch (TransformerException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Prints the Node for debugging purposes
* @param doc The Node to print
* @param out The output stream to print to
*/
public static void printDocument(Node doc, OutputStream out) {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = null;
try {
transformer = tf.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
return;
}
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
try {
transformer.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "UTF-8")));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
/**
* Returns a Document from the give URL
* @param xml The url which contains the xml
* @return A document of the URL
* @throws Exception Any problems loading the document
*/
public static Document loadXMLFromURL(URL xml) throws Exception {
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(xml.openStream());
}
}
It provides methods for reading (from a url) to writing (to an output stream), as well as some common parsing methods.
Let's say we have this document:
<Activities>
<Activity>
<RetailFormat>ABC</RetailFormat>
<FeedDate>2014-02-06 21:01:10</FeedDate>
<ActivityId>665507</ActivityId>
<ActivityTitle>ABC 3.9.14 Hawaii </ActivityTitle>
<StartDate>2014-03-09</StartDate>
<EndDate>2014-03-15</EndDate>
<StartTime>00:00:00</StartTime>
<EndTime>23:59:59</EndTime>
<JANumber>0</JANumber>
<PlanItemNo>0</PlanItemNo>
<ChannelType>Circular</ChannelType>
<Version>
</Version>
</Activity>
</Activities>
When you read it into a document, you can get a list of the Activity Elements by using the java Document's method (can't remember its name off the top of my head). Once you get the list of elements, you can loop through them and find the activity numbers with:
// element is the Activity node you get by looping through the list of activity nodes
String activityId = XMLUtilities.getValueOfNode(element,"ActivityId");
Then, later when you want to create a new Document, you just say:
// document is the document object you are creating
Element activityIdElement = XMLUtilities.createNode(document,"ActivityId","665507");
// then add the activityIdElement where you want to in the document
...
// when you are ready to output the document, create an output stream and call:
boolean success = XMLUtilities.printDocument(document,outputStream);
I can expand on anything that is not clear. The class is just to simply the use of the already existing java XML classes.