Почему SaxParser случайно выходит из строя? - PullRequest
0 голосов
/ 24 декабря 2010

Я использую парсер SAX в своем приложении для Android, чтобы читать несколько каналов одновременно. Сценарий выполняется следующим образом.

                     // 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'). Здесь

http://imm.io/media/2I/2IBQ.jpg Это худший вариант. Как вы можете видеть, заголовок отображает только апостроф, в то время как предполагается, что это «блаблабла». Кроме того, текст заканчивается в середине строки, без каких-либо специальных символов в кавычке. Лента здесь

Во всех случаях я не могу контролировать подачу. Я думаю, что сценарий задыхается от специальных символов. Как я могу убедиться, что SAX правильно выбирает все строки?

Если кто-нибудь знает ответ на этот вопрос, вы действительно поможете мне МНОГО: D

Заранее спасибо.

1 Ответ

5 голосов
/ 24 декабря 2010

Это из FAQ по Xerces.

Почему парсер SAX теряет некоторые символьные данные или почему данные разбиваются на несколько частей?Если вы прочтете документацию SAX, то обнаружите, что SAX может доставлять непрерывный текст в виде нескольких вызовов символов по причинам, связанным с эффективностью синтаксического анализатора и буферизацией ввода.Программист несет ответственность за то, чтобы справиться с этим надлежащим образом, например, путем накопления текста до следующего не символьного события.

Ваш код очень хорошо адаптирован из одного из многих учебных пособий по синтаксическому анализу XML (например, этот один здесь) Теперь учебник хорош и все, но они не упоминают что-то очень важное ...

Обратите внимание на эту часть здесь ...

    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 функция - это чанки ....

Итак, хитрость заключается в том, чтобы продолжать добавлять значения в строковую переменную и фактически 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 для добавления, так как это будетбыть более эффективным ....

Надеюсь, это имеет смысл!Если он не проверял , это и здесь

...