简体   繁体   English

Android中使用XMLPullParser遇到XML嵌套标签的困难

[英]Difficulty with XML nested tags with XMLPullParser in Android

I'm trying to get the name and reading type="alpha". 我正在尝试获取名称并读取type =“ alpha”。

I'm a beginner and English is not my first language, please pardon me. 我是初学者,英语不是我的母语,请原谅我。 I've read about DOM, SAX, Simple, other StackOverflow posts, other samples but I don't understand and will like to learn about XMLPullParser in this case. 我已经阅读了有关DOM,SAX,Simple,其他StackOverflow帖子,其他示例的信息,但我不理解,并且希望在这种情况下了解XMLPullParser。

Sample XML below: 下面的示例XML:

<feed>
    <title>Title</title>
    <item>

    <entry>
        <name>Name1</name>
        <record date="20001231">
            <reading type="alpha" value="100"/>
            <reading type="beta" value="200"/>
        </record>
    </entry>

    <entry>
        <name>Name2</name>
        <record date="20001231">
            <reading type="alpha" value="300"/>
            <reading type="beta" value="400"/>
        </record>
    </entry>

    </item>
</feed>

I've read this: http://developer.android.com/training/basics/network-ops/xml.html and the sample code works for the sample XML above without the <item> tags to get the name and record date. 我读过这篇文章: http : //developer.android.com/training/basics/network-ops/xml.html该示例代码适用于上面的示例XML,而没有<item>标记来获取名称和记录日期。

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

    parser.require(XmlPullParser.START_TAG, ns, "feed");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }

        if (parser.getName().equals("entry")) {
            entries.add(readEntry(parser));
        } else {
            skip(parser);
        }
    }
    return entries;
}

What I've tried with the presence of <item> tags (but does not work) is: 我尝试使用<item>标记(但不起作用)的原因是:

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

    parser.require(XmlPullParser.START_TAG, ns, "feed");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }

        if (parser.getName().equals("item")) {

            parser.next();

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

                if (parser.getName().equals("entry")) {
                    entries.add(readEntry(parser));
                } else {
                    skip(parser);
                }
            }

        } else {
            skip(parser);
        }
    }
    return entries;
}

If I can solve that, I will be able to read the name and record date, but what I'm trying to get is the name and reading type="alpha" , which I don't know how to get the nested reading type="alpha". 如果可以解决,我将能够读取名称和记录日期,但是我想要获取的是名称读取type =“ alpha” ,我不知道如何获取嵌套的读取类型= “阿尔法”。

Many thanks in advance. 提前谢谢了。

you keep looping and when 你不断循环,何时

parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("name")

you can retrive the value of the tag name with getText() : 您可以使用getText()检索标记名称的值:

you will call then 你会打电话给

parser.next();
String name = parser.getText();

when 什么时候

parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("reading")

you want to read your attributes, Eg. 您想读取属性,例如。 <reading type="alpha" value="300"/>

String type = parser.getAttributeValue(null, "type");
String value = parser.getAttributeValue(null, "value");

Edit: 编辑:

private void readFeed(XmlPullParser parser) throws IOException, XmlPullParserException {
    int eventType = parser.getEventType();
    while (eventType != XmlPullParser.END_DOCUMENT) {
        if (eventType == XmlPullParser.START_TAG) {
            String name = parser.getName();
            if (name == null) {
                continue;
            }
            if (name.equals("reading")) {
                Log.e(getClass().getSimpleName()," " + parser.getAttributeValue(null, "type"));
                Log.e(getClass().getSimpleName(), " " + parser.getAttributeValue(null, "value"));
            }
        }
        eventType = parser.next();
    }
}

You can try this function 你可以试试这个功能

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

    parser.require(XmlPullParser.START_TAG, ns, "feed");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        // Starts by looking for the item tag
        if (name.equals("item")) {
            parser.require(XmlPullParser.START_TAG, ns, "item");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                // and then get the entry here
                if (name.equals("entry")) {
                    entries.add(readEntry(parser));
                }
            }
        } else {
            skip(parser);
        }
    }  
    return entries;
}

Where readEntry Function is : 其中readEntry函数为:

private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "entry");
    String name = null;
    Record record = null;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("name")) {
            parser.require(XmlPullParser.START_TAG, ns, "name");
            String title = readText(parser);
            parser.require(XmlPullParser.END_TAG, ns, "name");
        } else if (name.equals("record")) {
            // Try to figure it out by yourself for practice ;)
        } else {
            skip(parser);
        }
    }
    return new Entry(title, summary, link);
}

I also got same error and my solution was simple just check right 我也遇到同样的错误,我的解决方案很简单,只需检查正确

String name=parser.getName(); 字符串名称= parser.getName();

parser.require(XmlPullParser.START_TAG, nameSpace, first_tag_key); parser.require(XmlPullParser.START_TAG,nameSpace,first_tag_key);

if name and first_tag_right is not same then you will get this exception. 如果name和first_tag_right不相同,则将出现此异常。

THIS IS A GENERIC ANSWER FOR ANY USER IF IN CASE HE GET THIS ERROR. 如果任何用户遇到此错误,这是一个通用的答案。

The accepted answer works only because you only have nested tags but what if you had unnested tags and you only wanted the nested ones ? 可接受的答案仅适用于您,因为您仅具有嵌套标签,但是如果您具有未嵌套的标签,而您只想要嵌套的标签,该怎么办?

One way you can do this is : 一种方法是:

    while (eventType != XmlPullParser.END_DOCUMENT ) {

        // check for the parent tag
        if (eventType == XmlPullParser.START_TAG && "item".equals(xpp.getName())) {
            eventType = xpp.next();

            // loop the parent tag elements until we reach the end of the parent tag
            while (eventType != XmlPullParser.END_TAG && !"item".equals(xpp.getName())) {

                // check the children tags
                if ("title".equals(xpp.getName()))
                    // do something
                else if ("link".equals(xpp.getName()))
                    // do something
                xpp.next();
            }
        }
        eventType = xpp.next();
    }

The basic idea is one while loop for each parent tag and corresponding ifs for each children. 基本思想是为每个父标记提供一个while循环,并为每个子标记提供相应的ifs。

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

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