【问题标题】:Difficulty with XML nested tags with XMLPullParser in Android在 Android 中使用 XMLPullParser 处理 XML 嵌套标签的困难
【发布时间】:2015-10-26 08:29:28
【问题描述】:

我正在尝试获取名称并读取 type="alpha"。

我是初学者,英语不是我的第一语言,请原谅我。我已经阅读了有关 DOM、SAX、Simple、其他 StackOverflow 帖子、其他示例的信息,但我不明白,并且想在这种情况下了解 XMLPullParser。

以下示例 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>

我读过这个:http://developer.android.com/training/basics/network-ops/xml.html 示例代码适用于上面没有 标记的示例 XML,以获取名称和记录日期。

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

我尝试使用 标签(但不起作用)是:

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

如果我能解决这个问题,我将能够读取名称和记录日期,但我想要得到的是 namereading type="alpha",我不知道如何获得嵌套阅读type="alpha"。

非常感谢。

【问题讨论】:

    标签: java android xml nested xmlpullparser


    【解决方案1】:

    你可以试试这个功能

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

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

    【讨论】:

    • parser.require(XmlPullParser.START_TAG, ns, "title");字符串标题 = readText(解析器); parser.require(XmlPullParser.END_TAG, ns, "title");为什么在这种情况下使用标题?
    • @TryingToLearn 抱歉错了键,请参阅我编辑的答案。
    • readFeed 没有像我发布的代码一样到达 :( 我不知道如何访问嵌套标签
    【解决方案2】:

    你一直在循环,什么时候

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

    您可以使用getText() 检索标签名称的值:

    你会打电话的

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

    什么时候

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

    你想读取你的属性,例如。 &lt;reading type="alpha" value="300"/&gt;

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

    编辑:

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

    【讨论】:

    • 谢谢,它帮助我了解了如何检索这些值。但是循环应该如何工作才能达到嵌套标签才能达到条件呢?第一个嵌套部分将在 内,第二个将在 () 内。有没有办法循环遍历整个 XML 文档,只到达我想要的标签?
    • 知道如何访问嵌套标签吗?我已经在另一篇文章和其他几个地方尝试过,但仍然无法这样做...:/
    • 如果我在你身边,我会开始删除 continue; 并在每次迭代时记录标签的名称。我可以为您编写解析器,但如果您能解决这个问题,那就太好了。
    • 删除后继续;它崩溃了。您能否详细说明如何做到这一点?或者提供一个关于如何处理嵌套标签的示例,以便我更好地理解并弄清楚。 logcat 还显示“com.example.android.networkusage E/eglCodecCommon: glUtilsParamSize: unknow param 0x00000b44 com.example.android.networkusage E/eglCodecCommon: glUtilsParamSize: unknow param 0x00000bd0 com.example.android.networkusage E/eglCodecCommon: ** ** ERROR unknown type 0x73000d (glSizeof,72)" 多次,知道这意味着什么吗?
    【解决方案3】:

    我也遇到了同样的错误,我的解决方案很简单,只需检查正确

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

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

    如果 name 和 first_tag_right 不一样,那么你会得到这个异常。

    这是任何用户的通用答案,以防万一他收到此错误。

    【讨论】:

      【解决方案4】:

      接受的答案仅因为您只有嵌套标签而有效,但是如果您有未嵌套的标签而您只想要嵌套的标签怎么办?

      您可以这样做的一种方法是:

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

      基本思想是每个父标签一个while循环,每个子标签对应一个ifs。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多