Android SAX解析器未从标签之间获取全文

问题描述 投票:21回答:3

我已经创建了自己的DefaultHandler来解析rss提要,对于大多数提要来说,它都可以正常工作,但是,对于ESPN,由于ESPN格式化其网址的方式,它切断了部分文章网址。来自ESPN的完整文章网址的示例。

http://sports.espn.go.com/nba/news/story?id=5189101&campaign=rss&source=ESPNHeadlines

问题是由于某种原因,DefaultHandler字符方法仅从包含上述url的标记中获取。

http://sports.espn.go.com/nba/news/story?id=5189101

如您所见,它切断了与号转义代码及其后的URL中的所有内容。我怎样才能使SAX解析器不要在此转义代码处截断我的字符串?对于参考。这是我的角色方法。.

 public void characters(char ch[], int start, int length) {

  String chars = (new String(ch).substring(start, start + length));

  try {
   // If not in item, then title/link refers to feed
   if (!inItem) {
    if (inTitle)
     currentFeed.title = chars;
   } else {
    if (inLink)
     currentArticle.url = new URL(chars);
    if (inTitle)
     currentArticle.title = chars;
    if (inDescription)
     currentArticle.description = chars;
    if (inPubDate)
     currentArticle.pubDate = chars;
    if (inEnclosure) {
    }
   }
  } catch (MalformedURLException e) {
   Log.e("RSSReader", e.toString());
  }
 }

Rob W。

android parsing escaping sax
3个回答
46
投票

如您所见,网址中的所有内容和号后缀代码。

documentation方法的characters()

解析器将调用此方法以报告每个字符数据块。SAX解析器可能会返回所有连续的单个块中的字符数据,或他们可能将其分成几块;但是,任何单个事件必须来自同一事件外部实体,以便定位器提供有用的信息。

当我编写SAX解析器时,我使用StringBuilder将传递的所有内容附加到characters()

public void characters (char ch[], int start, int length) {
    if (buf!=null) {
        for (int i=start; i<start+length; i++) {
            buf.append(ch[i]);
        }
    }
}

然后在endElement()中,我获取StringBuilder的内容并对其进行处理。这样,如果解析器多次调用characters(),我将不会错过任何内容。


6
投票
@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    sb=new StringBuilder();
    if(localName.equals("icon"))
    {
        iconflag=true;
    }
}

@Override
public void characters (char ch[], int start, int length) {
    if (sb!=null && iconflag == true) {
        for (int i=start; i<start+length; i++) {
            sb.append(ch[i]);
        }
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    // TODO Auto-generated method stub
    if(iconflag)
    {
        info.setIcon(sb.toString().trim());
        iconflag=false;
    }
}

所以我想通了,上面的代码是解决方案。


0
投票

前几天我遇到了这个问题,原来是因为如果值中包含以下任何字符,都会多次调用CHaracters方法:

"   &quot;
'   &apos;
<   &lt;
>   &gt;
&   &amp;

也要注意值内的换行符/换行符!!!如果xml在没有您的控制的情况下被换行,则还会为该语句中的每一行调用character方法,此外它将返回换行符! (您需要依次手动删除)。

处理所有这些问题的示例处理程序是这个:

 DefaultHandler handler = new DefaultHandler() {
   private boolean isInANameTag = false;
   private String localname;
   private StringBuilder elementContent;

   @Override
   public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
    if (qname.equalsIgnoreCase("myfield")) {
      isInMyTag = true;
      this.localname = localname;
      this.elementContent = new StringBuilder();
    }
   }

   public void characters(char[] buffer, int start, int length) {
      if (isInMyTag) {
         String content = new String(ch, start, length);
         if (StringUtils.equals(content.substring(0, 1), "\n")) {
              // remove leading newline
              elementContent.append(content.substring(1));
         } else {
              elementContent.append(content);
         }
      }
   }

   public void endElement(String uri, String localName, String qName) throws SAXException {
     if (qname.equalsIgnoreCase("myfield")) {
       isInMyTag = false;
       // do something with elementContent.toString());
       System.out.println(elementContent.toString());
       this.localname = "";
     }
   }
}

我希望这会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.