简体   繁体   中英

Exception during parsing XML with XMLPullParser

I need your help to parse XML announces.

Let's see the XML below :

<?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>

To parse this XML I followed the tutorial about XML Parsing in http://developer.android.com/training/basics/network-ops/xml.html

When I parse this XML I have an error like this :

expected: START_TAG {null}NOTICES (position:START_TAG <FAVORIS>@2:10 in java.io.InputStreamReader@40e69360) 

It's due to the require but how can I resolve this issue ?

More about my code :

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

If I parse an XML like this (see below), it works, but not with the XML above !

<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>

I hope you can help me, Thanks a lot !

In readFeed() method, you are telling to your Parser that the current event should be an START_TAG with name "NOTICES", in other case the method will throw an Exception, which is the one you posted. Thats why the second .xml file works, but not the first (the first event of this file will be an START_TAG with name "FAVORIS").

So you should use another way to look up for the NOTICES block, you can use something like this (there are other ways to do it):

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

So when this while loop ends, your parser will be at the start of the NOTICES block.

PS: I didn't test the code, so it might not work, but the solution should be similar.

Issue resolved using require "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;
    }

Thanks to @javi9375 for his tips ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM