Configuración de espacios de nombres y prefijos en un documento DOM de Java

Estoy tratando de convertir un ResultSet a un archivo XML. Primero he usado este ejemplo para la serialización.

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);

Después de hacer este trabajo, intenté validar mi archivo XML, hubo un par de advertencias. Una sobre no tener un doctype. Así que intenté otra forma de implementar esto. Me encontré con la clase Transformer. Esta clase me permite configurar la codificación, doctype, etc.

La implementación anterior admite la reparación automática del espacio de nombres. Lo siguiente no lo hace.

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

Mientras estaba probando la implementación anterior obtuve una TransformationException: el espacio de nombres para el prefijo 'xsi' no se ha declarado. Como puede ver, he intentado agregar un espacio de nombres con el prefijo xsi al elemento raíz de mi documento. Después de probar esto todavía tengo la excepción. ¿Cuál es la forma correcta de establecer espacios de nombres y sus prefijos?

Edición: Otro problema que tengo con la primera implementación es que el último elemento del documento XML no tiene las últimas tres etiquetas de cierre.

Respuestas a la pregunta(3)

Su respuesta a la pregunta