在提取EXI压缩的XML时编码问题

时间:2013-01-17 21:17:44

标签: java groovy exi exificient

以下代码尝试使用EXIficient

简化执行EXI压缩和解压缩所需的设置
class ExiCompressionUtils {
    static Transformer transformer = TransformerFactory.newInstance().newTransformer()

    static byte[] compress(String xml) {
        ByteArrayOutputStream exiOS = new ByteArrayOutputStream()
        EXIResult exiResult = new EXIResult(outputStream : exiOS)

        XMLReader xmlReader = XMLReaderFactory.createXMLReader()
        xmlReader.contentHandler = exiResult.handler
        xmlReader.parse(new InputSource(new StringReader(xml)))

        def compressed = exiOS.toByteArray()
        exiOS.close()
        return compressed
    }

    static String extract(byte[] compressed) {
        SAXSource exiSource = new SAXSource(new InputSource(new ByteArrayInputStream(compressed)))
        exiSource.setXMLReader(exiSource.reader)

        ByteArrayOutputStream exiOS = new ByteArrayOutputStream()
        transformer.transform(exiSource, new StreamResult(exiOS))  // fails here
        def extracted = exiOS.toString()
        exiOS.close()
        return compressed
    }
}

以下测试失败,ERROR: 'Invalid byte 1 of 1-byte UTF-8 sequence.'

@Test
void testExiCompression() {
    def xml = '<Root><Child id="1">Text</Child><EmptyTag/></Root>'
    def compressed = ExiCompressionUtils.compress(xml)
    assert ExiCompressionUtils.extract(compressed) == xml
} 

那里的任何编码专家都可以了解到这一点吗?

1 个答案:

答案 0 :(得分:1)

今天我在这个评论上挣扎。这段代码有一个重要问题(除了Java缺少分号的奇怪语法等)。

阅读时使用EXISource而不是SAXSource!

附上有效的代码片段。

- 丹尼尔

static Transformer transformer;

static {
    try {
        transformer = TransformerFactory.newInstance().newTransformer();
    } catch (TransformerConfigurationException e) {
    } catch (TransformerFactoryConfigurationError e) {
    }
}

static byte[] compress(String xml) throws IOException, EXIException,
        SAXException {
    ByteArrayOutputStream exiOS = new ByteArrayOutputStream();
    EXIResult exiResult = new EXIResult();
    exiResult.setOutputStream(exiOS);

    XMLReader xmlReader = XMLReaderFactory.createXMLReader();
    xmlReader.setContentHandler(exiResult.getHandler());
    xmlReader.parse(new InputSource(new StringReader(xml)));

    byte[] compressed = exiOS.toByteArray();
    exiOS.close();

    return compressed;
}

static String extract(byte[] compressed) throws TransformerException,
        IOException, EXIException {
    // SAXSource exiSource = new SAXSource(new InputSource(new
    // ByteArrayInputStream(compressed))); // use EXISource instead!
    SAXSource exiSource = new EXISource();
    exiSource.setInputSource(new InputSource(new ByteArrayInputStream(
            compressed)));

    ByteArrayOutputStream exiOS = new ByteArrayOutputStream();
    transformer.transform(exiSource, new StreamResult(exiOS));
    String extracted = exiOS.toString();
    exiOS.close();
    return extracted;
}

public static void main(String[] args) throws IOException, EXIException,
        SAXException, TransformerException {
    String xml = "<Root><Child id=\"1\">Text</Child><EmptyTag/></Root>";
    byte[] compressed = ExiCompressionUtils.compress(xml);
    System.out.println(ExiCompressionUtils.extract(compressed));
}