2014-02-14 56 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