2014-02-14 55 views
1

我一直在阅读上XmlPullParser一些教程在Android中如何解析XML数据。 更具体,我使用的XML从https://gdata.youtube.com/feeds/api/standardfeeds/top_rated如何用一些标签中的冒号解析XML?

在这里,我在此输入的条目简化部分(我希望在不改变结构):

<entry> 
<id>http://gdata.youtube.com/feeds/api/videos/abc45678qwe</id> 
[...] 
<title type='text'>THE TITLE</title> 
[...] 
<link rel='alternate' type='text/html' href='https://www.youtube.com/watch?v=abc45678qwe&amp;feature=youtube_gdata'/> 
[...] 
<media:group> 
[...] 
<media:title type='plain'>THE TITLE</media:title> 
<yt:duration seconds='300'/> 
[...] 
<yt:videoid>abc45678qwe</yt:videoid> 
</media:group> 
<gd:rating average='1' max='5' min='1' numRaters='1' rel='http://schemas.google.com/g/2005#overall'/> 
<yt:statistics favoriteCount='0' viewCount='11111111'/> 
<yt:rating numDislikes='111' numLikes='111'/> 
</entry> 

我顺利地拿到冠军并与链接:

private String[] readEntry(XmlPullParser parser) 
     throws XmlPullParserException, IOException { 
    parser.require(XmlPullParser.START_TAG, null, "entry"); 
    String title = null; 
    String link = null; 

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

     String name = parser.getName(); 
     String rel = parser.getAttributeValue(null, "rel"); 

     if (name.equalsIgnoreCase("title")) { 
      title = readTitle(parser); 
     } else if (name.equalsIgnoreCase("link") 
       && rel.equals("alternate")) { 
      link = readLink(parser); 
     } else { 
      skip(parser); 
     } 
    } 
    return new String[] { title, link }; 
} 

private String readLink(XmlPullParser parser) 
     throws XmlPullParserException, IOException { 
    String link = ""; 
    parser.require(XmlPullParser.START_TAG, null, "link"); 

    link = parser.getAttributeValue(null, "href"); 
    parser.nextTag(); 

    parser.require(XmlPullParser.END_TAG, null, "link"); 

    return link; 
} 

private String readTitle(XmlPullParser parser) 
     throws XmlPullParserException, IOException { 
    parser.require(XmlPullParser.START_TAG, null, "title"); 
    String title = readText(parser); 
    parser.require(XmlPullParser.END_TAG, null, "title"); 
    return title; 
} 

但无论我怎么努力,我无法从<yt:duration seconds='300'/>获得持续时间以秒计。

显然不能用类似上述方法访问的东西,如处理namespaces应该是必需的,但我不知道。由于我有点失落,任何建议都非常感谢。谢谢。

====

编辑:我添加了我所要输入标签yt:duration

skip(parser);之前添加其他检查。即:

} else if (name.equalsIgnoreCase("yt:")) { 
    Utils.logger("i", "entering yt:", TAG); 
    readDuration(parser) 
} 

和我一起"yt",或"yt:duration没有结果改变"yt:"

private String readDuration(XmlPullParser parser) 
     throws XmlPullParserException, IOException { 
    parser.require(XmlPullParser.START_TAG, "yt", "duration"); 

    String seconds = parser.getAttributeValue(null, "seconds"); 
    parser.nextTag(); 

    parser.require(XmlPullParser.END_TAG, "yt", "duration"); 

    Utils.logger("i", "duration: " + seconds + " seconds", TAG); 
    return seconds; 
} 

加成作出了“关于要求:

String namespace = parser.getNamespace(); 

,改变name.equalsIgnoreCase...namespace.equalsIgnoreCase...我不明白的日志条目,所以我甚至不有办法试试这个 还”。我不确定它是否有用。

+0

你是否可以在yt:duration标签上更新你的帖子?如果xmlpullparser确实会在命名空间前缀标记 – PopoFibo

+0

上做一些不好的事情,会很有趣。给我2分钟。 – dentex

+0

'contains'呢?这不是直接与'equalsIgnoreCase'比较'尝试'name.contains(“duration”)'? – PopoFibo

回答

0

XmlPullParser似乎已经是名称空间感知的能力,不同的是它必须被明确地设定。每XmlPullParseFactory#setNamespaceAware文档:

指定由该工厂生产的解析器将提供对XML命名空间 支持。默认情况下,这个值设置到 假。

你可能想尝试该选项。

另外,正如在评论中提到的,我试图用零遍历DOM来解决问题,下面是打印所有持续时间值的源代码(只是为了让您知道,这是作为Java程序,而不是内ADT):

public static void main(String[] args) throws ParserConfigurationException, 
      SAXException, IOException { 
     InputStream path = new URL(
       "https://gdata.youtube.com/feeds/api/standardfeeds/top_rated") 
       .openStream(); 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     Document document = builder.parse(path); 
     traverse(document.getDocumentElement()); 

    } 

    public static void traverse(Node node) { 
     NodeList list = node.getChildNodes(); 
     for (int i = 0; i < list.getLength(); i++) { 
      Node currentNode = list.item(i); 
      traverse(currentNode); 

     } 

     if (node.getNodeName().equals("yt:duration")) { 
      Element durationElement = (Element) node; 
      System.out.println(durationElement.getAttribute("seconds")); 
     } 

    } 

输出我得到:

56 
361 
225 
265 
219 
220 
259 
267 
376 
205 
127 
308 
249 
17 
162 
220 
183 
298 
172 
267 
204 
209 

我总是喜欢用DOM递归(如上),因为它简化了充分遍历从而提供灵活性。

如果您想了解更多关于将这些元素分组在一起的信息,也可以参考我的文章here

+0

太棒了。谢谢。我忘了说我已经启用了该功能:'XmlPullParser parser = Xml.newPullParser();' 'parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,true);'无论如何,现在我会尝试这种方法。我接受答案,因为它是一个答案:)非常感谢。 – dentex