Created
August 22, 2013 21:09
-
-
Save bmchild/6312814 to your computer and use it in GitHub Desktop.
A Dom4J Utility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
*/ | |
package com.bmchild.service.xml; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import org.dom4j.Document; | |
import org.dom4j.Node; | |
/** | |
* @author bchild | |
* | |
*/ | |
public interface XMLService { | |
String ENCODING = "ISO-8859-1"; | |
/** | |
* Creates an XML document with the root | |
* | |
* @param root | |
* @param xmlMap | |
* @return | |
*/ | |
Document createDocument(String root); | |
/** | |
* Recursive method to create an element and, if necessary, its parents and siblings | |
* @param document | |
* @param xpath to single element | |
* @param value if null an empty element will be created | |
* @return the created Node | |
*/ | |
Node addElementToDocument(Document document, String xpath, String value); | |
/** | |
* Transforms one xml document to another | |
* @param document to transform | |
* @param xlsResourceName name of the transformation file | |
* @return transformed Document | |
*/ | |
Document transformDocument(Document document, String xlsResourceName); | |
/** | |
* Gets the xml as a string | |
* @param document | |
*/ | |
String documentToString(Document document); | |
/** | |
* Gets the input stream for the document based on default settings | |
* @param document | |
* @return | |
* @throws IOException | |
*/ | |
InputStream getInputStream(Document document) throws IOException; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
*/ | |
package com.bmchild.service.xml; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.StringWriter; | |
import java.util.List; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.TransformerException; | |
import javax.xml.transform.TransformerFactory; | |
import javax.xml.transform.stream.StreamSource; | |
import org.apache.log4j.Logger; | |
import org.dom4j.Document; | |
import org.dom4j.DocumentHelper; | |
import org.dom4j.Element; | |
import org.dom4j.Node; | |
import org.dom4j.io.DocumentResult; | |
import org.dom4j.io.DocumentSource; | |
import org.dom4j.io.OutputFormat; | |
import org.dom4j.io.XMLWriter; | |
import org.springframework.stereotype.Service; | |
import com.bmchild.service.xml.exception.XmlException; | |
/** | |
* @author bchild | |
* | |
*/ | |
@Service | |
public class XMLServiceImpl implements XMLService { | |
private static final Logger LOGGER = Logger.getLogger(XMLServiceImpl.class.getName()); | |
/* (non-Javadoc) | |
* @see com.bmchild.service.xml.XMLService#createDocument(java.lang.String) | |
*/ | |
@Override | |
public Document createDocument(String root) { | |
return DocumentHelper.createDocument(DocumentHelper.createElement(root)); | |
} | |
/* (non-Javadoc) | |
* @see com.bmchild.service.xml.XMLService#addElementToDocument(org.dom4j.Document, java.lang.String, java.lang.String) | |
*/ | |
@Override | |
public Node addElementToDocument(Document document, String xpath, String value) { | |
if(LOGGER.isDebugEnabled()) { | |
LOGGER.debug("adding Element: " + xpath + " -> " + value); | |
} | |
Element created = null; | |
try { | |
String elementName = XPathUtils.getChildElementName(xpath); | |
String parentXPath = XPathUtils.getParentXPath(xpath); | |
Integer childIndex = XPathUtils.getChildElementIndex(xpath); | |
Node parentNode = document.selectSingleNode(parentXPath); | |
if(parentNode == null) { | |
parentNode = addElementToDocument(document, parentXPath, null); | |
} | |
// create younger siblings if needed | |
if(childIndex > 1) { | |
List<?> nodelist = document.selectNodes(XPathUtils.createPositionXpath(xpath, childIndex)); | |
// how many to create = (index wanted - existing - 1 to account for the new element we will create) | |
int nodesToCreate = childIndex - nodelist.size() - 1; | |
for(int i = 0; i < nodesToCreate; i++) { | |
((Element)parentNode).addElement(elementName); | |
} | |
} | |
// create requested element | |
created = ((Element)parentNode).addElement(elementName); | |
if(null != value) { | |
created.addText(value); | |
} | |
} catch (CreXmlException e) { | |
LOGGER.warn("unable to parse xpath", e); | |
} | |
return created; | |
} | |
/* (non-Javadoc) | |
* @see com.bmchild.service.xml.XMLService#transformDocument(org.dom4j.Document, java.lang.String) | |
*/ | |
@Override | |
public Document transformDocument(Document document, String xlsResourceName) { | |
TransformerFactory factory = TransformerFactory.newInstance(); | |
Document transformedDoc = null; | |
try { | |
InputStream stream = this.getClass().getResourceAsStream(xlsResourceName); | |
Transformer transformer = factory.newTransformer(new StreamSource(stream)); | |
DocumentSource source = new DocumentSource( document ); | |
DocumentResult result = new DocumentResult(); | |
transformer.transform( source, result ); | |
transformedDoc = result.getDocument(); | |
} catch (TransformerException e) { | |
throw new IllegalArgumentException("error configuring transformer", e); | |
} | |
return transformedDoc; | |
} | |
/* (non-Javadoc) | |
* @see com.bmchild.service.xml.XMLService#printDocToDebug(org.dom4j.Document) | |
*/ | |
@Override | |
public String documentToString(Document document) { | |
OutputFormat format = OutputFormat.createPrettyPrint(); | |
format.setEncoding(ENCODING); | |
StringWriter writer = new StringWriter(); | |
XMLWriter xmlwriter = new XMLWriter(writer, format); | |
String xml = null; | |
try { | |
xmlwriter.write( document ); | |
xml = writer.getBuffer().toString(); | |
} catch (IOException e) { | |
LOGGER.error(e.getMessage(), e); | |
} | |
return xml; | |
} | |
/* (non-Javadoc) | |
* @see com.bmchild.service.xml.XMLService#getInputStream(org.dom4j.Document) | |
*/ | |
@Override | |
public InputStream getInputStream(Document document) throws IOException { | |
InputStream input = null; | |
OutputFormat format = OutputFormat.createPrettyPrint(); | |
format.setEncoding(ENCODING); | |
ByteArrayOutputStream output = new ByteArrayOutputStream(); | |
XMLWriter xmlWriter = new XMLWriter(output, format); | |
xmlWriter.write(document); | |
input = new ByteArrayInputStream(output.toByteArray()); | |
return input; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
*/ | |
package com.bmchild.service.xml; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertTrue; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.StringWriter; | |
import java.util.List; | |
import org.apache.commons.io.IOUtils; | |
import org.apache.log4j.Logger; | |
import org.dom4j.Document; | |
import org.dom4j.Element; | |
import org.dom4j.io.OutputFormat; | |
import org.dom4j.io.XMLWriter; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import org.mockito.InjectMocks; | |
import org.mockito.runners.MockitoJUnitRunner; | |
/** | |
* @author bchild | |
* | |
*/ | |
@RunWith(MockitoJUnitRunner.class) | |
public class XMLServiceImplTest { | |
private static final Logger LOGGER = Logger.getLogger(XMLServiceImplTest.class.getName()); | |
private static final String ROOT = "root"; | |
private static final String BASE_XPATH = "/" + ROOT + "/data"; | |
@InjectMocks | |
private XMLService xmlService = new XMLServiceImpl(); | |
@Test | |
public void testCreateDocument() { | |
Document doc = xmlService.createDocument(ROOT); | |
assertEquals(ROOT, doc.getRootElement().getName()); | |
} | |
@Test | |
public void testAddElementToDocument() throws Exception { | |
Document doc = xmlService.createDocument(ROOT); | |
xmlService.addElementToDocument(doc, prependBase("/discharge_status"), "ACTIVE"); | |
xmlService.addElementToDocument(doc, prependBase("/suspension_rec[2]/start"), "0915"); | |
xmlService.addElementToDocument(doc, prependBase("/suspension_rec[1]/start"), "0815"); | |
xmlService.addElementToDocument(doc, prependBase("/suspension_rec[3]/start"), "0115"); | |
xmlService.addElementToDocument(doc, prependBase("/suspension_rec[1]/end"), "0125"); | |
List<?> nodes = doc.selectNodes("//discharge_status"); | |
assertEquals(1, nodes.size()); | |
assertEquals("ACTIVE", ((Element)nodes.get(0)).getText()); | |
nodes = doc.selectNodes("//suspension_rec"); | |
assertEquals(3, nodes.size()); | |
assertEquals("0915", ((Element)doc.selectSingleNode(prependBase("/suspension_rec[2]/start"))).getText()); | |
assertEquals("0815", ((Element)doc.selectSingleNode(prependBase("/suspension_rec[1]/start"))).getText()); | |
assertEquals("0115", ((Element)doc.selectSingleNode(prependBase("/suspension_rec[3]/start"))).getText()); | |
assertEquals("0125", ((Element)doc.selectSingleNode(prependBase("/suspension_rec[1]/end"))).getText()); | |
if(LOGGER.isDebugEnabled()) { | |
printDoc(doc); | |
} | |
} | |
/** | |
* @param string | |
* @return | |
*/ | |
private String prependBase(String string) { | |
return BASE_XPATH + string; | |
} | |
/** | |
* prints the xml to the LOGGER | |
* @param document | |
*/ | |
private String printDoc(Document document) { | |
OutputFormat format = OutputFormat.createPrettyPrint(); | |
format.setEncoding("ISO-8859-1"); | |
StringWriter writer = new StringWriter(); | |
XMLWriter xmlwriter = new XMLWriter(writer, format); | |
String xml = null; | |
try { | |
xmlwriter.write( document ); | |
xml = writer.getBuffer().toString(); | |
LOGGER.debug("generated xml: \n" + xml); | |
} catch (IOException e) { | |
LOGGER.error(e.getMessage(), e); | |
} | |
return xml; | |
} | |
@Test | |
public void testDocumentToString() throws Exception { | |
Document doc = xmlService.createDocument(ROOT); | |
String docString = xmlService.documentToString(doc); | |
assertTrue(docString.contains(ROOT)); | |
} | |
@Test | |
public void testGetInputStream() throws Exception { | |
Document doc = xmlService.createDocument(ROOT); | |
InputStream in = xmlService.getInputStream(doc); | |
StringWriter writer = new StringWriter(); | |
IOUtils.copy(in, writer); | |
assertTrue(writer.toString().contains(ROOT)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment