2009-12-11 4 views
6

У меня есть контакт, который испытывает проблемы с SAX при анализе файлов RSS и Atom. По его словам, как будто текст, исходящий из элементов Item, усекается при апострофе или иногда акцентированном персонаже. Кажется, что проблема с кодировкой тоже.Sax parsing and encoding

Я попробовал SAX, и у меня тоже есть усечение, но еще не удалось выкопать. Я был бы признателен за некоторые предложения, если кто-то из них уже справился с этим.

Это код, который используется в ContentHandler:

public void characters(char[], int start, int end) throws SAXException { 
// 
    link = new String(ch, start, end); 

Edit: Проблема кодирования может быть связано с хранением информации в виде массива байтов, как я знаю, Java работает в Unicode.

+1

Большинство людей используют SAX, потому что разбор DOM медленный и интенсивный. Если только компромисс заключается в том, что синтаксический анализ SAX становится очень нежелательным, если структура документа, если она сложна, если вы обнаружите, что SAX синтаксический анализ сложный или слишком низкий уровень, vtd-xml может быть лучшим выбором для сочетания лучших характеристик производительности и низкой памяти. –

ответ

13

Метод characters() не гарантирует полного содержимого символов текстового элемента за один проход - полный текст может охватывать границы буфера. Вы должны сами буферизировать символы между событиями начала и конца элемента.

например.

StringBuilder builder; 

public void startElement(String uri, String localName, String qName, Attributes atts) { 
    builder = new StringBuilder(); 
} 

public void characters(char[] ch, int start, int length) { 
    builder.append(ch,start,length); 
} 

public void endElement(String uri, String localName, String qName) { 
    String theFullText = builder.toString(); 
} 
+0

Не следует ли синхронизировать приложение StringBuilder? или использовать StringBuffer? – ruchirhhi

+0

Синхронизация не требуется - синтаксический анализ SAX является однопоточным, и обычно для каждого анализируемого документа используется отдельный ContentHandler. Если вы хотите повторно использовать ContentHandlers, вам лучше использовать ThreadLocal или другой механизм объединения - было бы очень сложно написать ContentHandler, который мог бы одновременно обрабатывать несколько потоков синтаксического разбора в отдельных потоках, как бы он отслеживал, какое событие произошло из какой документ? –

+0

Спасибо! Спас мой день. –

1

Как вы передаете вход SAX? Как InputStream (рекомендуется) или Reader? Итак, начиная с вашего байта [], попробуйте использовать ByteArrayInputStream.

+0

Egon , Я заглянул в класс Channel и используется XMLReader. ContentHandler установлен, а затем вызывается метод parse(). Это похоже на это. –

+0

Вы можете посмотреть мой код: http://cdk.git.sourceforge.net/git/gitweb.cgi?p=cdk/cdk;a=blob;f=src/main/org/openscience/cdk/ io/CMLReader.java; h = 490743955939b8a003c95769c3261b06eb341842; hb = HEAD –

+0

BTW, какой анализатор XML вы используете? Код, который я только что связал, позволяет использовать три разных синтаксических анализатора XML: по умолчанию используется версия (более новая) Java, а затем Aelfred, последняя Xerces. –

5

XML entities создавать специальные мероприятия в SAX. Вы можете поймать их с LexicalHandler, хотя это вообще не нужно. Но это объясняет , почему нельзя предположить, что вы получите только одно событие characters за тег. Используйте буфер, как описано в других ответах.

Например hello&world будет генерировать последовательность

  • StartElement
  • символы привет
  • startEntity
  • символов &
  • endEntity
  • символов мира

Посмотрите на Auxialiary SAX interface, если хотите еще несколько примеров. Другие специальные события - внешние лица, комментарии, CDATA и т. Д.

 Смежные вопросы

  • Нет связанных вопросов^_^