2014-02-11 59 views
0

我試圖解析這樣的XML文件:Android的XML解析停在第一個孩子

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<cartoonia xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <stagione nome="Cartoonia Speciale due per vedere se funziona"> 
     <puntata> 
      <numero>0</numero> 
      <titolo>Ciao Cipo</titolo> 
      <link>http://www.dimaleinpentium.com/app/download/5429764359/Cartoonia+%288%5E+Puntata%29.mp3?t=1389213968</link> 
      <descrizione>Ma ciao mia bella Cipo</descrizione> 
     </puntata> 
    </stagione> 
    <stagione nome="Stagione 1"> 
     <puntata> 
      <numero>1</numero> 
      <titolo>Puntata 1</titolo> 
      <link>http://www.dimaleinpentium.com/app/download/5424302459/Cartoonia+1%5E+Puntata.mp3?t=1383736417</link> 
      <descrizione>Descrizione</descrizione> 
     </puntata> 
     <puntata> 
      <numero>2</numero> 
      <titolo>Puntata 2</titolo> 
      <link>http://www.dimaleinpentium.com/app/download/5425828359/Cartoonia+%282%5E+Puntata%29.mp3?t=1384351442</link> 
      <descrizione>Descrizione</descrizione> 
     </puntata> 
     <puntata> 
      <numero>3</numero> 
      <titolo>Puntata 3</titolo> 
      <link>http://www.dimaleinpentium.com/app/download/5427087659/Cartoonia+%283%5E+Puntata%29.mp3?t=1384981673</link> 
      <descrizione>Descrizione Puntata</descrizione> 
     </puntata> 
    </stagione> 
    <stagione nome="Cartoonia Special!"> 
     <puntata> 
      <numero>0</numero> 
      <titolo>Ciao Cipo</titolo> 
      <link>http://www.dimaleinpentium.com/app/download/5429764359/Cartoonia+%288%5E+Puntata%29.mp3?t=1389213968</link> 
      <descrizione>Ma ciao mia bella Cipo</descrizione> 
     </puntata> 
    </stagione> 
</cartoonia> 

有了這個代碼(由AndroidDevs採取和修改,以適應我的文件),我只能讀取第一<stagione>,其他人被忽略。

public Map < String, List <Entry>> parse(InputStream in) throws XmlPullParserException, IOException { 
    try { 
     XmlPullParser parser = Xml.newPullParser(); 
     parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); 
     parser.setInput(in , null); 
     parser.nextTag(); 
     return readFeed(parser); 
    } finally { in .close(); 
    } 
} 


private Map < String, List <Entry>> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException { 
    Map < String, List <Entry>> entries = new HashMap < String, List <Entry>>(); 
    String index = ""; 
    parser.require(XmlPullParser.START_TAG, ns, "cartoonia"); 
    while (parser.next() != XmlPullParser.END_TAG) { 
     Log.d(TAG, "> " + parser.getLineNumber() + " <"); 
     if (parser.getEventType() != XmlPullParser.START_TAG) { 
      continue; 
     } 
     String name = parser.getName(); 
     Log.d(TAG, "" + name); 

     if (name.equals("stagione")) { 
      index = parser.getAttributeValue(null, "nome"); 
      Log.d(TAG, " " + index); 
      entries.put(index, new ArrayList <Entry>()); 
     } else if (name.equals("puntata")) { 
      Log.d(TAG, "  Entry: " + parser.getName()); 
      List <Entry> en = entries.get(index); 
      en.add(readEntry(parser)); 
     } else { 
      skip(parser); 
     } 
    } 
    return entries; 
} 

// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off 
// to their respective "read" methods for processing. Otherwise, skips the tag. 
private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException { 
    parser.require(XmlPullParser.START_TAG, ns, "puntata"); 
    String title = null; 
    String summary = null; 
    String link = null; 
    String number = null; 

    while (parser.next() != XmlPullParser.END_TAG) { 
     if (parser.getEventType() != XmlPullParser.START_TAG) { 
      continue; 
     } 
     String name = parser.getName(); 
     if (name.equals("titolo")) { 
      title = readTitle(parser); 
     } else if (name.equals("numero")) { 
      number = readNumber(parser); 
     } else if (name.equals("descrizione")) { 
      summary = readSummary(parser); 
     } else if (name.equals("link")) { 
      link = readLink(parser); 
     } else { 
      skip(parser); 
     } 
    } 
    return new Entry(title, number, summary, link); 
} 

沒有顯示錯誤或警告或例外。如果我更改<stagione>的順序,我會得到相同的結果,所以我不認爲這是文件的問題。

+0

不是一個大文件。請嘗試使用調試器。 – danny117

+1

這似乎是一個邏輯問題,而不是一個語法錯誤......在這種情況下調試有用嗎? –

+0

你打賭調試將有所幫助。這是您幾分鐘內完成的一個小文件。 – danny117

回答

1

實際上,我在這裏看不懂,它看起來像你在考慮「stagione」和「puntata」是鄰居標籤,但它們不是鄰居,「puntata」是「stagione」的元素,所以,你需要創建每個「stagione」內的另一個解析器讀取「puntata」的

if (name.equals("stagione")) { 
      index = parser.getAttributeValue(null, "nome"); 
      Log.d(TAG, " " + index); 
      entries.put(index, new ArrayList <Entry>()); 
     } else if (name.equals("puntata")) { 
      Log.d(TAG, "  Entry: " + parser.getName()); 
      List <Entry> en = entries.get(index); 
      en.add(readEntry(parser)); 
     } 
1

的問題是你的循環狀態:

while (parser.next() != XmlPullParser.END_TAG) { ... 

你跟END_DOCUMENT混合起來END_TAG。我給你添加一個適合你的實現的例子。我儘可能多地添加了評論。看看這個:

int eventType; 

while ((eventType = parser.getEventType()) != XmlPullParser.END_DOCUMENT) { 
    String current_tag = null; 
    switch (eventType) { 
    case XmlPullParser.START_DOCUMENT: 
     // Do the pertinent initializations here (if you need, if not, just break) 
     break; 

    case XmlPullParser.START_TAG: 
     current_tag = parser.getName();    // Get current tag 
     if (current_tag.equals("cartoonia") 
     continue; 
     else if (current_tag.equals("stagione"))  // Initialize a new object to store a "stagione", probably add the name from "nome" 
     myStagione = new WhatEver(); 
     else if (current_tag.equals("puntata"))  // Do the proper initialization to store a "puntata" 
     myPuntata = new WhatEver2(); 
     else if (myPuntata != null) {     // Just do the same! 
     ... 
     } 

     break; 

    case XmlPullParser.END_TAG:      // This is called if you terminated processing a tag, not at the end of the XML file! 
     current_tag = parser.getName(); 
     ... 

     break; 
    } 

    eventType = parser.next();      // Next event 
} 
+0

我的「START_TAG」是「cartoonia」,所以我認爲'END_TAG'又是「cartoonia」。我錯了嗎?在先前的步驟中,我的XML沒有任何「stagione」,它只是' ... ... ...'和所有「puntata」標記都被處理。 –

+1

我認爲你確實是錯的,因爲你有幾個'START_TAG'標籤,你必須區分它們(用'if'語句)。 'END_TAG'將匹配''和'',所以這是模擬過程,您需要區分它們並正確處理數據,但主要的是您的循環條件是'END_TAG',因此您的循環正在退出其中的第一個,這不是你想要的,而是簡單地遍歷'END_DOCUMENT'。 – nKn

+0

我不是說你錯了,但爲什麼所有在「stagione」中的「puntata」被處理,而只有第一個「stagione」是?我的意思是,如果'END_TAG'將匹配''和'',那麼它應該停在第一個''......我需要了解這種情況,所以感謝您的幫助:) –