变压器不从文档对象读取特殊字符

时间:2013-12-30 06:26:23

标签: java xml xslt encoding utf-8

我正在尝试从Document Object读取xml数据,然后使用transform将文档对象内的数据渲染为pdf,使用XSL,

我的代码是:

Document doc = toXML(arg1,arg2);

doc包含以下数据:   的İlkyönetmeliği   with in标签

InputStream inputStream = new FileInputStream(xslFilePath);
transformer = factory.newTransformer(new StreamSource(inputStream));
transformer.setParameter("encoding", "UTF-8");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc.getDocumentElement()), res);

xml中存在的特殊字符未相应呈现并显示为

#lk yard #m

我还将编码设置为UTF-8,但仍然显示如上所示。

1 个答案:

答案 0 :(得分:0)

目前尚不清楚是什么原因导致您的编码问题,因为我无法看到您的文档的读取/构建方式以及转换结果res的设置方式。尝试以下使用XSLT处理编码的独立示例代码。也许您甚至可以逐渐修改它以使用您的实际数据来查看出现了什么问题。

public static void main(String[] args) {
    try {
        String inputEncoding = "UTF-16";
        String xsltEncoding = "ASCII";
        String outputEncoding = "UTF-8";

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(bos, inputEncoding);
        osw.write("<?xml version='1.0' encoding='" + inputEncoding + "'?>");
        osw.write("<root>İlkyönetmeliği</root>"); osw.close();
        byte[] inputBytes = bos.toByteArray();
        bos.reset();

        osw = new OutputStreamWriter(bos, xsltEncoding);
        osw.write("<?xml version='1.0' encoding='" + xsltEncoding + "'?>");
        osw.write("<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>");
        osw.write("<xsl:template match='@*|node()'><xsl:copy><xsl:apply-templates select='@*|node()'/></xsl:copy></xsl:template>");
        osw.write("</xsl:stylesheet>"); osw.close();
        byte[] xsltBytes = bos.toByteArray();
        bos.reset();

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document d = db.parse(new InputSource(new InputStreamReader(new ByteArrayInputStream(inputBytes), inputEncoding)));
        // if encoding declaration correct, use: Document d = db.parse(new InputSource(new ByteArrayInputStream(inputBytes)));
        System.out.println(XPathFactory.newInstance().newXPath().evaluate("/root[1]", d));

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer(new StreamSource(new InputStreamReader(new ByteArrayInputStream(xsltBytes), xsltEncoding)));
        // if encoding declaration correct, use: Transformer t = tf.newTransformer(new StreamSource(new ByteArrayInputStream(xsltBytes)));
        StreamResult sr = new StreamResult(new OutputStreamWriter(bos, outputEncoding));
        t.setOutputProperty(OutputKeys.ENCODING, outputEncoding);
        t.transform(new DOMSource(d.getDocumentElement()), sr);
        byte[] outputBytes = bos.toByteArray();

        Scanner s = new Scanner(new InputStreamReader(new ByteArrayInputStream(outputBytes), outputEncoding));
        String output = s.useDelimiter("</>").next(); // read all
        s.close();

        System.out.println(output);
    } catch (Exception ex) {
        ex.printStackTrace(System.err);
    }

示例代码将XSLT identity template应用于包含非ASCII字符的最小输入。

我输出字符串以检查它是否已使用XPath在文档中正确解析。如果您知道如何使用XPath找到它,则可能需要检查(中间)文档。

请注意,如果存在,解析器会在读取XML文件时尝试选择在XML处理指令(PI)中声明的编码。它假定实际和声明的编码是相同的。如果它们不同或缺少PI,那么您可以强制执行实际编码,例如使用上面代码中的InputStreamReader