我在 Android 应用程序中使用 SAX 解析器一次读取一些提要。脚本执行如下。
// Begin FeedLezer
try {
/** Handling XML **/
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags **/
URL sourceUrl = new URL(
BronFeeds[i]);
/** Create handler to handle XML Tags ( extends DefaultHandler ) **/
Feed_XMLHandler myXMLHandler = new Feed_XMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
sitesList = Feed_XMLHandler.sitesList;
String titels = sitesList.getMergedTitles();
这里是Feed_XMLHandler.java和 Feed_XMLList.java ,我基本上都是从网络上获取的。
但是,此代码有时会失败。我将展示一些示例。
http://imm.io/media/2I/2IAs.jpg 这里进展顺利。它甚至可以识别并显示撇号。即使单击打开文章,几乎所有文本都会显示,所以这一切都很好。来源提要在这里。我无法控制饲料。
http://imm.io/media/2I/2IB1.jpg在这里,事情进展得不太顺利。它确实显示了 ï,但由于撇号而哽咽(Waarom 之后应该是“NORAD”)。 Here
http://imm.io/media/2I/2IBQ.jpg这是最糟糕的。正如您所看到的,标题仅显示一个撇号,而它应该是“blablabla”。此外,文本在行的中间结束,引号中没有任何特殊字符。 The feed is here
在所有情况下,我都无法控制 feed。我认为剧本确实因特殊角色而令人窒息。如何确保 SAX 正确获取所有字符串?
如果有人知道这个问题的答案,你真的帮了我很多忙:D
提前致谢。
最佳答案
这是来自 Xerces 的常见问题解答。
Why does the SAX parser lose some character data or why is the data split into several chunks? If you read the SAX documentation, you will find that SAX may deliver contiguous text as multiple calls to characters, for reasons having to do with parser efficiency and input buffering. It is the programmer's responsibility to deal with that appropriately, e.g. by accumulating text until the next non-characters event.
您的代码很好地改编自许多 XML 解析教程之一(例如 this 这里的一个)现在,该教程很好,但他们没有提到一些非常重要的事情......
请注意这里的这一部分...
public void characters(char[] ch, int start, int length)
throws SAXException
{
if(in_ThisTag){
myobj.setName(new String(ch,start,length))
}
}
我打赌此时您正在检查 boolean 值以标记您所在的标签,然后在某种 class
中设置一个值你做了?或类似的东西......
但问题是,SAX 解析器(已缓冲)不一定会一次性获取标签之间的所有字符......假设 if <tag> Lorem Ipsum...really long sentence...</tag>
所以你的 SAX 解析器调用 characters
功能是 block ......
所以这里的技巧是不断将值附加到字符串变量中,而实际上 set
当标签结束时(或提交)它到您的结构中...(即在 endElement
中)
示例
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("tag"))
{
sitesList.setName(currentValue);
currentValue = ""; //reset the currentValue
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (in_Tag) {
currentValue += new String(ch, start, length); //keep appending string, don't set it right here....maybe there's more to come.
}
}
另外,如果使用 StringBuilder
会更好用于附加,因为这样会更有效......
关于java - 为什么 SaxParser 会随机失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4527782/