2011-05-03 54 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

相关问题