Android Html.fromHtml()如果以<p>标记</p>开头,则会丢失HTML

时间:2012-04-19 10:38:48

标签: android android-xml android-pullparser

我调用一个Web服务,它返回一些包含在XML信封中的HTML ......类似于:

<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。

元素的数据以&lt; p&gt; 标记开头时出现问题,如上例所示。在这种情况下,数据将丢失,文本为空。

我该如何解决这个问题?

修改

感谢Nik&amp; rajesh指出我的服务的响应实际上不是有效的XML&amp;元素未正确关闭。但我无法控制服务,所以我无法编辑返回的内容。我想知道是否有类似HTML Agility的内容可以解析任何类型的格式错误的HTML,或者至少可以在html标签中找到什么内容..就像在&lt; text&gt;里面一样...&lt; / text&gt; 在我的情况下?那也不错。

或者我可以用来解析我从服务中得到的东西的其他任何东西都是好的,只要它可以很好地实现。

对不起我的英语不好

3 个答案:

答案 0 :(得分:3)

您看到的是这种行为,因为<text>...</text>标记内的内容不是文本元素,而是XML Node元素。您应将内容包含在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();
         }

答案 1 :(得分:2)

因为上面的代码,您不会关闭"</p>" TAG。

<p> Some text <br /> </p>

使用此行。

答案 2 :(得分:1)

解决方案

通过Martin's方法将接收到的数据首先转换为字符串,我用一种混合方法管理我的问题。

将收到的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()));

希望这有助于某人!