【问题标题】:How to Preserve the Input's Declared Encoding in the Output of javax.xml.transform.Transformer.transform? (e.g. avoid UTF-16 changing to UTF-8)如何在 javax.xml.transform.Transformer.transform 的输出中保留输入声明的编码? (例如,避免将 UTF-16 更改为 UTF-8)
【发布时间】:2011-06-18 20:19:26
【问题描述】:

假设这个输入 XML

<?xml version="1.0" encoding="UTF-16"?>
<test></test>

编写这些代码行:

StreamSource source = new StreamSource(new StringReader(/* the above XML*/));
StringWriter stringWriter = new StringWriter();
StreamResult streamResult = new StreamResult(stringWriter);
TransformerFactory.newInstance().newTransformer().transform(source, streamResult);
return stringWriter.getBuffer().toString();

为我输出这个 XML:

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

(将声明的UTF-16编码转换为默认的UTF-8)

我知道我可以明确要求 UTF-16 输出

transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-16");

但问题是,如何让输出编码自动和输入一样?

【问题讨论】:

  • 如果不先手动查看输入流,我认为这是不可能的。顺便说一句,如果您使用 XML 标头的编码,则不能使用字符串,只能使用字节数组。
  • 出于好奇:为什么存在这个要求?如果使用 UTF-8 编码,生成的 XML 应该同样有效。

标签: java xml character-encoding xslt


【解决方案1】:

为此,您必须使用比StreamSource 更复杂的东西。例如,StAXSource 采用XMLStreamReader,它具有getCharacterEncodingScheme() 方法,可以告诉您输入文档使用的编码 - 您可以将其设置为输出编码。

【讨论】:

    【解决方案2】:

    试试这个:

    // Create an XML Stream Reader
    XMLStreamReader xmlSR = XMLInputFactory.newInstance()
            .createXMLStreamReader(new StringReader(/* the above XML*/));
    // Wrap the XML Stream Reader in a StAXSource
    StAXSource source = new StAXSource(xmlSR);
    // Create a String Writer
    StringWriter stringWriter = new StringWriter();
    // Create a Stream Result
    StreamResult streamResult = new StreamResult(stringWriter);
    // Create a transformer
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    // Set STANDALONE based on the source stream
    transformer.setOutputProperty(OutputKeys.STANDALONE,
            xmlSR.isStandalone() ? "yes" : "no");
    // Set ENCODING based on the source stream
    transformer.setOutputProperty(OutputKeys.ENCODING,
            xmlSR.getCharacterEncodingScheme());
    // Set VERSION based on the source stream
    transformer.setOutputProperty(OutputKeys.VERSION, xmlSR.getVersion());
    // Transform the source stream to the out stream
    transformer.transform(source, streamResult);
    // Print the results
    return stringWriter.getBuffer().toString();
    

    【讨论】:

    • 我得到:无法转换 javax.xml.transform.stax.StAXSource 类型的源
    【解决方案3】:

    您需要先窥视信息流。 XML specification 的 F 部分让您了解如何自动检测编码。

    【讨论】:

    • 请不要自己编写代码来确定编码。它会坏掉。
    【解决方案4】:

    XSLT 处理器实际上并不知道输入编码是什么(XML 解析器不会告诉它,因为它不需要知道)。您可以使用 xsl:output 设置输出编码,但要使其与输入编码相同,您必须首先发现输入编码,例如在解析源文件之前先查看它。

    【讨论】:

    • +1 正确答案。在解析和信息集构建之后,不需要这些数据,这就是为什么不作为信息集的一部分保留。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 2012-06-30
    • 2012-11-07
    • 1970-01-01
    • 2011-03-18
    相关资源
    最近更新 更多