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 "\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; } }