在Java DOM文档中设置名称空间和前缀 [英] Setting namespaces and prefixes in a Java DOM document

查看:165
本文介绍了在Java DOM文档中设置名称空间和前缀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将ResultSet转换为XML文件。
我首先使用这个例子进行序列化。

I'm trying to convert a ResultSet to an XML file. I've first used this example for the 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);

在我完成这项工作后,我尝试验证我的XML文件,有几个警告。
一个关于没有doctype的问题。所以我尝试了另一种方法来实现它。我遇到了Transformer课程。这个类让我设置编码,doctype等。

After I made this work, I tried to validate my XML file, there were a couple of warnings. One about not having a doctype. So I tried another way to implement this. I came across the Transformer class. This class lets me set the encoding, doctype, etc.

前面的实现支持自动命名空间修复。以下不是。

The previous implementation supports automatic namespace fix-up. The following does 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;
}

当我测试之前的实现时,我得到了一个TransformationException:前缀的命名空间' xsi'尚未声明。正如您所看到的,我已尝试将带有xsi前缀的命名空间添加到文档的根元素中。经过测试,我仍然得到了例外。设置命名空间及其前缀的正确方法是什么?

While I was testing the previous implementation I got an TransformationException: Namespace for prefix 'xsi' has not been declared. As you can see I've tried to add a namespace with the xsi prefix to the root element of my document. After testing this I still got the Exception. What is the correct way to set namespaces and their prefixes?

编辑:我对第一个实现的另一个问题是XML文档中的最后一个元素没有最后三个结束标记。

Another problem I have with the first implementation is that the last element in the XML document doesn't have the last three closing tags.

推荐答案

您还没有在根节点中添加名称空间声明;你刚刚在命名空间中声明了根节点,两个完全不同的东西。构建DOM时,需要在每个相关节点上引用命名空间。换句话说,当你添加你的属性时,你需要定义它的命名空间(例如,setAttributeNS)。

You haven't added the namespace declaration in the root node; you just declared the root node in the namespace, two entirely different things. When building a DOM, you need to reference the namespace on every relevant Node. In other words, when you add your attribute, you need to define its namespace (e.g., setAttributeNS).

旁注:虽然XML命名空间看起来像URL,但它们真的不是T。这里不需要使用URL类。

Side note: Although XML namespaces look like URLs, they really aren't. There's no need to use the URL class here.

这篇关于在Java DOM文档中设置名称空间和前缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆