JAVA: сбор смещений байтов тегов xml с использованием XmlStreamReader - PullRequest
3 голосов
/ 05 июля 2010

Существует ли способ точного сбора смещений байтов тегов xml с помощью XMLStreamReader?

У меня большой XML-файл, к которому мне нужен произвольный доступ. Вместо того, чтобы записывать все это в базу данных, я бы хотел один раз прогнать ее через XMLStreamReader, чтобы собрать смещения байтов значимых тегов, а затем иметь возможность использовать RandomAccessFile для получения содержимого тегов позже.

У XMLStreamReader, похоже, нет способа отслеживать смещения символов. Вместо этого люди рекомендуют подключать XmlStreamReader к считывателю, который отслеживает, сколько байтов было прочитано (например, CountingInputStream, предоставленный apache.commons.io )

например:

CountingInputStream countingReader = new CountingInputStream(new FileInputStream(xmlFile)) ;
XMLStreamReader xmlStreamReader = xmlStreamFactory.createXMLStreamReader(countingReader, "UTF-8") ;


while (xmlStreamReader.hasNext()) {
    int eventCode = xmlStreamReader.next();

    switch (eventCode) {
        case XMLStreamReader.END_ELEMENT :
            System.out.println(xmlStreamReader.getLocalName() + " @" + countingReader.getByteCount()) ;
    }

}
xmlStreamReader.close();

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

Ответы [ 5 ]

2 голосов
/ 05 июля 2010

Вы можете использовать getLocation () для XMLStreamReader (или XMLEvent.getLocation (), если вы используете XMLEventReader), но я помню, что где-то читал, что это ненадежно и точно.И похоже, что он дает конечную точку тега, а не начальное местоположение.

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

1 голос
/ 27 апреля 2014

К сожалению, Aalto не реализует интерфейс LocationInfo.

Последняя реализация ximpleware Java VTD-XML, в настоящее время 2.11 http://sourceforge.net/projects/vtd-xml/files/vtd-xml/ обеспечивает некоторый код, сопровождающий байтовое смещение после каждого вызова метод getChar () его реализаций IReader.

Реализации IReader для различных кодировок символов доступны внутри VTDGen.java и VTDGenHuge.java

Реализации IReader предоставляются для следующих кодировок

ASCII;
ISO_8859_1
ISO_8859_10
ISO_8859_11
ISO_8859_12
ISO_8859_13
ISO_8859_14
ISO_8859_15
ISO_8859_16
ISO_8859_2
ISO_8859_3
ISO_8859_4
ISO_8859_5
ISO_8859_6
ISO_8859_7
ISO_8859_8
ISO_8859_9
UTF_16BE
UTF_16LE
UTF8;   
WIN_1250
WIN_1251
WIN_1252
WIN_1253
WIN_1254
WIN_1255
WIN_1256
WIN_1257
WIN_1258

Обновление IReader с помощью метода getCharOffset () и реализовать его добавив элемент charCount вместе со смещенным элементом VTDGen и VTDGenHuge классы и увеличивая его при каждом вызове getChar () и skipChar () каждой реализации IReader, вы получите начало решения.

1 голос
/ 05 июля 2010

Вы можете использовать входной поток-обертку вокруг фактического входного потока, просто откладывая в обернутый поток для фактических операций ввода-вывода, но сохраняя внутренний механизм подсчета с различным кодом для получения текущего смещения?

0 голосов
/ 16 мая 2017

Я недавно разработал решение для аналогичного вопроса по Как найти смещение символов в больших файлах XML с использованием Java? . Я думаю, что это обеспечивает хорошее решение, основанное на сгенерированном ANTLR XML-парсере.

0 голосов
/ 05 июля 2010

Я думаю, что нашел другой вариант.Если вы замените свой блок switch на следующий, он будет сбрасывать позицию сразу после тега конечного элемента.

        switch (eventCode) {
        case XMLStreamReader.END_ELEMENT :
            System.out.println(xmlStreamReader.getLocalName() + " end@" + xmlStreamReader.getLocation().getCharacterOffset()) ;
        }

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

Мне не удалось отследить некоторые незначительные несоответствия в управлении данными (я думаю, это связано с тем, как я инициализировал свой XMLStreamReader), но я всегда видел последовательное увеличение местоположения, когда читатель перемещался по контенту.

Надеюсь, это поможет!

...