Android Html.fromHtml() теряет HTML, если он начинается с тега<p>
Я называю веб-сервис, который возвращает HTML, заключенный в конверт XML... что-то вроде:
<xml version="1.0" cache="false">
<text color="white">
<p> Some text <br /> <p>
</text>
</xml>
Я использую XmlPullParser для анализа этого XML/HTML. Чтобы получить текст в элемент, я делаю следующее:
case XmlPullParser.START_TAG:
xmlNodeName = parser.getName();
if (xmlNodeName.equalsIgnoreCase("text")) {
String color = parser.getAttributeValue(null, "color");
String text = parser.nextText();
if (color.equalsIgnoreCase("white")) {
detail.setDetail(Html.fromHtml(text).toString());
}
}
break;
Это хорошо работает и получает текст или HTML в элемент, даже если он содержит некоторые HTML-теги.
Проблема возникает, когда Данные элемента начинаются с тега ,
Как я могу решить это?
РЕДАКТИРОВАТЬ
Спасибо Nikhil & Rajesh за то, что он указал, что ответ моей службы на самом деле не является действительным XML-элементом и элемент не закрыт должным образом. Но у меня нет контроля над сервисом, поэтому я не могу редактировать то, что вернул. Интересно, есть ли что-то вроде HTML Agility, которое может анализировать любой тип искаженного HTML или, по крайней мере, может получить то, что в HTML-тегах.. как внутри
ИЛИ что-нибудь еще, что я могу использовать для анализа того, что я получаю от сервиса, будет хорошо, если это прилично реализуемо.
Извините за мой плохой английский
3 ответа
Решение
Вдохновленный подходом Мартина по преобразованию полученных данных сначала в строку, я решил свою проблему в виде смешанного подхода.
Преобразуйте полученное значение InputStream в строку и замените ошибочный тег на "" (или как хотите):
InputStreamReader isr = new InputStreamReader(serviceReturnedStream);
BufferedReader br = new BufferedReader(isr);
StringBuilder xmlAsString = new StringBuilder(512);
String line;
try {
while ((line = br.readLine()) != null) {
xmlAsString.append(line.replace("<p>", "").replace("</p>", ""));
}
} catch (IOException e) {
e.printStackTrace();
}
Теперь у меня есть строка, которая содержит правильные данные XML (для моего случая), так что просто используйте обычный XmlPullParser для его анализа вместо того, чтобы анализировать его вручную:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser parser = factory.newPullParser();
parser.setInput(new StringReader(xmlAsString.toString()));
Надеюсь, это поможет кому-то!
Вы видите это поведение, потому что то, что у вас есть внутри <text>...</text>
Теги - это не текстовый элемент, а элемент узла XML. Вы должны заключить содержимое в раздел CDATA.
Изменить: Предоставление сегмента кода для моего предложения в комментарии. Он действительно работает с предоставленным вами примером XML.
StringBuffer html = new StringBuffer();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_TAG) {
String name = parser.getName();
if(name.equalsIgnoreCase("text")){
isText = true;
}else if(isText){
html.append("<");
html.append(name);
html.append(">");
}
} else if(eventType == XmlPullParser.END_TAG) {
String name = parser.getName();
if(name.equalsIgnoreCase("text")){
isText = false;
}else if(isText){
html.append("</");
html.append(name);
html.append(">");
}
} else if(eventType == XmlPullParser.TEXT) {
if(isText){
html.append(parser.getText());
}
}
eventType = parser.next();
}
Потому что выше код не закрывается "</p>"
ТЕГ.
<p> Some text <br /> </p>
Использовал эту строчку.