I need to create an XML file dynamically. I tried using StAX with the XMLStreamWriter interface, but in this first code sample, the "cars" node tag is on the same line as the first XML node.
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
transformerFactory.setAttribute("indent-number", 2);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter inputStringWriter = new StringWriter();
XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter xMLStreamWriter =
xMLOutputFactory.createXMLStreamWriter(inputStringWriter);
xMLStreamWriter.writeStartDocument();
xMLStreamWriter.writeStartElement("cars");
xMLStreamWriter.writeStartElement("supercars");
xMLStreamWriter.writeAttribute("company", "Ferrari");
xMLStreamWriter.writeStartElement("carname");
xMLStreamWriter.writeAttribute("type", "formula one");
xMLStreamWriter.writeCharacters("Ferrari 101");
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeStartElement("carname");
xMLStreamWriter.writeAttribute("type", "sports");
xMLStreamWriter.writeCharacters("Ferrari 202");
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndDocument();
xMLStreamWriter.flush();
xMLStreamWriter.close();
String xmlString = inputStringWriter.getBuffer().toString();
StringWriter outputStringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(outputStringWriter);
Source xmlInput = new StreamSource(new StringReader(xmlString));
transformer.transform(xmlInput, xmlOutput);
FileOutputStream outputXml = new FileOutputStream(new File("./src/temp/myfile.xml"));
outputXml.write(xmlOutput.getWriter().toString().getBytes("UTF-8"));
inputStringWriter.close();
outputStringWriter.close();
System.out.println(xmlOutput.getWriter().toString());
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
I tried using IndentingXMLStreamWriter to solve the above code problem, but to use it I need to import com.sun.xml.internal.txw2.output.IndentingXMLStreamWriter and SonarLint flags the import for me as a major quality defect.
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter inputStringWriter = new StringWriter();
XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter xMLStreamWriter =
new IndentingXMLStreamWriter(xMLOutputFactory.createXMLStreamWriter(inputStringWriter));
xMLStreamWriter.writeStartDocument();
xMLStreamWriter.writeStartElement("cars");
xMLStreamWriter.writeStartElement("supercars");
xMLStreamWriter.writeAttribute("company", "Ferrari");
xMLStreamWriter.writeStartElement("carname");
xMLStreamWriter.writeAttribute("type", "formula one");
xMLStreamWriter.writeCharacters("Ferrari 101");
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeStartElement("carname");
xMLStreamWriter.writeAttribute("type", "sports");
xMLStreamWriter.writeCharacters("Ferrari 202");
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndElement();
xMLStreamWriter.writeEndDocument();
xMLStreamWriter.flush();
xMLStreamWriter.close();
String xmlString = inputStringWriter.getBuffer().toString();
FileOutputStream outputXml = new FileOutputStream(new File("./src/temp/myfile.xml"));
outputXml.write(xmlString.getBytes("UTF-8"));
inputStringWriter.close();
System.out.println(xmlString);
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
I am showing a simple XML structure as an example, but in reality the XML that I need to generate is much larger and with internal nodes that will be displayed depending on certain conditions.
Any recommendation?