package scriptbuilder.structures;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
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.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Utility methods that build XML elements from content strings.
* @author Bryan McGuffin
*/
public class XMLBuilder
{
/**
* XML-style opening tag. Example: if given string "my_tag", returns
* "".
*
* @param s the XML element to be included in the tag.
* @return the properly formatted tag
*/
public static String openTag(String s)
{
return "<" + s + ">";
}
/**
* XML-style closing tag. Example: if given string "my_tag", returns
* "".
*
* @param s the XML element to be included in the tag.
* @return the properly formatted tag
*/
public static String closeTag(String s)
{
return "" + s + ">\n";
}
/**
* XML-style empty tag. Example: if given string "my_tag", returns
* "".
*
* @param s the XML element to be included in the tag.
* @return the properly formatted tag
*/
public static String emptyTag(String s)
{
return "<" + s + "/>\n";
}
/**
* Creates a pair of XML open and close tags to wrap a simple line of data.
* Useful if only one element need be enclosed in this particular tag.
*
* @param s the data to be wrapped
* @param e the XML element represented by the data
* @return an XML string of the format some_data_goes_here
*/
public static String simpleTag(String s, ELEMENT e)
{
String output = "";
if (s == null)
{
s = "";
}
output += openTag(e.tag);
output += s;
output += closeTag(e.tag);
return output;
}
/**
* @return the xml string with the link to external DTD for XML script files.
*/
public static String externalDTD()
{
return "\n";
}
/**
* @return The xml string that starts the document.
*/
public static String xmlHeader()
{
return "\n";
}
/**
* Prettyprint an XML string.
* @param xmlString (works best if it contains no newlines)
* @return String that has been nicely formatted with indentation
*/
public static String prettyPrintXML(String xmlString)
{
Document xmlDoc = null;
String formattedXML = "";
try {
xmlDoc = toXmlDocument(xmlString);
formattedXML = prettyprintdoc(xmlDoc);
} catch (ParserConfigurationException | SAXException | IOException
| TransformerException e) {
e.printStackTrace();
}
// Prepend the header and externalDTD lines. (This must be done after
// prettyprinting, which tries to read the externalDTD if the link is present.)
// Fixes #239.
formattedXML = xmlHeader() + externalDTD() + formattedXML;
return formattedXML;
}
/**
* Prettyprint an XML document.
* @param document an "ugly" XML document
* @return String nicely formatted XML with indentation
* @throws TransformerException
*/
public static String prettyprintdoc(Document document)
throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
DOMSource source = new DOMSource(document);
StringWriter strWriter = new StringWriter();
StreamResult result = new StreamResult(strWriter);
transformer.transform(source, result);
return strWriter.getBuffer().toString();
}
/** Create an XML Document from a string that is in xml format.
*
* @param str xml format content
* @return Document containing the specified content.
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static Document toXmlDocument(String str)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(new InputSource(new StringReader(
str)));
return document;
}
}