XmlPullParser - 解析嵌套标记

iqu*_*rio 8 java arrays android xmlpullparser android-xmlpullparser

我有这个XML:

<menu>
    <day name="monday">
        <meal name="BREAKFAST">
            <counter name="Bread">
               <dish>
                   <name>Plain Bagel</name>
               </dish>
            <counter/>
        <meal/>
    <day/>
    <day name="tuesday">
        <meal name="LUNCH">
            <counter name="Other">
               <dish>
                   <name>Cheese Bagel</name>
               </dish>
            <counter/>
        <meal/>
    <day/>
<menu/>
Run Code Online (Sandbox Code Playgroud)

如果day标签的属性等于星期一,那么现在我正在尝试这样做.然后饭标属性等于BREAKFAST,然后我想得到计数器的属性."面包".

我已经设置了xml pull解析器,但我正在努力获得这个值.这是我尝试过的,我现在看到它不能也不会起作用......所以任何有关如何设置它的帮助都会很棒.

while (eventType != XmlResourceParser.END_DOCUMENT) {
        String tagName = xmlData.getName();

        switch (eventType) {
            case XmlResourceParser.START_TAG:
                if (tagName.equalsIgnoreCase("day")) {
                    if (xmlData.getAttributeValue(null, "name").equalsIgnoreCase(day)) {
                        if (tagName.equalsIgnoreCase("meal")) {
                            mealArray.add(xmlData.getAttributeValue(null, "name"));
                            Log.i(TAG, xmlData.getAttributeValue(null, "name"));
                        }
                    }


                }
                break;
            case XmlResourceParser.TEXT:
                break;
            case XmlPullParser.END_TAG:

                break;
        }
        eventType = xmlData.next();
    }
Run Code Online (Sandbox Code Playgroud)

Mys*_*icϡ 6

您需要添加用于解析嵌套标记的逻辑:

一个非常简单的例子可以帮助您继续前进:

我解析了这个字符串:

<menu><day name=\"monday\"><meal name=\"BREAKFAST\"><meal/><day/></menu>

码:

try {
    factory = XmlPullParserFactory.newInstance();
    factory.setNamespaceAware(true);
    XmlPullParser xpp = factory.newPullParser();

    xpp.setInput(new StringReader("<menu><day name=\"monday\"><meal name=\"BREAKFAST\"><meal/><day/></menu>"));
    int eventType = xpp.getEventType();
    while (eventType != XmlResourceParser.END_DOCUMENT) {
        String tagName = xpp.getName();

        switch (eventType) {
            case XmlResourceParser.START_TAG:
                if (tagName.equalsIgnoreCase("day")) {
                    if (xpp.getAttributeValue(null, "name").equalsIgnoreCase("MONDAY")) {
                        int eventType2 = xpp.next();
                        while (eventType2 != XmlResourceParser.END_DOCUMENT) {
                            String tagName2 = xpp.getName();
                            switch (eventType2) {
                            case XmlResourceParser.START_TAG:
                                if (tagName2.equalsIgnoreCase("meal")) {
                                    Log.i("tag", "meal: " + xpp.getAttributeValue(null, "name"));
                                }
                                break;
                            case XmlResourceParser.TEXT:
                                break;
                            case XmlPullParser.END_TAG:
                                break;
                            }
                            eventType2 = xpp.next();
                        }
                    }
                }
            break;
            case XmlResourceParser.TEXT:
            break;
            case XmlPullParser.END_TAG:
            break;
        }
        eventType = xpp.next();
    }

} catch (XmlPullParserException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

你看到了区别,对吗?

我基本上就是在获得我想要的那一天之后添加了这个.(就我而言,硬编码字符串"Monday".)

int eventType2 = xpp.next();
Run Code Online (Sandbox Code Playgroud)

并在此基础上eventType2,检索出tagName2哪些"用餐"

一个更好的例子来帮助您以一种很好的方式编写逻辑.

希望这可以帮助.


Amr*_*dri 2

       while (eventType != XmlResourceParser.END_DOCUMENT) {
        String tagName = xmlData.getName();

        switch (eventType) {
           case XmlResourceParser.START_TAG:
                if (tagName.equalsIgnoreCase("day")) {
                    day = xmlData.getAttributeValue(null, "name");
                }
                if (tagName.equalsIgnoreCase("meal")) {
                    meal = xmlData.getAttributeValue(null, "name");
                }
                if (tagName.equalsIgnoreCase("counter")) {
                    counter = xmlData.getAttributeValue(null, "name");
                }

                break;
            case XmlResourceParser.TEXT:
                data += xmlData.getText();
                if (tagName.equalsIgnoreCase("name")) {
                    name= xmlData.getText();
                }
                break;
            case XmlPullParser.END_TAG:
                if (tagName.equals("day")) {
                    recordsFound++;

                }
                break;
        }
        publishProgress(new String[]{day,meal,counter});
        eventType = xmlData.next();

    }
Run Code Online (Sandbox Code Playgroud)

首先,您的 switch-case 语句中缺少中断。其次,属性始终从 START_TAG 情况进行解析。标签内的文本在 TEXT 情况下进行解析,END_TAG 对于基于其嵌套创建对象或数组列表非常有用。

onProgressUpdate 必须如下所示:

@Override
protected void onProgressUpdate(String... values) {
   super.onProgressUpdate(values);
   if (values.length == 0) {
        Log.i(TAG, "no data");
    }
    else {
       String day = values[0];
       String meal= values[1];
       String counter= values[2];
    }

}
Run Code Online (Sandbox Code Playgroud)