2013-07-29 4 views
0

Мне нужна ваша помощь для синтаксического анализа XML-объявлений.Исключение при анализе XML с помощью XMLPullParser

Давайте посмотрим ниже XML:

<?xml version="1.0" encoding="UTF-8"?> 
<FAVORIS> 
    <LOGGED>1</LOGGED> 
    <NOTICES NUM_PAGE="2"> 
     <NOTICE> 
     <DEPARTMENT>33</DEPARTMENT> 
     <SOURCE>EMP</SOURCE> 
     <OBJET><![CDATA[Fourniture d'une solution régionale]]></OBJET> 
     <ID_PROCEDURE>7543</ID_PROCEDURE> 
     <ORGANISME><![CDATA[Gcs]]></ORGANISME> 
     <TYPE_AVIS>ZZ</TYPE_AVIS> 
     <TYPE_PROCEDURE>W3</TYPE_PROCEDURE> 
     <CATEGORIE>Service</CATEGORIE> 
     <DATE_OFFRE>16/09/2013 12:00</DATE_OFFRE> 
     <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE> 
     </NOTICE> 
     <NOTICE> 
     <DEPARTMENT>33</DEPARTMENT> 
     <SOURCE>EMP</SOURCE> 
     <OBJET><![CDATA[Refonte du portail]]></OBJET> 
     <ID_PROCEDURE>4323</ID_PROCEDURE> 
     <ORGANISME><![CDATA[Mairie de W]]></ORGANISME> 
     <TYPE_AVIS>Z</TYPE_AVIS> 
     <TYPE_PROCEDURE>W1</TYPE_PROCEDURE> 
     <CATEGORIE>Service</CATEGORIE> 
     <DATE_OFFRE>03/09/2013 12:00</DATE_OFFRE> 
     <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE> 
     </NOTICE> 
.... 
    </NOTICES> 
</FAVORIS> 

Чтобы разобрать этот XML я следовал учебник о XML Разбор в http://developer.android.com/training/basics/network-ops/xml.html

Когда я разобрать этот XML У меня есть ошибка, как это:

expected: START_TAG {null}NOTICES (position:START_TAG <FAVORIS>@2:10 in [email protected]) 

Это связано с требованием, но как я могу решить эту проблему?

Больше о моем коде:

public class AOThumbnail_ParserXML { 

private static final String ns = null; 

public ArrayList<AOThumbnail> parse(String in) throws XmlPullParserException, IOException { 

    Decoder decoder = new Decoder(); 
    String decoded_in = decoder.decode(in); 

    XmlPullParser parser = Xml.newPullParser(); 
    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); 
    parser.setInput(new ByteArrayInputStream(decoded_in.getBytes()), null); 
    parser.nextTag(); 
    return readFeed(parser); 
} 

private ArrayList<AOThumbnail> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException { 
    ArrayList<AOThumbnail> entries = new ArrayList<AOThumbnail>(); 

    parser.require(XmlPullParser.START_TAG, ns, "NOTICES"); 

    while (parser.next() != XmlPullParser.END_TAG) { 
     if (parser.getEventType() != XmlPullParser.START_TAG) { 
      continue; 
     } 
     String name = parser.getName(); 

     // Starts by looking for the entry tag 
     if (name.equals("NOTICE")) { 
      entries.add(readEntry(parser)); 
     } else { 
      skip(parser); 
     } 
    } 
    return entries; 
} 

private AOThumbnail readEntry(XmlPullParser parser) throws XmlPullParserException, IOException { 

    parser.require(XmlPullParser.START_TAG, ns, "NOTICE"); 

    String organisme = null; 
    String objet = null; 
    String date_candidature = null; 
    String date_offre = null; 
    String departement = null; 
    String source = null; 
    String idProcedure = null; 
    String decalageHoraire = null; 

    while (parser.next() != XmlPullParser.END_TAG) { 
     if (parser.getEventType() != XmlPullParser.START_TAG) { 
      continue; 
     } 
     String name = parser.getName(); 
     if (name.equals("ORGANISME")) { 
      organisme = read(parser, "ORGANISME"); 
     } else if (name.equals("OBJET")) { 
      objet = read(parser, "OBJET"); 
     } else if (name.equals("DATE_CAND")) { 
      date_candidature = read(parser, "DATE_CAND"); 
     } else if (name.equals("DATE_OFFRE")) { 
      date_offre = read(parser, "DATE_OFFRE"); 
     } else if (name.equals("DEPARTMENT")) { 
      departement = read(parser, "DEPARTMENT"); 
     } else if (name.equals("SOURCE")) { 
      source = read(parser, "SOURCE"); 
     } else if (name.equals("ID_PROCEDURE")) { 
      idProcedure = read(parser, "ID_PROCEDURE"); 
     } else if (name.equals("DECALAGE_HORAIRE")) { 
      decalageHoraire = read(parser, "DECALAGE_HORAIRE"); 
     } else { 
      skip(parser); 
     } 
    } 

    String date = ""; 
    try { 
     if (date_candidature.length() > 0) 
      date = date_candidature; 
     else if (date_offre.length() > 0) 
      date = date_offre; 
     else 
      date = "Se référer à l'annonce"; 
    } catch (Exception ex) { 
     Logger.logit(ex); 
    } 

    return new AOThumbnail(organisme, objet, date, departement, idProcedure, source, Boolean.parseBoolean(decalageHoraire)); 
} 

private String read(XmlPullParser parser, String balise) throws IOException, XmlPullParserException { 
    parser.require(XmlPullParser.START_TAG, ns, balise); 
    String content = readText(parser); 
    parser.require(XmlPullParser.END_TAG, ns, balise); 
    return content; 
} 

private String readText(XmlPullParser parser) throws IOException, XmlPullParserException { 
    String result = ""; 
    if (parser.next() == XmlPullParser.TEXT) { 
     result = parser.getText(); 
     parser.nextTag(); 
    } 
    return result; 
} 

private void skip(XmlPullParser parser) throws XmlPullParserException, IOException { 
    if (parser.getEventType() != XmlPullParser.START_TAG) { 
     throw new IllegalStateException(); 
    } 
    int depth = 1; 
    while (depth != 0) { 
     switch (parser.next()) { 
      case XmlPullParser.END_TAG: 
       depth--; 
       break; 
      case XmlPullParser.START_TAG: 
       depth++; 
       break; 
     } 
    } 
} 
} 

Если я разобрать XML, как это (смотри ниже), он работает, но не с выше XML!

<NOTICES NUM_PAGE="2"> 
     <NOTICE> 
     <DEPARTMENT>33</DEPARTMENT> 
     <SOURCE>EMP</SOURCE> 
     <OBJET><![CDATA[Fourniture d'une solution régionale]]></OBJET> 
     <ID_PROCEDURE>7543</ID_PROCEDURE> 
     <ORGANISME><![CDATA[Gcs]]></ORGANISME> 
     <TYPE_AVIS>ZZ</TYPE_AVIS> 
     <TYPE_PROCEDURE>W3</TYPE_PROCEDURE> 
     <CATEGORIE>Service</CATEGORIE> 
     <DATE_OFFRE>16/09/2013 12:00</DATE_OFFRE> 
     <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE> 
     </NOTICE> 
     <NOTICE> 
     <DEPARTMENT>33</DEPARTMENT> 
     <SOURCE>EMP</SOURCE> 
     <OBJET><![CDATA[Refonte du portail]]></OBJET> 
     <ID_PROCEDURE>4323</ID_PROCEDURE> 
     <ORGANISME><![CDATA[Mairie de W]]></ORGANISME> 
     <TYPE_AVIS>Z</TYPE_AVIS> 
     <TYPE_PROCEDURE>W1</TYPE_PROCEDURE> 
     <CATEGORIE>Service</CATEGORIE> 
     <DATE_OFFRE>03/09/2013 12:00</DATE_OFFRE> 
     <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE> 
     </NOTICE> 
.... 
    </NOTICES> 

Я надеюсь, что вы можете мне помочь, Спасибо большое!

ответ

1

В методе readFeed() вы указываете вашему парсеру, что текущее событие должно быть START_TAG с именем «УВЕДОМЛЕНИЯ», в другом случае метод будет генерировать исключение, которое вы отправили. Вот почему работает второй .xml-файл, но не первый (первым событием этого файла будет START_TAG с именем «FAVORIS»).

Таким образом, вы должны использовать другой способ посмотреть на блок УВЕДОМЛЕНИЯ, вы можете использовать что-то вроде этого (есть и другие способы сделать это):

while (parser.next() != XmlPullParser.START_TAG && !(parser.getName().equals("NOTICES"))); 

Так что, когда это время замкнёте, ваш парсер будет в начале блока NOTICES.

PS: Я не тестировал код, поэтому он может не работать, но решение должно быть аналогичным.

+0

Хорошо, я попробую это, ТНХ;) – thedjnivek

+0

Я решил эту проблему, используя ваши советы;) Спасибо вам много – thedjnivek

+0

К сожалению, этот строка неверна, вы, возможно, должны использовать OR вместо AND в состоянии цикла while. EDIT: Я просто вижу ваш ответ, пожалуйста! – javi9375

0

Проблема решена с использованием «FAVORIS»!

private ArrayList<AOThumbnail> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException { 
     ArrayList<AOThumbnail> entries = new ArrayList<AOThumbnail>(); 

     //Go to FAVORIS' level 
     parser.require(XmlPullParser.START_TAG, ns, "FAVORIS"); 

     while (parser.next() != XmlPullParser.END_TAG) { 
      if (parser.getEventType() != XmlPullParser.START_TAG) { 
       continue; 
      } 

      String name = parser.getName(); 
      if(parser.getName().equals("NOTICES")) { 
       //Go to NOTICES' level 
       parser.require(XmlPullParser.START_TAG, ns, "NOTICES"); 
       //Parse on Notices' level 
       return readFeed(parser); 
      } 

      // Starts by looking for the entry tag 
      if (name.equals("NOTICE")) { 
       Logger.logit("Dans notice !!!!!!"); 
       entries.add(readEntry(parser)); 
      } else { 
       skip(parser); 
      } 
     } 
     return entries; 
    } 

Благодаря @ javi9375 за его советы;)

Смежные вопросы