1

以下のコードは、 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
} 

これの底に達することができるそこにあるエンコーディングの専門家はいますか?

4

1 に答える 1

1

今日、私はこのコメントに苦労しました。このコードには重要な問題が 1 つあります (Java の奇妙な構文にセミコロンがないなどのほかに)。

読み取るときは、SAXSource ではなく EXISource を使用してください。

動作するコードを添付しました。

-- ダニエル

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));
}
于 2017-04-04T06:52:34.043 に答える