Tra*_*Can 12 java xml serialization transformer-model
我正在尝试将ResultSet转换为XML文件.我首先使用这个例子进行序列化.
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);
Run Code Online (Sandbox Code Playgroud)
在我完成这项工作后,我尝试验证我的XML文件,有几个警告.一个关于没有doctype的人.所以我尝试了另一种方法来实现它.我遇到了Transformer课程.这个类让我设置编码,doctype等.
以前的实现支持自动命名空间修复.以下不是.
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;
}
Run Code Online (Sandbox Code Playgroud)
当我测试之前的实现时,我得到了TransformationException:前缀'xsi'的命名空间尚未声明.正如您所看到的,我已尝试将带有xsi前缀的命名空间添加到文档的根元素中.经过测试,我仍然得到了例外.设置命名空间及其前缀的正确方法是什么?
编辑:我对第一个实现的另一个问题是XML文档中的最后一个元素没有最后三个结束标记.
小智 32
在namespaceAware文档上设置节点的正确方法是使用:
rootNode.createElementNS("http://example/namespace", "PREFIX:aNodeName");
Run Code Online (Sandbox Code Playgroud)
因此,您可以将"PREFIX"替换为您自己的自定义前缀,并将"aNodeName"替换为您的节点名称.为避免每个节点都有自己的名称空间声明,您可以将名称空间定义为根节点上的属性,如下所示:
rootNode.setAttribute("xmlns:PREFIX", "http://example/namespace");
Run Code Online (Sandbox Code Playgroud)
请务必设置:
documentBuilderFactory.setNamespaceAware(true)
Run Code Online (Sandbox Code Playgroud)
否则你没有namespaceAwareness.
请注意,使用setAttribute设置xmlns前缀是错误的.如果您想要对DOM进行签名,则必须使用setAttributeNS:
element.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:PREFIX", "http://example/namespace");
您尚未在根节点中添加名称空间声明; 你刚刚在命名空间中声明了根节点,两个完全不同的东西.构建DOM时,需要在每个相关节点上引用命名空间.换句话说,当您添加属性时,您需要定义其命名空间(例如,setAttributeNS).
旁注:虽然XML命名空间看起来像URL,但实际上并非如此.这里不需要使用URL类.
| 归档时间: |
|
| 查看次数: |
55446 次 |
| 最近记录: |