I am trying to convert a ResultSet to an XML file. I first used this example for serialization.
import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.Document; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSSerializer; ... DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); ... LSSerializer writer = impl.createLSSerializer(); String str = writer.writeToString(document);
After doing this work, I tried to validate my XML file, there were several warnings. One that he has no doctrine. So I tried another way to implement this. I came across a Transformer class. This class allows me to set the encoding, doctype, etc.
The previous implementation supports automatic namespace detection. Not.
private static Document toDocument(ResultSet rs) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.newDocument(); URL namespaceURL = new URL("http://www.w3.org/2001/XMLSchema-instance"); String namespace = "xmlns:xsi="+namespaceURL.toString(); Element messages = doc.createElementNS(namespace, "messages"); doc.appendChild(messages); ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); String attributeValue = "true"; String attribute = "xsi:nil"; rs.beforeFirst(); while(rs.next()) { amountOfRecords = 0; Element message = doc.createElement("message"); messages.appendChild(message); for(int i = 1; i <= colCount; i++) { Object value = rs.getObject(i); String columnName = rsmd.getColumnName(i); Element messageNode = doc.createElement(columnName); if(value != null) { messageNode.appendChild(doc.createTextNode(value.toString())); } else { messageNode.setAttribute(attribute, attributeValue); } message.appendChild(messageNode); } amountOfRecords++; } logger.info("Amount of records archived: " + amountOfRecords); TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); BufferedWriter bf = createFile(); StreamResult sr = new StreamResult(bf); DOMSource source = new DOMSource(doc); tf.transform(source, sr); return doc; }
While testing the previous implementation, I got a TransformationException: the namespace for the 'xsi' prefix was not declared. As you can see, I tried adding a namespace with the xsi prefix to the root element of my document. After testing, I still got an exception. What is the correct way to set namespaces and their prefixes?
Edit: Another problem that I encountered with the first version is that the last element in the XML document does not have the last three closing tags.
source share