Парсер Android SAX не получает полный текст между тегами

Я создал свой собственный DefaultHandler для анализа rss-каналов, и для большинства каналов он работает нормально, однако для ESPN он отрезает часть URL-адреса статьи из-за того, как ESPN форматирует его URL-адреса. Пример полного URL-адреса статьи из 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-адреса от escape-кода амперсанда и после него. Как я могу заставить синтаксический анализатор SAX не обрезать мою строку в этом escape-коде? Для исх. вот мой метод символов ..

 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());
  }
 }

Роб В.


person brockoli    schedule 14.05.2010    source источник


Ответы (3)


Как вы можете видеть, он отрезает все от URL-адреса от escape-кода амперсанда и после него.

Из документации метода 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(), я ничего не пропущу.

person CommonsWare    schedule 14.05.2010
comment
Хорошо, я действительно не тратил время, чтобы полностью понять, как работает парсер. Прочитав ваш ответ, я вернулся и продолжил исследование, чтобы лучше понять. Конечно, ваше предложение было проблемой, с тех пор я обновил свой код, чтобы правильно обрабатывать данные char. ТЮ - person brockoli; 17.05.2010
comment
@CommonsWare: не хватает некоторых символов? Я сталкиваюсь с этим в моем случае. - person Ankit; 19.07.2013
comment
У меня есть ‹image›image1:title‹/image› в моем xml, и иногда я получаю полное значение, а иногда я получаю только itle или Title. Я пытался напечатать значения, но он никогда не печатал image1: для частичных значений. - person Ankit; 19.07.2013
comment
@Ankit: Пожалуйста, откройте новый вопрос StackOverflow, покажите свой ввод, код синтаксического анализа и результаты. - person CommonsWare; 19.07.2013
comment
С вашим решением моя проблема была решена, даже тогда я опубликую ее как вопрос для будущих читателей. - person Ankit; 19.07.2013
comment
Спасибо, ваши ответы всегда короткие, описательные, содержат реальную аргументацию ответа и, конечно же, на месте! - person Nemanja; 28.03.2014
comment
@CommonsWare Я использую синтаксический анализатор SAX, который содержит следующий текст внутри в виде тега, как показано ниже: ‹book id=1›Привет, эта книга выбрана для награды ‹ref id=23›IIFA‹/ref›.‹/book› Когда я анализирую , и получить текст из книги тегов, я получаю следующее содержимое: «Привет, эта книга выбрана для награды IIFA». Но я хочу этот текст «Привет, эта книга выбрана для награды ‹ref id=23›IIFA‹/ref›». Почему в тексте отсутствует ‹ref›, как его получить при разборе?? Пожалуйста, дай мне знать - person KK_07k11A0585; 10.06.2015
comment
@ KK_07k11A0585: Это отдельный элемент XML. Вы уже получаете его при разборе в своих методах startElement() и endElement(). - person CommonsWare; 10.06.2015
comment
@CommonsWare Спасибо, я проанализировал это, добавив имя этого тега в startElement и endElement(). Но есть ли другой способ получить полный текст внутри тега как обычный текст?? Как в приведенном выше примере получить этот текст "Привет, эта книга выбрана для ‹ref id=23›IIFA‹/ref›" из тега книга ?? - person KK_07k11A0585; 10.06.2015
comment
@ KK_07k11A0585: Вам придется собрать это самостоятельно, используя конкатенацию строк. Это не имеет ничего общего с Android конкретно. Если у вас есть дополнительные вопросы в этой области, задайте новый вопрос Stack Overflow с тегом java, где вы объясните свой вклад и то, чего вы пытаетесь достичь. - person CommonsWare; 10.06.2015

@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;
    }
}

Итак, я понял, что приведенный выше код является решением.

person anonymous123    schedule 29.05.2012

Я столкнулся с этой проблемой на днях, оказывается, причина этого в том, что метод CHaracters вызывается несколько раз, если какой-либо из этих символов содержится в значении:

"   &quot;
'   &apos;
<   &lt;
>   &gt;
&   &amp;

Также будьте осторожны с разрывами строк / новыми строками внутри значения!!! Если xml переносится без вашего контроля, метод символов также будет вызываться для каждой строки в выражении, плюс он вернет разрыв строки! (которые вам вручную нужно вырезать по очереди).

Вот пример обработчика, который решает все эти проблемы:

 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 = "";
     }
   }
}

Надеюсь, это поможет.

person fl0w    schedule 24.10.2019