【发布时间】:2020-09-24 14:59:58
【问题描述】:
我需要生成一个包含一些数据的 XML 文件,以发送到我没有实际操作的第 3 方系统(由另一家公司制造,我无法修改或要求修改)
这个其他系统不接受我生成的文档,因为它有一些用于空元素的自闭合标签:<tag/> 而不是 <tag></tag>
我当前的代码是这样的
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
StreamResult streamResult = new StreamResult(file);
transformer.transform(source, streamResult);
为了生成全结束标签,我尝试让Transformer 使用html 输出方法:
transformer.setOutputProperty(OutputKeys.METHOD, "html");
来源:http://makble.com/the-self-closing-tag-problem-of-javaxxmltransform-package-dom-to-source
这可以使用完整的结束标签,但我还有其他问题:
- 没有生成XML文档起始标签(如
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>) - 特殊字符以 HTML 方式生成(例如
&eacute;而不是é)
所以我发现我可以像这样使用StAXResult 而不是StreamResult:
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(new BufferedWriter(new FileWriter(nomFichier)));
StAXResult streamResult = new StAXResult(writer);
transformer.transform(source, streamResult);
这也适用于在空元素上使用完整的结束标记,但我的 XML 文档开始标记不完整:
<?xml version="1.0"?>
如果我尝试使用 Transformer 的输出属性来定义它,这不起作用:
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.VERSION, "1.0");
transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
由于使用了StAXResult,所有属性都被忽略
Michael Kay (https://stackoverflow.com/users/415448/michael-kay) 在Processing xml file (Java) 中明确表示:
调用
Transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");无效,除非变压器正在生产 序列化输出。在您的情况下,变压器不生产 序列化输出,因为您将输出发送到 StAXResult
我尝试配置 XMLStreamWriter 至少来定义编码:
XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(new BufferedWriter(new FileWriter(nomFichier)));
writer.writeStartDocument("ISO-8859-1", "1.0");
StAXResult streamResult = new StAXResult(writer);
transformer.transform(source, streamResult);
这会导致添加“正确”的起始 XML 标记,但我也有来自 Transformer 的默认标记:
<?xml version="1.0" encoding="ISO-8859-1"?><?xml version="1.0"?>
最后我尝试删除 Transformer 默认标签:
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
但正如已经说过的那样,这不起作用,因为 Transformer 的输出属性被忽略了......
我有什么想法可以同时拥有所有这些吗?
- 有效的 XML 起始标签 (
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>) - 正确的字符编码(
é而不是&eacute;) - 元素为空时的完整结束标记(
<tag></tag>而不是<tag/>)
我看到的唯一方法是使用XMLStreamWriter 和StAXResult 编写文档,然后处理生成的文件以解析它并删除<?xml version="1.0"?> 元素并将其替换为硬编码的<?xml version="1.0" encoding="ISO-8859-1"?> 字符串,但我并不想仅仅为此解析我生成的 XML 文件,因为它可能非常大。
我正在寻找更优雅的解决方案!
提前感谢您的帮助。
【问题讨论】: