2011-05-03 82 views
2

我有ff。來自URL的XML:Android:我如何顯示具有相同標記名稱的所有XML值

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<Phonebook> 
    <PhonebookEntry> 
     <firstname>Michael</firstname> 
     <lastname>De Leon</lastname> 
     <Address>5, Cat Street</Address> 
    </PhonebookEntry> 
    <PhonebookEntry> 
     <firstname>John</firstname> 
     <lastname>Smith</lastname> 
     <Address>6, Dog Street</Address> 
    </PhonebookEntry> 
</Phonebook> 

我想同時顯示PhonebookEntry值(名字,姓氏,地址)。目前,我的代碼只顯示John Smith的電話簿條目(最後一個條目)。這是我的代碼。

ParsingXML.java

package com.example.parsingxml; 

import java.net.Proxy; 
import java.net.Socket; 
import java.net.SocketAddress; 
import java.net.URL; 
import java.net.URLConnection; 

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.xml.sax.InputSource; 
import org.xml.sax.XMLReader; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.TextView; 
public class ParsingXML extends Activity { 



    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 

     /* Create a new TextView to display the parsingresult later. */ 
     TextView tv = new TextView(this); 
     try { 
       /* Create a URL we want to load some xml-data from. */ 
       URL url = new URL("http://somedomain.com/jm/sampleXML.xml"); 
       URLConnection ucon = url.openConnection(); 
       /* Get a SAXParser from the SAXPArserFactory. */ 
       SAXParserFactory spf = SAXParserFactory.newInstance(); 
       SAXParser sp = spf.newSAXParser(); 

       /* Get the XMLReader of the SAXParser we created. */ 
       XMLReader xr = sp.getXMLReader(); 
       /* Create a new ContentHandler and apply it to the XML-Reader*/ 
       ExampleHandler myExampleHandler = new ExampleHandler(); 
       xr.setContentHandler(myExampleHandler); 

       /* Parse the xml-data from our URL. */ 
       xr.parse(new InputSource(url.openStream())); 
       /* Parsing has finished. */ 

       /* Our ExampleHandler now provides the parsed data to us. */ 
       ParsedExampleDataSet parsedExampleDataSet = 
              myExampleHandler.getParsedData(); 

       /* Set the result to be displayed in our GUI. */ 
       tv.setText(parsedExampleDataSet.toString()); 

     } catch (Exception e) { 
       /* Display any Error to the GUI. */ 
       tv.setText("Error: " + e.getMessage()); 

     } 
     /* Display the TextView. */ 
     this.setContentView(tv); 
    } 
} 

ExampleHandler.java

package com.example.parsingxml; 

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 


public class ExampleHandler extends DefaultHandler{ 

    // =========================================================== 
    // Fields 
    // =========================================================== 

    private boolean in_outertag = false; 
    private boolean in_innertag = false; 
    private boolean in_firstname = false; 
    private boolean in_lastname= false; 
    private boolean in_Address=false; 


    private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet(); 

    // =========================================================== 
    // Getter & Setter 
    // =========================================================== 

    public ParsedExampleDataSet getParsedData() { 
      return this.myParsedExampleDataSet; 
    } 

    // =========================================================== 
    // Methods 
    // =========================================================== 
    @Override 
    public void startDocument() throws SAXException { 
      this.myParsedExampleDataSet = new ParsedExampleDataSet(); 
    } 

    @Override 
    public void endDocument() throws SAXException { 
      // Nothing to do 
    } 

    /** Gets be called on opening tags like: 
     * <tag> 
     * Can provide attribute(s), when xml was like: 
     * <tag attribute="attributeValue">*/ 
    @Override 
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 

     if (localName.equals("PhoneBook")) { 
      this.in_outertag = true; 
     }else if (localName.equals("PhonebookEntry")) { 
      this.in_innertag = true; 
     }else if (localName.equals("firstname")) { 
      this.in_firstname = true; 
     }else if (localName.equals("lastname")) { 
      this.in_lastname= true; 
     }else if(localName.equals("Address")) { 
      this.in_Address= true; 
     } 

    } 

    /** Gets be called on closing tags like: 
     * </tag> */ 
    @Override 
    public void endElement(String namespaceURI, String localName, String qName) 
       throws SAXException { 
      if (localName.equals("Phonebook")) { 
       this.in_outertag = false; 
      }else if (localName.equals("PhonebookEntry")) { 
       this.in_innertag = false; 
      }else if (localName.equals("firstname")) { 
       this.in_firstname = false; 
      }else if (localName.equals("lastname")) { 
       this.in_lastname= false; 
      }else if(localName.equals("Address")) { 
       this.in_Address= false; 
      } 
    } 

    /** Gets be called on the following structure: 
     * <tag>characters</tag> */ 
    @Override 
    public void characters(char ch[], int start, int length) { 
      if(this.in_firstname){ 
      myParsedExampleDataSet.setfirstname(new String(ch, start, length)); 
      } 
      if(this.in_lastname){ 
      myParsedExampleDataSet.setlastname(new String(ch, start, length)); 
      } 
      if(this.in_Address){ 
       myParsedExampleDataSet.setAddress(new String(ch, start, length)); 
      } 
    } 
} 

ParsedExampleDataSet.java

package com.example.parsingxml; 

public class ParsedExampleDataSet { 
    private String firstname = null; 
    private String lastname=null; 
    private String Address=null; 


    //Firstname 
    public String getfirstname() { 
     return firstname; 
    } 
    public void setfirstname(String firstname) { 
     this.firstname = firstname; 
    } 

    //Lastname 
    public String getlastname(){ 
     return lastname; 
    } 
    public void setlastname(String lastname){ 
     this.lastname=lastname; 
    } 

    //Address 
    public String getAddress(){ 
     return Address; 
    } 
    public void setAddress(String Address){ 
     this.Address=Address; 
    } 

    public String toString(){ 
     return "Firstname: " + this.firstname + "\n" + "Lastname: " + this.lastname + "\n" + "Address: " + this.Address; 

    } 
} 

我是新來的java和android dev,很多感謝提前任何幫助! :)

+0

只是讓您知道有更好的方法來處理Android中的XML。我建議不要直接使用所有內置的解析器,而是使用Simple XML爲您完成所有繁重的工作,而您只需使用註釋來引導數據:http://massaioli.homelinux.com/wordpress/2011/04/21/simple-xml-in-android-1-5-up-up/ – 2011-05-04 00:45:47

回答

2

其他反應已經指出,你需要一個列表來存儲從XML得到所有ParsedExampleDataSet對象。

但是我想將你的注意力放在關於XML處理程序的另一件事上,它可能會在以後(隨機)咬你。字符方法不是一種很好的地方,可以爲您的XML中的標籤分配值,因爲字符方法不能保證一次返回元素中的所有字符。它可能會在同一元素中多次調用以報告迄今爲止發現的字符。按照現在的實施方式,您最終會丟失數據並且想知道發生了什麼。

也就是說,我要做的是使用StringBuilder來累積你的角色,然後在endElement(...)調用中分配它們。像這樣:

public class ExampleHandler extends DefaultHandler{ 

// =========================================================== 
// Fields 
// =========================================================== 

private StringBuilder mStringBuilder = new StringBuilder(); 

private ParsedExampleDataSet mParsedExampleDataSet = new ParsedExampleDataSet(); 
private List<ParsedExampleDataSet> mParsedDataSetList = new ArrayList<ParsedExampleDataSet>(); 

// =========================================================== 
// Getter & Setter 
// =========================================================== 

public List<ParsedExampleDataSet> getParsedData() { 
     return this.mParsedDataSetList; 
} 

// =========================================================== 
// Methods 
// =========================================================== 

/** Gets be called on opening tags like: 
    * <tag> 
    * Can provide attribute(s), when xml was like: 
    * <tag attribute="attributeValue">*/ 
@Override 
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 
    if (localName.equals("PhonebookEntry")) { 
     this.mParsedExampleDataSet = new ParsedExampleDataSet(); 
    } 

} 

/** Gets be called on closing tags like: 
    * </tag> */ 
@Override 
public void endElement(String namespaceURI, String localName, String qName) 
      throws SAXException { 
     if (localName.equals("PhonebookEntry")) { 
      this.mParsedDataSetList.add(mParsedExampleDataSet); 
     }else if (localName.equals("firstname")) { 
      mParsedExampleDataSet.setfirstname(mStringBuilder.toString().trim()); 
     }else if (localName.equals("lastname")) { 
      mParsedExampleDataSet.setlastname(mStringBuilder.toString().trim()); 
     }else if(localName.equals("Address")) { 
      mParsedExampleDataSet.setAddress(mStringBuilder.toString().trim()); 
     } 
     mStringBuilder.setLength(0); 
} 

/** Gets be called on the following structure: 
    * <tag>characters</tag> */ 
@Override 
public void characters(char ch[], int start, int length) { 
     mStringBuilder.append(ch, start, length); 
} 
} 

然後你可以檢索你的活動ParsedExampleDataSets在多個文本視圖或只在一個列表中,要麼顯示。您的Activity.onCreate(...)方法可能如下所示:

/** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 

     /* Create a new TextView to display the parsingresult later. */ 
     TextView tv = new TextView(this); 
     try { 
       /* Create a URL we want to load some xml-data from. */ 
       URL url = new URL("http://somedomain.com/jm/sampleXML.xml"); 
       URLConnection ucon = url.openConnection(); 

       /* Create a new ContentHandler and apply it to the XML-Reader*/ 
       ExampleHandler myExampleHandler = new ExampleHandler(); 

       //remember to import android.util.Xml 
       Xml.parse(url.openStream(), Xml.Encoding.UTF_8, myExampleHandler); 


       /* Our ExampleHandler now provides the parsed data to us. */ 
       List<ParsedExampleDataSet> parsedExampleDataSetList = 
              myExampleHandler.getParsedData(); 

       /* Set the result to be displayed in our GUI. */ 
       for(ParsedExampleDataSet parsedExampleDataSet : parsedExampleDataSetList){ 
        tv.append(parsedExampleDataSet.toString()); 
       } 

     } catch (Exception e) { 
       /* Display any Error to the GUI. */ 
       tv.setText("Error: " + e.getMessage()); 

     } 
     /* Display the TextView. */ 
     this.setContentView(tv); 
    } 
+0

哇!非常感謝你的代碼和建議,但是我沒有使用第二個代碼塊,我仍然使用上面的ParsingXML.java並更改了下面的代碼:** ParsedExampleDataSet parsedExampleDataSet = myExampleHandler.getParsedData(); ** to ** List parsedExampleDataSet = myExampleHandler.getParsedData(); ** ...還要感謝其他回覆的人! :) – Kris 2011-05-03 07:39:12

0

您的處理程序中只有一個ParsedExampleDataSet對象,因此只能存儲一個條目的空間。更改ExampleHandler以擁有ArrayList<ParsedExampleDataSet> results以及ParsedExampleDataSet currentSet。在startElement內部,當您看到PhoneBook標記時,將currentSet設置爲ParsedExampleDataSet的新實例並將其添加到results。解析後,results應該包含你想要的一切。

0

你很近。既然你有很多PhoneBookeEntrys你需要將它們存儲在什麼地方:

public class ExampleHandler extends DefaultHandler{ 

// =========================================================== 
// Fields 
// =========================================================== 

private boolean in_outertag = false; 
private boolean in_innertag = false; 
private boolean in_firstname = false; 
private boolean in_lastname= false; 
private boolean in_Address=false; 

private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet(); 
private List<ParsedExampleDataSet> allSets = new ArrayList<ParsedExampleDataSet>(); 

// =========================================================== 
// Getter & Setter 
// =========================================================== 

public ParsedExampleDataSet getParsedData() { 
     return this.myParsedExampleDataSet; 
} 

// =========================================================== 
// Methods 
// =========================================================== 

/** Gets be called on opening tags like: 
    * <tag> 
    * Can provide attribute(s), when xml was like: 
    * <tag attribute="attributeValue">*/ 
@Override 
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 

    if (localName.equals("PhoneBook")) { 
     this.in_outertag = true; 
    }else if (localName.equals("PhonebookEntry")) { 
     this.in_innertag = true; 
     this.myParsedExampleDataSet = new ParsedExampleDataSet(); 
    }else if (localName.equals("firstname")) { 
     this.in_firstname = true; 
    }else if (localName.equals("lastname")) { 
     this.in_lastname= true; 
    }else if(localName.equals("Address")) { 
     this.in_Address= true; 
    } 

} 

/** Gets be called on closing tags like: 
    * </tag> */ 
@Override 
public void endElement(String namespaceURI, String localName, String qName) 
      throws SAXException { 
     if (localName.equals("Phonebook")) { 
      this.in_outertag = false; 
     }else if (localName.equals("PhonebookEntry")) { 
      this.in_innertag = false; 
      allSets.add(myParsedExampleDataSet); 
     }else if (localName.equals("firstname")) { 
      this.in_firstname = false; 
     }else if (localName.equals("lastname")) { 
      this.in_lastname= false; 
     }else if(localName.equals("Address")) { 
      this.in_Address= false; 
     } 
} 

/** Gets be called on the following structure: 
    * <tag>characters</tag> */ 
@Override 
public void characters(char ch[], int start, int length) { 
     if(this.in_firstname){ 
     myParsedExampleDataSet.setfirstname(new String(ch, start, length)); 
     } 
     if(this.in_lastname){ 
     myParsedExampleDataSet.setlastname(new String(ch, start, length)); 
     } 
     if(this.in_Address){ 
      myParsedExampleDataSet.setAddress(new String(ch, start, length)); 
     } 
} 
} 
+0

你剛剛添加了這行嗎?私人列表 allSets = new ArrayList (); ...我如何檢索所有的值然後,對於這個noob問題抱歉... – Kris 2011-05-03 06:35:07

+0

對不起小錯誤:讓它公開。 – 2011-05-03 09:03:35

0

我發現了一個XML教程在線here和editied它與你的XML文件中工作。以下是代碼。爲了在我的機器上測試它,我從本地文件而不是在線獲取XML文件,但解決這個問題不應該太困難。

這應該有希望指出你在正確的方向。

package phonebook; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 

import java.io.File; 

import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 


public class program { 
    public static void main(String argv[]) { 

      try { 
       File file = new File("phonebook.xml"); 
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
       DocumentBuilder db = dbf.newDocumentBuilder(); 
       Document doc = db.parse(file); 
       doc.getDocumentElement().normalize(); 
       System.out.println("Root element " + doc.getDocumentElement().getNodeName()); 
       NodeList nodeLst = doc.getElementsByTagName("PhonebookEntry"); 
       System.out.println("Information of all entries"); 

       for (int s = 0; s < nodeLst.getLength(); s++) { 

       Node fstNode = nodeLst.item(s); 

       if (fstNode.getNodeType() == Node.ELEMENT_NODE) 
       { 
        Element fstElmnt = (Element) fstNode; 

        // Firstname 
        NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("firstname"); 
        Element fstNmElmnt = (Element) fstNmElmntLst.item(0); 
        NodeList fstNm = fstNmElmnt.getChildNodes(); 
        System.out.println("First Name : " + ((Node) fstNm.item(0)).getNodeValue()); 

        // Lastname 
        NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("lastname"); 
        Element lstNmElmnt = (Element) lstNmElmntLst.item(0); 
        NodeList lstNm = lstNmElmnt.getChildNodes(); 
        System.out.println("Last Name : " + ((Node) lstNm.item(0)).getNodeValue()); 

        // Address 
        NodeList addrNmElmntLst = fstElmnt.getElementsByTagName("Address"); 
        Element addrNmElmnt = (Element) addrNmElmntLst.item(0); 
        NodeList addrNm = addrNmElmnt.getChildNodes(); 
        System.out.println("Address : " + ((Node) addrNm.item(0)).getNodeValue()); 
       } 
       } 
      } catch (Exception e) { 
      e.printStackTrace(); 
      } 
     } 
} 
+0

感謝您的回覆,但我得到一個強制關閉消息,我有我的代碼在這裏:http://stackoverflow.com/questions/5866113/android-dom-parsing-gets-force-close-message – Kris 2011-05-03 06:56:51

相關問題