当前位置: 首页 > 面试题库 >

Transformer.setOutputProperty(OutputKeys.ENCODING,“ UTF-8”)无法正常工作

广亮
2023-03-14
问题内容

我有以下方法将XMLDom写入流:

public void writeToOutputStream(Document fDoc, OutputStream out) throws Exception {
    fDoc.setXmlStandalone(true);
    DOMSource docSource = new DOMSource(fDoc);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty(OutputKeys.INDENT, "no");
    transformer.transform(docSource, new StreamResult(out));
}

我正在测试其他XML功能,而这只是我用来写入文件的方法。我的测试程序生成了33个测试用例,其中文件被写出。其中28个具有以下标头:

<?xml version="1.0" encoding="UTF-8"?>...

但是由于某种原因,现在有一个测试用例产生:

<?xml version="1.0" encoding="ISO-8859-1"?>...

还有另外四个产品:

<?xml version="1.0" encoding="Windows-1252"?>...

如您所见,我将ENCODING输出键设置为UTF-8。这些测试过去可用于Java的早期版本。我已经有一段时间(一年多了)没有运行测试,但是今天在“
Java(TM)SE运行时环境(内部版本1.6.0_22-b04)”上运行,我得到了这种有趣的行为。

我已经验证了导致该问题的文档是从最初具有这些编码的文件中读取的。似乎新版本的库正在尝试保留已读取的源文件的编码。但这不是我想要的……我确实希望输出为UTF-8。

有谁知道其他因素可能导致变压器忽略UTF-8编码设置?还需要在文档上设置其他内容,以忘记最初读取的文件的编码吗?

更新:

我在另一台计算机上签出了相同的项目,并在那里进行了测试。在那台机器上,所有测试均通过!所有文件的标题中都带有“ UTF-8”。该机器具有“
Java™SE运行时环境(内部版本1.6.0_29-b11)”,两台计算机都运行Windows7。在可以正常工作的新机器上,使用jdk1.5.0_11进行了构建,但是在旧机器上机器jdk1.6.0_26用于进行构建。这两个版本使用的库完全相同。在构建时是否可能与JDK
1.6不兼容1.5?

更新:

4.5年后,Java库仍然损坏,但是由于以下Vyrx的建议,我终于有了一个适当的解决方案!

public void writeToOutputStream(Document fDoc, OutputStream out) throws Exception {
    fDoc.setXmlStandalone(true);
    DOMSource docSource = new DOMSource(fDoc);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.setOutputProperty(OutputKeys.INDENT, "no");
    out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>".getBytes("UTF-8"));
    transformer.transform(docSource, new StreamResult(out));
}

解决方案是禁用标题的编写,并在将XML序列化到输出流之前,编写正确的标题。me脚,但它产生正确的结果。超过4年前的测试现在又可以运行!


问题答案:

序列化表情符号字符时,我在Android上遇到相同的问题。在转换器中使用UTF-8编码时,输出为HTML字符实体(UTF-16代理对),这些实体随后将破坏读取数据的其他解析器。

这就是我最终解决它的方式:

StringWriter sw = new StringWriter();
sw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
Transformer t = TransformerFactory.newInstance().newTransformer();

// this will work because we are creating a Java string, not writing to an output
t.setOutputProperty(OutputKeys.ENCODING, "UTF-16"); 
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.transform(new DOMSource(elementNode), new StreamResult(sw));

return IOUtils.toInputStream(sw.toString(), Charset.forName("UTF-8"));


 类似资料:
  • 问题内容: 考虑以下方法,该方法将返回一个字段(如果存在)或递归调用自身直到找到该字段: 虽然这可行,但我想可以将其缩短为: 但是奇怪的是,该部分似乎总是被调用。 我在这里想念什么? 问题答案: 方法的参数始终在调用方法之前进行求值。您想要带一个仅在不存在时才被调用的:

  • 问题内容: 我正在尝试运行selenium测试。但是,每次尝试运行应该运行IE的测试时,我都会在htmlutils.js的863行收到错误消息,它表示我应该禁用弹出窗口阻止程序。事情是我去了IE工具->弹出窗口块。 所以它被禁用,我得到这个错误。 还有什么我需要禁用的吗?实际上,我什至不知道它正在运行哪个版本的Internet Explorer,因为我使用的是Windows 7 Pro 64位版本

  • 我正在用Laravel 8制作一个论坛,基本上每当用户在这个论坛上提问时,它应该被重定向到这个问题。 我还想使重定向过程基于问题的字段。 因此,为了做到这一点,我在方法的末尾添加了以下内容: 下面是看问题的路线: 然后我在控制器编码: 但现在的问题是,当我尝试添加新问题时,该问题将成功添加,但它会将我重定向到页面。重定向后的URL也如下所示: 正如你所看到的问题没有正确添加! 那么这里出了什么问题

  • 当我双击可以编辑的单元格时,网格的Vaadin 8编辑器无法正常工作。 我使用简单的代码来创建网格并添加一个列编辑器组件。 接下来,我运行应用程序并开始滚动网格,直到列“计划状态”。 那么。我该怎么做,或者如何修复它以在网格中正确打开编辑器?

  • 我正在尝试从谷歌获取jwk密钥集,以便与Apache Cxf OIDC和Jose Libs一起使用。当我在一个独立的main方法上运行它时,代码工作得很好。 ID、算法、密钥类型和使用正确打印,这意味着密钥是属性填充的。 样本输出: pom公司。Main类的xml提取。 但是,在Tomee 8中部署时,相同的代码不起作用。 当此代码在Tomee 8中运行时,ID、算法、密钥类型和用途为空。我已经添

  • 问题内容: 我正在尝试使用DOMDocument解析一些HTML,但是当我这样做时,我突然失去了编码(至少这对我来说是这样)。 这段代码的结果是我得到了一堆不是日语的字符。但是,如果我这样做: 正确显示。我尝试过saveHTML和saveXML,但都无法正确显示。我正在使用PHP 5.3。 我所看到的: 应该显示什么: 编辑:我已经将代码简化为五行,因此您可以自己对其进行测试。 这是返回的html