我已经创建了自己的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。
如您所见,网址中的所有内容和号后缀代码。
从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()
,我将不会错过任何内容。
@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;
}
}
所以我想通了,上面的代码是解决方案。
前几天我遇到了这个问题,原来是因为如果值中包含以下任何字符,都会多次调用CHaracters方法:
" "
' '
< <
> >
& &
也要注意值内的换行符/换行符!!!如果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 = "";
}
}
}
我希望这会有所帮助。