Проблема XMLStreamReader - PullRequest
       12

Проблема XMLStreamReader

2 голосов
/ 15 ноября 2010

Я использую интерфейс XMLStreamReader из javax.xml для анализа XML-файла. Файл содержит огромные объемы данных и отдельные текстовые узлы размером в несколько килобайт.

Проверка и чтение, как правило, работают очень хорошо, но у меня проблемы с текстовыми узлами, длина которых превышает 15 000 символов. Проблема возникает в этой функции

String foo = "";
if (xsr.getEventType() == XMLStreamConstants.CHARACTERS) {
    foo = xsr.getText();
    xsr.next(); // read next tag
}
return foo;

xsr считыватель потоков. Текст в текстовом узле имеет длину 53'337 символов в данном конкретном случае (но различается), однако метод xsr.getText() возвращает только первые 15'537 из них. Конечно, я мог бы зациклить функцию и объединить строки, но почему-то я не думаю, что это идея ...

Я не нашел ничего в документации или где-либо еще об этом. Это предполагаемое поведение или кто-то может подтвердить / опровергнуть это? Я использую это как-то неправильно?

Спасибо

Ответы [ 2 ]

1 голос
/ 15 ноября 2010

Конечно, я мог бы зациклить функцию и объединить строки, но почему-то я не думаю, что это идея ...

На самом деле, есть idea:)

Синтаксическому анализатору разрешено разбивать поток событий по своему усмотрению, если он соответствует исходному документу.Это означает, что он может и часто будет разбивать ваши текстовые данные на несколько событий.Как и когда он решит это сделать, это деталь реализации, внутренняя для синтаксического анализатора, и по существу непредсказуемая.

Так что да, если вы получаете несколько последовательных событий CHARACTERS, вам нужно добавить их вручную.Это цена, которую вы платите за API низкого уровня.

0 голосов
/ 28 декабря 2011

Другим вариантом является параметр javax.xml.stream.isCoalescing (задокументированный в XMLStreamReader.next () или с использованием StAX ), который автоматически объединяет длинный текст в одну строку. Следующий тест JUint3 успешно пройден.

Предупреждение : isCoalescing, вероятно, не должен использоваться в рабочей среде, потому что, если в документе много ссылок на символы ( ) или ссылок на сущности (<), это вызовет StackOverflowError!

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import junit.framework.TestCase;

public class XmlStreamTest extends TestCase {
    public void testLengthInXMlStreamReader() throws XMLStreamException {
        StringBuilder b = new StringBuilder();
        b.append("<root>");
        for (int i = 0; i < 65536; i++)
            b.append("hello\n");
        b.append("</root>");
        InputStream is = new ByteArrayInputStream(b.toString().getBytes());
        XMLInputFactory inputFactory = XMLInputFactory.newFactory();
        inputFactory.setProperty("javax.xml.stream.isCoalescing", true);
        XMLStreamReader reader = inputFactory.createXMLStreamReader(is);
        reader.nextTag();
        reader.next();
        assertEquals(6 * 65536, reader.getTextLength());
    }
}
...