【问题标题】:Why does SaxParser fail at random?为什么 SaxParser 随机失败?
【发布时间】:2010-12-24 18:28:30
【问题描述】:

我在我的 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.javaFeed_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

在所有情况下,我都无法控制提要。我认为脚本确实会因特殊字符而窒息。如何确保 SAX 正确获取所有字符串?

如果有人知道这个问题的答案,你真的帮了我很多:D

提前致谢。

【问题讨论】:

    标签: java android special-characters saxparser


    【解决方案1】:

    这是来自 Xerces 的常见问题解答。

    为什么 SAX 解析器会丢失一些 字符数据或为什么是数据 分成几块?如果你 阅读 SAX 文档,您将 发现 SAX 可以提供连续的 文本作为对字符的多次调用, 由于与解析器有关的原因 效率和输入缓冲。这是 程序员的责任 适当处理,例如经过 累积文本直到下一个 非字符事件。

    您的代码很好地改编自许多 XML Parsing 教程之一(例如 this 此处的一个)

    请注意这里的这部分...

        public void characters(char[] ch, int start, int length)
                throws SAXException
        {
                  if(in_ThisTag){
                         myobj.setName(new String(ch,start,length))
                  }
        }
    

    我敢打赌,此时您正在检查布尔值以标记您所在的标签,然后在您创建的某种class 中设置一个值?或类似的东西......

    但问题是,SAX 解析器(它是缓冲的)不一定会一次性获取标签之间的所有字符....假设<tag> Lorem Ipsum...really long sentence...</tag> 所以你的 SAX 解析器调用 characters 函数是块....

    所以这里的诀窍是继续将值附加到一个字符串变量,并在标签结束时将其实际添加到您的结构中...(即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 进行附加会更好,因为这样会更有效率....

    希望这是有道理的!如果没有检查thishere

    【讨论】:

    • 我希望得到这样一个简单的答案。这修复了它并帮助我更多地了解 SAX。非常感谢!
    猜你喜欢
    • 2021-12-10
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多