Проблемы с кодированием при извлечении EXI-сжатого XML
Приведенный ниже код является попыткой упростить настройку, необходимую для выполнения сжатия и распаковки EXI с использованием EXIficient.
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 ответ
Решение
Сегодня я боролся за этот комментарий. В этом коде есть одна важная проблема (кроме странного синтаксиса для 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));
}