LINUX.ORG.RU

SAX xml parser, амперсанды

 , ,


0

1

Немного запутался с xml-парсером. ЯП - Java, использую SAX-парсер.

Есть довольно сложный и запутанный xml-файл (если точнее, это RSS-лента). Основная сложность в том, что он содержит такие теги (для примера сильно упростил):

<tag1>value1</tag1>
<tag2>value2</tag2>
....
<bigtag>&lt;b&gt;Bold Text&lt;/b&gt;
&lt;a href="http://google.com"&gt;
&lt;img src="http://example.com/image.png"&gt;
</bigtag>

В общем, по сути внутри xml-тега целая html-страница (ну не страница, но код в разметке html, естественно с кучей угловых скобок. они экранированы (&lt, &gt).

Проблема в том, что SAX-parser (по умолчанию в Java) «не берёт» всё содержимое тега, а «откусывает» только до первого амперсанда. (речь о методе handler.characters())

Использовал примерно такой простой рецепт (изменил под себя) http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

Какой наиболее безболезненный способ эту проблему решить?

(задача вообще в чём - xml имеет вполне определённую структуру - мне надо его распарсить и сохранить в простой Plain old java object (все поля обычные String), ну и потом сохранить в базу данных, это уже тонкости. То есть этот html код тоже сохранить в виде строки (потом подумаю, как его использовать, пока это не важно), или в неизменном виде, или заменить все &lt и &gt на < и > соответственно.

Метод characters() может вызываться несколько раз для одного тега. По кусочкам.

anonymous
()

Просто интересно, для кого CDATA придумали?

zJes ★★
()
Ответ на: комментарий от BattleCoder

В документации SAX. Я тоже проглядел в свое время.

Это делается примерно так (Например, внутри тэга есть табы, возвраты каретки и прочее) :

public void characters(char[] ch, int start, int length) throws SAXException {
	for (int i = start; i < start + length; i++) {
		switch (ch[i]) {
		case '\n':
			break;
		case '\r':
			break;
		case '\t':
			break;
		default:
			lastValue.append(ch[i]);
			break;
		}
	}
}
eagleivg ★★★★★
()
Ответ на: комментарий от eagleivg

глупый вопрос: а зачем игнорировать табы, возвраты каретки и прочее в xml=документе? (да и не факт, что они у меня есть в конкретном случае, но это не так важно). что мешает их запилить в строку? экономия байтов? :) или какая-то другая причина?

или я вообще неправильно понял суть примера?

я вообще делал так:

new String(ch,start,length)

и уже эту строку запихивал целиком в переменную. я так понял, достаточно это не запихивать целиком в переменную - а добавлять в существующую переменную (например, stringbuilder.append()) при каждому вызове characters().

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от anonymous

А можно всё-таки ткнуть носом, где это написано?

Полазил по http://www.saxproject.org , в том числе javadoc посмотрел, не нашёл, чтобы написано было, что вызывается несколько раз.

Сейчас конечно код попробую изменить и посмотрю, что получится.

BattleCoder ★★★★★
() автор топика

Всем спасибо, исправленный вариант работает.

BattleCoder ★★★★★
() автор топика
Ответ на: комментарий от BattleCoder

Верно, весь смысл в аппенде при каждом вызове characters(). Зачем игнорить табы и прочее - сейчас уже не вспомню, но с ними был какой-то косяк. Или задача так стояла.

eagleivg ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.