Configurando Espaços de Nomes e Prefixos em um Documento DOM Java

Eu estou tentando converter um ResultSet para um arquivo XML. Eu usei primeiro este exemplo para a serialização.

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

Depois que fiz esse trabalho, tentei validar meu arquivo XML, houve alguns avisos. Um sobre não ter um doctype. Então eu tentei outra maneira de implementar isso. Eu me deparei com a classe Transformer. Esta classe me permite definir a codificação, tipo de documento, etc.

A implementação anterior suporta correção automática de namespace. O seguinte não faz.

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

Enquanto eu estava testando a implementação anterior, recebi uma TransformationException: Namespace para o prefixo 'xsi' não foi declarado. Como você pode ver, tentei adicionar um namespace com o prefixo xsi ao elemento raiz do meu documento. Depois de testar isso, ainda tenho a exceção. Qual é a maneira correta de definir namespaces e seus prefixos?

Edit: Outro problema que tenho com a primeira implementação é que o último elemento no documento XML não tem as três últimas marcas de fechamento.

questionAnswers(3)

yourAnswerToTheQuestion