Android SAX 解析器没有从标签之间获取全文
Posted
技术标签:
【中文标题】Android SAX 解析器没有从标签之间获取全文【英文标题】:Android SAX parser not getting full text from between tags 【发布时间】:2011-02-19 18:05:13 【问题描述】:我已经创建了自己的 DefaultHandler 来解析 rss 提要,并且对于大多数提要来说它工作正常,但是,对于 ESPN,由于 ESPN 格式化它的 url 的方式,它正在切断部分文章 url。来自 ESPN 的完整文章 URL 示例。
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("Rs-s-reader", e.toString());
罗伯·W.
【问题讨论】:
【参考方案1】:如您所见,它正在切割 网址中的所有内容 &符号转义码及之后。
来自characters()
方法的documentation:
解析器会调用这个方法来 报告每一块字符数据。 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()
,我不会错过任何东西。
【讨论】:
好吧,我并没有真正花时间完全理解解析器是如何工作的。阅读您的答案后,我回去进一步研究以获得更好的理解。你的建议当然是问题所在,我已经更新了我的代码以正确处理 char 数据。 TY @CommonsWare:会漏掉一些字符吗?在我的情况下,我正面临它。 我的 xml 中有startElement()
和 endElement()
方法中得到它。【参考方案2】:
@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;
所以我想通了,上面的代码就是解决方案。
【讨论】:
【参考方案3】:前几天我遇到了这个问题,原来这是因为字符方法被多次调用,以防这些字符中的任何一个包含在值中:
" "
' '
< <
> >
& &
还要小心值内的换行符/换行符!!! 如果 xml 在没有您控制的情况下被换行,则还将为语句中的每一行调用 characters 方法,并且它将返回换行符! (您需要依次手动剥离)。
处理所有这些问题的示例处理程序是这个:
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 = "";
我希望这会有所帮助。
【讨论】:
以上是关于Android SAX 解析器没有从标签之间获取全文的主要内容,如果未能解决你的问题,请参考以下文章