2011-05-02 52 views
1

的標籤我有這些XML在URL安卓:SAX解析返回空值和檢索值同名

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<Phonebook> 
    <PhonebookEntry> 
     <firstname>John</firstname> 
     <lastname>Connor</lastname> 
     <Address>5,Downing Street</Address> 
     <Phone loc="home">9875674567</Phone> 
     <Phone loc="work">9875674567</Phone> 
     <Phone loc="mobile">78654562341</Phone> 
    </PhonebookEntry> 
    <PhonebookEntry> 
     <firstname>John</firstname> 
     <lastname>Smith</lastname> 
     <Address>6,Downing Street</Address> 
     <Phone loc="home">678-56-home</Phone> 
     <Phone loc="work">678-59-work</Phone> 
     <Phone loc="mobile">678-85-mobile</Phone> 
    </PhonebookEntry> 
</Phonebook> 

當談到我能夠提取的名字,姓氏和地址的值,但到電話標籤,我的代碼返回空值。這裏是我的代碼:

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); 
     //System.setProperty("http.proxyHost"," 129.188.69.100 "); 
     //System.setProperty("http.proxyPort","1080"); 
     //System.setProperty("http.nonProxyHosts","10.228.97.76"); 

     /* 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 boolean in_Phone=false; 
    private boolean in_homePhone=false; 
    private boolean in_workPhone=false; 
    private boolean in_mobilePhone=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; 
      }else if (localName.equals("Phone")){ 
       this.in_Phone=true; 
       String phoneattr=atts.getValue("loc"); 
       if(phoneattr.equals("home")){ 
       this.in_homePhone=true; 
       }else if(phoneattr.equals("work")){ 
       this.in_workPhone=true; 
       }else if(phoneattr.equals("mobile")){ 
       this.in_mobilePhone=true; 
      } 
     } 


      } 

       //else if (localName.equals("tagwithnumber")) { 
     // } 
       // Extract an Attribute 
       // String attrValue = atts.getValue("thenumber"); 
       // int i = Integer.parseInt(attrValue); 
       // myParsedExampleDataSet.setExtractedInt(i); 
     // } 


    /** 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; 
      }else if(localName.equals("Phone")) { 
       this.in_Phone=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)); 
      } 
      if(this.in_homePhone){ 
       myParsedExampleDataSet.sethomePhone(new String(ch, start, length)); 
      } 
      if(this.in_workPhone){ 
       myParsedExampleDataSet.setworkPhone(new String(ch, start, length)); 
      } 
      if(this.in_mobilePhone){ 
       myParsedExampleDataSet.setmobilePhone(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; 
    private String Phone=null; 
    private String homephone=null; 
    private String workphone=null; 
    private String mobilephone=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; 
    } 

    //Phone 
    public String getPhone(){ 
     return Phone; 
    } 
    public void sethomePhone(String homePhone){ 
     this.homephone=homePhone; 
    } 
    public void setworkPhone(String homePhone){ 
     this.homephone=homePhone; 
    } 
    public void setmobilePhone(String homePhone){ 
     this.homephone=homePhone; 
    } 


    public String toString(){ 
     return "firstname: " + this.firstname + "\n" + "lastname=: " + this.lastname + "\n" + "Address: " + this.Address+ "\n" + "homephone: " + this.homephone + "\n" + "workphone: " + this.workphone + "\n" + "mobilephone: " + this.mobilephone; 

    } 
} 

另一件事我該如何檢索PhonebookEntry標記中的兩個值?

我有點新來java和android開發,非常感謝提前! :)

回答

7

此代碼使得不正確的假設characters方法將在startElementendElement調用標記之間調用一次。

而不必在characters方法設置值的邏輯,你需要在startElement方法初始化一個緩衝區,收集字符轉換成在characters法進行緩衝,然後進行分配和清除緩衝區中endElement方法。

編輯:

其實,有你的代碼的一些其他問題...

你有setMobilePhone和setWorkPhone在模型類設置HOMEPHONE場......一個必然的風險時,你複製 - 修改代碼。

而你的處理程序只創建一個結果,並且會覆蓋並只返回文件中的最後一個結果。

我玩過它,將一些方法更改爲Java標準命名,並將一些xml更改爲CamelCase。

修改後的XML:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<PhoneBook> 
    <PhoneBookEntry> 
     <FirstName>John</FirstName> 
     <LastName>Connor</LastName> 
     <Address>5,Downing Street</Address> 
     <Phone loc="home">9875674567</Phone> 
     <Phone loc="work">9875674567</Phone> 
     <Phone loc="mobile">78654562341</Phone> 
    </PhoneBookEntry> 
    <PhoneBookEntry> 
     <FirstName>John</FirstName> 
     <LastName>Smith</LastName> 
     <Address>6,Downing Street</Address> 
     <Phone loc="home">678-56-home</Phone> 
     <Phone loc="work">678-59-work</Phone> 
     <Phone loc="mobile">678-85-mobile</Phone> 
    </PhoneBookEntry> 
</PhoneBook> 

修訂ParsedExampleDataSet:

public class ParsedExampleDataSet { 
    private String firstName = null; 
    private String lastName =null; 
    private String address =null; 
    private String homePhone =null; 
    private String workPhone =null; 
    private String mobilePhone =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 void setHomePhone(String homePhone){ 
     this.homePhone =homePhone; 
    } 
    public void setWorkPhone(String homePhone){ 
     this.workPhone =homePhone; 
    } 
    public void setMobilePhone(String homePhone){ 
     this.mobilePhone =homePhone; 
    } 


    public String toString(){ 
     return "firstName: " + this.firstName + "\n" + "lastName=: " + this.lastName + "\n" + "address: " + this.address + "\n" + "homePhone: " + this.homePhone + "\n" + "workPhone: " + this.workPhone + "\n" + "mobilePhone: " + this.mobilePhone; 

    } 
} 

這確實解析處理程序:

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

import java.util.ArrayList; 
import java.util.List; 

public class ExampleHandler extends DefaultHandler { 

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

    private boolean in_homePhone = false; 
    private boolean in_workPhone = false; 
    private boolean in_mobilePhone = false; 

    private StringBuffer stringBuffer; 

    private List<ParsedExampleDataSet> myParsedExampleDataSets; 
    private ParsedExampleDataSet myParsedExampleDataSet; 

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

    public List<ParsedExampleDataSet> getParsedData() { 
     return myParsedExampleDataSets; 
    } 

    @Override 
    public void startDocument() throws SAXException { 
     myParsedExampleDataSets = new ArrayList<ParsedExampleDataSet>(); 
     stringBuffer = new StringBuffer(); 
    } 

    @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 (qName.equals("PhoneBookEntry")) { 
      myParsedExampleDataSet = new ParsedExampleDataSet(); 
     } 

     if (qName.equals("Phone")) { 
      String phoneLocation = atts.getValue("loc"); 
      if (phoneLocation.equals("home")) { 
       this.in_homePhone = true; 
      } else if (phoneLocation.equals("work")) { 
       this.in_workPhone = true; 
      } else if (phoneLocation.equals("mobile")) { 
       this.in_mobilePhone = true; 
      } 
     } 
    } 

    /** 
    * Gets be called on closing tags like: 
    * </tag> 
    */ 
    @Override 
    public void endElement(String namespaceURI, String localName, String qName) 
      throws SAXException { 

     String result = stringBuffer.toString(); 
     stringBuffer.setLength(0); 

     if (in_homePhone) { 
      myParsedExampleDataSet.setHomePhone(result); 
      in_homePhone = false; 
     } 
     else if (in_mobilePhone) { 
      myParsedExampleDataSet.setMobilePhone(result); 
      in_mobilePhone = false; 
     } 
     else if (in_workPhone) { 
      myParsedExampleDataSet.setWorkPhone(result); 
      in_workPhone = false; 
     } 
     else if (qName.equals("FirstName")) { 
      myParsedExampleDataSet.setFirstName(result); 
     } 
     else if (qName.equals("LastName")) { 
      myParsedExampleDataSet.setLastName(result); 
     } 
     else if (qName.equals("Address")) { 
      myParsedExampleDataSet.setAddress(result); 
     } 
     else if (qName.equals("PhoneBookEntry")) { 
      myParsedExampleDataSets.add(myParsedExampleDataSet); 
     } 
    } 

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

} 

它把一些可能不需要的空白的領域,但我懷疑你可以弄清楚如何修剪。

調用它,你會得到一個列表,而不是一個單一的對象,但除了處理這個,你的調用代碼不應該改變太多。我沒有嘗試去處理這個問題,因爲我在android上沒有這樣做。

+0

嗨,唐,謝謝你的迴應!你有它的示例代碼? – Kris 2011-05-18 07:42:01

+0

你做了我的一天,謝謝。 – RobinHood 2014-11-03 07:22:38

0

此外,要從元素中獲取屬性,您可以使用如下所示: 您可以從startElement方法中的atts Attributes中獲取屬性。

}else if (localName.equals("Phone")){ 
      this.in_Phone=true; 
      int length = atts.getLength(); 
      System.out.println("length = " + length); 
      for(int i = 0; i < length; i++){ 
       String name = atts.getQName(i); 
       System.out.println(name); 
       String value = atts.getValue(i); 
       System.out.println(value); 
       if(name.equals("loc")){ 
        if(value.equals("home")){ 
        this.in_homePhone=true; 
        }else if(value.equals("work")){ 
        this.in_workPhone=true; 
        }else if(value.equals("mobile")){ 
        this.in_mobilePhone=true; 
       } 

       } 
      } 
    } 
+0

感謝您的回覆!你的意思是我要設置startElement方法的值?嗯,你有它的示例代碼? – Kris 2011-05-18 07:43:13