BAEL 2338 - Sample code for the article (#7762)
* FEAT Added Jaxp transformer to convert xml to html * CHORE Added additional refactors * UPDATE Refactor to use Map instead of Element navigation * FEAT Added Stax transformer to convert from XML to HTML * FEAT Added Freemarker transformer * FEAT Added Mustache transformer
This commit is contained in:
parent
81da8bb2d3
commit
c291aae952
12
xml/pom.xml
12
xml/pom.xml
@ -59,6 +59,16 @@
|
|||||||
<artifactId>stax-api</artifactId>
|
<artifactId>stax-api</artifactId>
|
||||||
<version>${stax-api.version}</version>
|
<version>${stax-api.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.freemarker</groupId>
|
||||||
|
<artifactId>freemarker</artifactId>
|
||||||
|
<version>${freemarker.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.spullara.mustache.java</groupId>
|
||||||
|
<artifactId>compiler</artifactId>
|
||||||
|
<version>${mustache.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- JMH Libraries -->
|
<!-- JMH Libraries -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjdk.jmh</groupId>
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
@ -324,6 +334,8 @@
|
|||||||
<xmlunit-assertj.version>2.6.3</xmlunit-assertj.version>
|
<xmlunit-assertj.version>2.6.3</xmlunit-assertj.version>
|
||||||
<junit-jupiter.version>5.5.0</junit-jupiter.version>
|
<junit-jupiter.version>5.5.0</junit-jupiter.version>
|
||||||
<jmh.version>1.21</jmh.version>
|
<jmh.version>1.21</jmh.version>
|
||||||
|
<freemarker.version>2.3.29</freemarker.version>
|
||||||
|
<mustache.version>0.9.6</mustache.version>
|
||||||
<!-- util -->
|
<!-- util -->
|
||||||
<commons-lang3.version>3.5</commons-lang3.version>
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
<commons-lang.version>2.4</commons-lang.version>
|
<commons-lang.version>2.4</commons-lang.version>
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.xmlhtml.freemarker;
|
||||||
|
|
||||||
|
import com.baeldung.xmlhtml.stax.StaxTransformer;
|
||||||
|
import freemarker.template.Configuration;
|
||||||
|
import freemarker.template.Template;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
import freemarker.template.TemplateExceptionHandler;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class FreemarkerTransformer {
|
||||||
|
private StaxTransformer staxTransformer;
|
||||||
|
private String templateDirectory;
|
||||||
|
private String templateFile;
|
||||||
|
|
||||||
|
public FreemarkerTransformer(StaxTransformer staxTransformer, String templateDirectory, String templateFile) {
|
||||||
|
this.staxTransformer = staxTransformer;
|
||||||
|
this.templateDirectory = templateDirectory;
|
||||||
|
this.templateFile = templateFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String html() throws IOException, XMLStreamException, TemplateException {
|
||||||
|
Configuration cfg = new Configuration(Configuration.VERSION_2_3_29);
|
||||||
|
cfg.setDirectoryForTemplateLoading(new File(templateDirectory));
|
||||||
|
cfg.setDefaultEncoding(StandardCharsets.UTF_8.toString());
|
||||||
|
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
|
||||||
|
cfg.setLogTemplateExceptions(false);
|
||||||
|
cfg.setWrapUncheckedExceptions(true);
|
||||||
|
cfg.setFallbackOnNullLoopVariable(false);
|
||||||
|
Template temp = cfg.getTemplate(templateFile);
|
||||||
|
Writer output = new StringWriter();
|
||||||
|
temp.process(staxTransformer.buildMap(), output);
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -2,15 +2,11 @@ package com.baeldung.xmlhtml.helpers;
|
|||||||
|
|
||||||
|
|
||||||
import com.baeldung.xmlhtml.helpers.jaxb.JAXBHelper;
|
import com.baeldung.xmlhtml.helpers.jaxb.JAXBHelper;
|
||||||
import com.baeldung.xmlhtml.helpers.jaxp.JAXPHelper;
|
import com.baeldung.xmlhtml.stax.StaxTransformer;
|
||||||
import com.baeldung.xmlhtml.helpers.stax.STAXHelper;
|
|
||||||
|
|
||||||
public class XMLRunner {
|
public class XMLRunner {
|
||||||
|
|
||||||
public static void doWork() {
|
public static void doWork() {
|
||||||
JAXBHelper.example();
|
JAXBHelper.example();
|
||||||
JAXPHelper.saxParser();
|
|
||||||
JAXPHelper.documentBuilder();
|
|
||||||
STAXHelper.write(STAXHelper.read());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package com.baeldung.xmlhtml.helpers.jaxp;
|
|
||||||
|
|
||||||
import org.xml.sax.ContentHandler;
|
|
||||||
import org.xml.sax.Locator;
|
|
||||||
|
|
||||||
import static com.baeldung.xmlhtml.Constants.*;
|
|
||||||
|
|
||||||
public class CustomHandler implements ContentHandler {
|
|
||||||
|
|
||||||
public void startDocument() {}
|
|
||||||
|
|
||||||
public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes atts) { }
|
|
||||||
|
|
||||||
public void endDocument() {
|
|
||||||
System.out.println(DOCUMENT_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void endElement(String uri, String localName, String qName) { }
|
|
||||||
|
|
||||||
public void startPrefixMapping(String prefix, String uri) { }
|
|
||||||
|
|
||||||
public void endPrefixMapping(String prefix) { }
|
|
||||||
|
|
||||||
public void setDocumentLocator(Locator locator) { }
|
|
||||||
|
|
||||||
public void characters(char[] ch, int start, int length) { }
|
|
||||||
|
|
||||||
public void ignorableWhitespace(char[] ch, int start, int length) { }
|
|
||||||
|
|
||||||
public void processingInstruction(String target, String data) { }
|
|
||||||
|
|
||||||
public void skippedEntity(String name) { }
|
|
||||||
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package com.baeldung.xmlhtml.helpers.jaxp;
|
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.XMLReader;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.SAXParser;
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
|
||||||
import javax.xml.transform.stream.StreamResult;
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import static com.baeldung.xmlhtml.Constants.*;
|
|
||||||
|
|
||||||
public class JAXPHelper {
|
|
||||||
|
|
||||||
private static void print(Document document) {
|
|
||||||
NodeList list = document.getChildNodes();
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < list.getLength(); i++) {
|
|
||||||
Node node = list.item(i);
|
|
||||||
String message =
|
|
||||||
node.getNodeType()
|
|
||||||
+ WHITE_SPACE
|
|
||||||
+ node.getNodeName()
|
|
||||||
+ LINE_BREAK;
|
|
||||||
System.out.println(message);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void saxParser() {
|
|
||||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
|
||||||
spf.setNamespaceAware(true);
|
|
||||||
try {
|
|
||||||
SAXParser saxParser = spf.newSAXParser();
|
|
||||||
XMLReader xmlReader = saxParser.getXMLReader();
|
|
||||||
xmlReader.setContentHandler(new CustomHandler());
|
|
||||||
xmlReader.parse(XML_FILE_IN);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void documentBuilder() {
|
|
||||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
|
||||||
try {
|
|
||||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
|
||||||
Document parsed = db.parse(new File(XML_FILE_IN));
|
|
||||||
Element xml = parsed.getDocumentElement();
|
|
||||||
|
|
||||||
Document doc = db.newDocument();
|
|
||||||
Element html = doc.createElement("html");
|
|
||||||
Element head = doc.createElement("head");
|
|
||||||
html.appendChild(head);
|
|
||||||
|
|
||||||
Element body = doc.createElement("body");
|
|
||||||
Element descendantOne = doc.createElement("p");
|
|
||||||
descendantOne.setTextContent("descendantOne: " +
|
|
||||||
xml.getElementsByTagName("descendantOne")
|
|
||||||
.item(0).getTextContent());
|
|
||||||
Element descendantThree = doc.createElement("p");
|
|
||||||
descendantThree.setTextContent("descendantThree: " +
|
|
||||||
xml.getElementsByTagName("descendantThree")
|
|
||||||
.item(0).getTextContent());
|
|
||||||
Element nested = doc.createElement("div");
|
|
||||||
nested.appendChild(descendantThree);
|
|
||||||
|
|
||||||
body.appendChild(descendantOne);
|
|
||||||
body.appendChild(nested);
|
|
||||||
html.appendChild(body);
|
|
||||||
doc.appendChild(html);
|
|
||||||
|
|
||||||
TransformerFactory tFactory = TransformerFactory.newInstance();
|
|
||||||
tFactory
|
|
||||||
.newTransformer()
|
|
||||||
.transform(new DOMSource(doc), new StreamResult(new File(JAXP_FILE_OUT)));
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
package com.baeldung.xmlhtml.helpers.stax;
|
|
||||||
|
|
||||||
import com.baeldung.xmlhtml.pojo.stax.Body;
|
|
||||||
import com.baeldung.xmlhtml.pojo.stax.CustomElement;
|
|
||||||
import com.baeldung.xmlhtml.pojo.stax.NestedElement;
|
|
||||||
|
|
||||||
import javax.xml.stream.XMLInputFactory;
|
|
||||||
import javax.xml.stream.XMLOutputFactory;
|
|
||||||
import javax.xml.stream.XMLStreamReader;
|
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
|
|
||||||
import static com.baeldung.xmlhtml.Constants.*;
|
|
||||||
|
|
||||||
public class STAXHelper {
|
|
||||||
|
|
||||||
private static XMLStreamReader reader() {
|
|
||||||
XMLStreamReader xmlStreamReader = null;
|
|
||||||
try {
|
|
||||||
xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream(XML_FILE_IN));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
return xmlStreamReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static XMLStreamWriter writer() {
|
|
||||||
XMLStreamWriter xmlStreamWriter = null;
|
|
||||||
try {
|
|
||||||
xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(new FileWriter(STAX_FILE_OUT));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
return xmlStreamWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Body read() {
|
|
||||||
Body body = new Body();
|
|
||||||
try {
|
|
||||||
XMLStreamReader xmlStreamReader = reader();
|
|
||||||
|
|
||||||
CustomElement customElement = new CustomElement();
|
|
||||||
NestedElement nestedElement = new NestedElement();
|
|
||||||
CustomElement child = new CustomElement();
|
|
||||||
|
|
||||||
while (xmlStreamReader.hasNext()) {
|
|
||||||
xmlStreamReader.next();
|
|
||||||
if (xmlStreamReader.isStartElement()) {
|
|
||||||
System.out.println(xmlStreamReader.getLocalName());
|
|
||||||
if (xmlStreamReader.getLocalName().equals("descendantOne")) {
|
|
||||||
customElement.setValue(xmlStreamReader.getElementText());
|
|
||||||
}
|
|
||||||
if (xmlStreamReader.getLocalName().equals("descendantThree")) {
|
|
||||||
child.setValue(xmlStreamReader.getElementText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nestedElement.setCustomElement(child);
|
|
||||||
body.setCustomElement(customElement);
|
|
||||||
body.setNestedElement(nestedElement);
|
|
||||||
|
|
||||||
xmlStreamReader.close();
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void write(Body body) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
XMLStreamWriter xmlStreamWriter = writer();
|
|
||||||
xmlStreamWriter.writeStartElement("html");
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB);
|
|
||||||
xmlStreamWriter.writeStartElement("head");
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB + TAB);
|
|
||||||
xmlStreamWriter.writeStartElement("meta");
|
|
||||||
xmlStreamWriter.writeEndElement();
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB);
|
|
||||||
xmlStreamWriter.writeEndElement();
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB);
|
|
||||||
xmlStreamWriter.writeStartElement("body");
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB + TAB);
|
|
||||||
xmlStreamWriter.writeStartElement("p");
|
|
||||||
xmlStreamWriter.writeCharacters("descendantOne: " + body.getCustomElement().getValue());
|
|
||||||
xmlStreamWriter.writeEndElement();
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB + TAB);
|
|
||||||
xmlStreamWriter.writeStartElement("div");
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB + TAB + TAB);
|
|
||||||
xmlStreamWriter.writeStartElement("p");
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK);
|
|
||||||
xmlStreamWriter.writeCharacters(TAB + TAB + TAB + TAB + "descendantThree: " + body.getNestedElement().getCustomElement().getValue());
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB + TAB + TAB);
|
|
||||||
xmlStreamWriter.writeEndElement();
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB + TAB);
|
|
||||||
xmlStreamWriter.writeEndElement();
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK + TAB);
|
|
||||||
xmlStreamWriter.writeEndElement();
|
|
||||||
xmlStreamWriter.writeCharacters(BREAK);
|
|
||||||
xmlStreamWriter.writeEndDocument();
|
|
||||||
xmlStreamWriter.flush();
|
|
||||||
xmlStreamWriter.close();
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.println(EXCEPTION_ENCOUNTERED + ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
102
xml/src/main/java/com/baeldung/xmlhtml/jaxp/JaxpTransformer.java
Normal file
102
xml/src/main/java/com/baeldung/xmlhtml/jaxp/JaxpTransformer.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package com.baeldung.xmlhtml.jaxp;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.XMLConstants;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
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 java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class JaxpTransformer {
|
||||||
|
|
||||||
|
private Document input;
|
||||||
|
private DocumentBuilderFactory factory;
|
||||||
|
|
||||||
|
public JaxpTransformer(String resourcePath) throws ParserConfigurationException, IOException, SAXException {
|
||||||
|
// 1- Build the doc from the XML file
|
||||||
|
factory = DocumentBuilderFactory.newInstance();
|
||||||
|
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
input = factory
|
||||||
|
.newDocumentBuilder()
|
||||||
|
.parse(resourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String html() throws ParserConfigurationException, TransformerException {
|
||||||
|
Element xml = input.getDocumentElement();
|
||||||
|
Document doc = factory
|
||||||
|
.newDocumentBuilder()
|
||||||
|
.newDocument();
|
||||||
|
//Build Map
|
||||||
|
Map<String, String> map = buildMap(xml);
|
||||||
|
//Head
|
||||||
|
Element html = doc.createElement("html");
|
||||||
|
html.setAttribute("lang", "en");
|
||||||
|
Element head = buildHead(map, doc);
|
||||||
|
html.appendChild(head);
|
||||||
|
//Body
|
||||||
|
Element body = buildBody(map, doc);
|
||||||
|
html.appendChild(body);
|
||||||
|
doc.appendChild(html);
|
||||||
|
Writer output = applyTransformation(doc);
|
||||||
|
return String.format("<!DOCTYPE html>%n%s", output.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Writer applyTransformation(Document doc) throws TransformerException {
|
||||||
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
|
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||||
|
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||||
|
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
|
||||||
|
Writer output = new StringWriter();
|
||||||
|
Transformer transformer = transformerFactory.newTransformer();
|
||||||
|
transformer.transform(new DOMSource(doc), new StreamResult(output));
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> buildMap(Element xml) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
map.put("heading", xml
|
||||||
|
.getElementsByTagName("heading")
|
||||||
|
.item(0)
|
||||||
|
.getTextContent());
|
||||||
|
map.put("from", String.format("from: %s", xml
|
||||||
|
.getElementsByTagName("from")
|
||||||
|
.item(0)
|
||||||
|
.getTextContent()));
|
||||||
|
map.put("content", xml
|
||||||
|
.getElementsByTagName("content")
|
||||||
|
.item(0)
|
||||||
|
.getTextContent());
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element buildHead(Map<String, String> map, Document doc) {
|
||||||
|
Element head = doc.createElement("head");
|
||||||
|
Element title = doc.createElement("title");
|
||||||
|
title.setTextContent(map.get("heading"));
|
||||||
|
head.appendChild(title);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Element buildBody(Map<String, String> map, Document doc) {
|
||||||
|
Element body = doc.createElement("body");
|
||||||
|
Element from = doc.createElement("p");
|
||||||
|
from.setTextContent(map.get("from"));
|
||||||
|
Element success = doc.createElement("p");
|
||||||
|
success.setTextContent(map.get("content"));
|
||||||
|
body.appendChild(from);
|
||||||
|
body.appendChild(success);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.baeldung.xmlhtml.mustache;
|
||||||
|
|
||||||
|
import com.baeldung.xmlhtml.stax.StaxTransformer;
|
||||||
|
import com.github.mustachejava.DefaultMustacheFactory;
|
||||||
|
import com.github.mustachejava.Mustache;
|
||||||
|
import com.github.mustachejava.MustacheFactory;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
public class MustacheTransformer {
|
||||||
|
private StaxTransformer staxTransformer;
|
||||||
|
private String templateFile;
|
||||||
|
|
||||||
|
public MustacheTransformer(StaxTransformer staxTransformer, String templateFile) {
|
||||||
|
this.staxTransformer = staxTransformer;
|
||||||
|
this.templateFile = templateFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String html() throws IOException, XMLStreamException {
|
||||||
|
MustacheFactory mf = new DefaultMustacheFactory();
|
||||||
|
Mustache mustache = mf.compile(templateFile);
|
||||||
|
Writer output = new StringWriter();
|
||||||
|
mustache.execute(output, staxTransformer.buildMap());
|
||||||
|
output.flush();
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +0,0 @@
|
|||||||
package com.baeldung.xmlhtml.pojo.stax;
|
|
||||||
|
|
||||||
public class Body {
|
|
||||||
|
|
||||||
private CustomElement customElement;
|
|
||||||
|
|
||||||
public CustomElement getCustomElement() {
|
|
||||||
return customElement;
|
|
||||||
}
|
|
||||||
public void setCustomElement(CustomElement customElement) {
|
|
||||||
this.customElement = customElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NestedElement nestedElement;
|
|
||||||
|
|
||||||
public NestedElement getNestedElement() {
|
|
||||||
return nestedElement;
|
|
||||||
}
|
|
||||||
public void setNestedElement(NestedElement nestedElement) {
|
|
||||||
this.nestedElement = nestedElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package com.baeldung.xmlhtml.pojo.stax;
|
|
||||||
|
|
||||||
public class CustomElement {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package com.baeldung.xmlhtml.pojo.stax;
|
|
||||||
|
|
||||||
public class NestedElement {
|
|
||||||
|
|
||||||
private CustomElement customElement;
|
|
||||||
|
|
||||||
public CustomElement getCustomElement() {
|
|
||||||
return customElement;
|
|
||||||
}
|
|
||||||
public void setCustomElement(CustomElement customElement) {
|
|
||||||
this.customElement = customElement;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,89 @@
|
|||||||
|
package com.baeldung.xmlhtml.stax;
|
||||||
|
|
||||||
|
import javax.xml.stream.*;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class StaxTransformer {
|
||||||
|
|
||||||
|
private XMLStreamReader input;
|
||||||
|
|
||||||
|
public StaxTransformer(String resourcePath) throws FileNotFoundException, XMLStreamException {
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
||||||
|
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
|
||||||
|
factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
|
||||||
|
input = factory.createXMLStreamReader(new FileInputStream(resourcePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String html() throws XMLStreamException {
|
||||||
|
Map<String, String> map = buildMap();
|
||||||
|
Writer output = new StringWriter();
|
||||||
|
XMLStreamWriter writer = XMLOutputFactory
|
||||||
|
.newInstance()
|
||||||
|
.createXMLStreamWriter(output);
|
||||||
|
//Head
|
||||||
|
writer.writeDTD("<!DOCTYPE html>");
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeStartElement("html");
|
||||||
|
writer.writeAttribute("lang", "en");
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeStartElement("head");
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeDTD("<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeStartElement("title");
|
||||||
|
writer.writeCharacters(map.get("heading"));
|
||||||
|
writer.writeEndElement();
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeEndElement();
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
//Body
|
||||||
|
writer.writeStartElement("body");
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeStartElement("p");
|
||||||
|
writer.writeCharacters(map.get("from"));
|
||||||
|
writer.writeEndElement();
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeStartElement("p");
|
||||||
|
writer.writeCharacters(map.get("content"));
|
||||||
|
writer.writeEndElement();
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeEndElement();
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.writeEndDocument();
|
||||||
|
writer.writeCharacters(String.format("%n"));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> buildMap() throws XMLStreamException {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
while (input.hasNext()) {
|
||||||
|
input.next();
|
||||||
|
if (input.isStartElement()) {
|
||||||
|
if (input
|
||||||
|
.getLocalName()
|
||||||
|
.equals("heading")) {
|
||||||
|
map.put("heading", input.getElementText());
|
||||||
|
}
|
||||||
|
if (input
|
||||||
|
.getLocalName()
|
||||||
|
.equals("from")) {
|
||||||
|
map.put("from", String.format("from: %s", input.getElementText()));
|
||||||
|
}
|
||||||
|
if (input
|
||||||
|
.getLocalName()
|
||||||
|
.equals("content")) {
|
||||||
|
map.put("content", input.getElementText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input.close();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
@ -47,7 +47,9 @@ public class Dom4jProcessorUnitTest {
|
|||||||
String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml")
|
String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml")
|
||||||
.toURI()))));
|
.toURI()))));
|
||||||
|
|
||||||
String result = transformer.modifyAttribute(attribute, oldValue, newValue);
|
String result = transformer
|
||||||
|
.modifyAttribute(attribute, oldValue, newValue)
|
||||||
|
.replaceAll("(?m)^[ \t]*\r?\n", "");//Delete extra spaces added by Java 11
|
||||||
|
|
||||||
assertThat(result).and(expectedXml)
|
assertThat(result).and(expectedXml)
|
||||||
.areSimilar();
|
.areSimilar();
|
||||||
|
@ -47,7 +47,9 @@ public class JooxProcessorUnitTest {
|
|||||||
String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml")
|
String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml")
|
||||||
.toURI()))));
|
.toURI()))));
|
||||||
|
|
||||||
String result = transformer.modifyAttribute(attribute, oldValue, newValue);
|
String result = transformer
|
||||||
|
.modifyAttribute(attribute, oldValue, newValue)
|
||||||
|
.replaceAll("(?m)^[ \t]*\r?\n", "");//Delete extra spaces added by Java 11
|
||||||
|
|
||||||
assertThat(result).and(expectedXml)
|
assertThat(result).and(expectedXml)
|
||||||
.areSimilar();
|
.areSimilar();
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.baeldung.xmlhtml.freemarker;
|
||||||
|
|
||||||
|
import com.baeldung.xmlhtml.stax.StaxTransformer;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class FreemarkerTransformerUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenXml_whenTransform_thenGetHtml() throws IOException, URISyntaxException, XMLStreamException, TemplateException {
|
||||||
|
String expectedHtml = new String(Files.readAllBytes((Paths.get(getClass()
|
||||||
|
.getResource("/xmlhtml/notification.html")
|
||||||
|
.toURI()))));
|
||||||
|
StaxTransformer staxTransformer = new StaxTransformer("src/test/resources/xmlhtml/notification.xml");
|
||||||
|
String templateFile = "freemarker.html";
|
||||||
|
String templateDirectory = "src/test/resources/templates";
|
||||||
|
FreemarkerTransformer transformer = new FreemarkerTransformer(staxTransformer, templateDirectory, templateFile);
|
||||||
|
|
||||||
|
String result = transformer.html();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(expectedHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.xmlhtml.jaxp;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class JaxpTransformerUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenXml_whenTransform_thenGetHtml() throws IOException, SAXException, ParserConfigurationException, TransformerException, URISyntaxException {
|
||||||
|
String path = getClass()
|
||||||
|
.getResource("/xmlhtml/notification.xml")
|
||||||
|
.toString();
|
||||||
|
String expectedHtml = new String(Files.readAllBytes((Paths.get(getClass()
|
||||||
|
.getResource("/xmlhtml/notification.html")
|
||||||
|
.toURI()))));
|
||||||
|
JaxpTransformer transformer = new JaxpTransformer(path);
|
||||||
|
|
||||||
|
String result = transformer
|
||||||
|
.html()
|
||||||
|
.replaceAll("(?m)^\\s+", "");//Delete extra spaces added by Java 11
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(expectedHtml);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.baeldung.xmlhtml.mustache;
|
||||||
|
|
||||||
|
import com.baeldung.xmlhtml.stax.StaxTransformer;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class MustacheTransformerUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenXml_whenTransform_thenGetHtml() throws IOException, URISyntaxException, XMLStreamException {
|
||||||
|
String expectedHtml = new String(Files.readAllBytes((Paths.get(getClass()
|
||||||
|
.getResource("/xmlhtml/notification.html")
|
||||||
|
.toURI()))));
|
||||||
|
StaxTransformer staxTransformer = new StaxTransformer("src/test/resources/xmlhtml/notification.xml");
|
||||||
|
String templateFile = "src/test/resources/templates/template.mustache";
|
||||||
|
MustacheTransformer transformer = new MustacheTransformer(staxTransformer, templateFile);
|
||||||
|
|
||||||
|
String result = transformer.html();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(expectedHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.xmlhtml.stax;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class StaxTransformerUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenXml_whenTransform_thenGetHtml() throws IOException, URISyntaxException, XMLStreamException {
|
||||||
|
String path = "src/test/resources/xmlhtml/notification.xml";
|
||||||
|
String expectedHtml = new String(Files.readAllBytes((Paths.get(getClass()
|
||||||
|
.getResource("/xmlhtml/notification.html")
|
||||||
|
.toURI()))));
|
||||||
|
StaxTransformer transformer = new StaxTransformer(path);
|
||||||
|
|
||||||
|
String result = transformer.html();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(expectedHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
xml/src/test/resources/templates/freemarker.html
Normal file
11
xml/src/test/resources/templates/freemarker.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>${heading}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>${from}</p>
|
||||||
|
<p>${content}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
11
xml/src/test/resources/templates/template.mustache
Normal file
11
xml/src/test/resources/templates/template.mustache
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>{{heading}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>{{from}}</p>
|
||||||
|
<p>{{content}}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
11
xml/src/test/resources/xmlhtml/notification.html
Normal file
11
xml/src/test/resources/xmlhtml/notification.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>Build #7 passed</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>from: builds@baeldung.com</p>
|
||||||
|
<p>Success: The Jenkins CI build passed</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
6
xml/src/test/resources/xmlhtml/notification.xml
Normal file
6
xml/src/test/resources/xmlhtml/notification.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<notification>
|
||||||
|
<from>builds@baeldung.com</from>
|
||||||
|
<heading>Build #7 passed</heading>
|
||||||
|
<content>Success: The Jenkins CI build passed</content>
|
||||||
|
</notification>
|
Loading…
x
Reference in New Issue
Block a user