简体   繁体   English

使用XMLPullParser解析XML时发生异常

[英]Exception during parsing XML with XMLPullParser

I need your help to parse XML announces. 我需要您的帮助来解析XML声明。

Let's see the XML below : 让我们看下面的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>

To parse this XML I followed the tutorial about XML Parsing in http://developer.android.com/training/basics/network-ops/xml.html 为了解析该XML,我遵循了http://developer.android.com/training/basics/network-ops/xml.html中有关XML解析的教程。

When I parse this XML I have an error like this : 当我解析此XML时,出现了如下错误:

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 ! 如果我解析这样的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>

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. 在readFeed()方法中,您要告诉解析器当前事件应为名称为“ NOTICES”的START_TAG,否则,该方法将引发Exception,即您发布的异常。 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"). 这就是为什么第二个.xml文件起作用,而不是第一个起作用的原因(该文件的第一个事件将是名称为“ FAVORIS”的START_TAG)。

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): 因此,您应该使用另一种方法来查找NOTICES块,可以使用类似的方法(有其他方法可以这样做):

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. 因此,当while循环结束时,解析器将位于NOTICES块的开始处。

PS: I didn't test the code, so it might not work, but the solution should be similar. PS:我没有测试代码,因此它可能无法正常工作,但是解决方案应该相似。

Issue resolved using require "FAVORIS" ! 使用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 ;) 感谢@ javi9375的技巧;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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