Android:处理程序返回空字符串解析与SAX解析器的XML

Android:处理程序返回空字符串解析与SAX解析器的XML

问题描述:

我一直试图在Android上使用SAX解析器来显示一些xml,这是查询到数据库的结果。Android:处理程序返回空字符串解析与SAX解析器的XML

我从数据库中得到正确的答案,但是当我想要解析xml并将内容转储到文本视图中时,ExampleHandler(ParsedExampleDataSet)返回一个带有空字符串的对象。我一直在试图追踪问题出在哪里,但却无法解决问题。

到目前为止,我知道数据在字符方法中被正确解析,我设法将内容打印到日志文件中,但是我不能在该点返回字符串。

我相信更多的程序员法的实验可以很容易地解决这个问题:

我的XML文件是非常基本的,<body> blablablah </body>

以下是文件:

package com.ignacio.BilingualSTT; 

import java.io.BufferedInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 
import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 
import android.util.Log; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.util.ByteArrayBuffer; 
import org.xml.sax.InputSource; 
import org.xml.sax.XMLReader; 
import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.TextView; 
import android.widget.Toast; 

public class PostAndGet extends Activity { 

    private static String Utterance = null; 
    TextView Title; 
    TextView Content; 
    private static final String TAG = "TextToSpeechDemo"; 
    String text; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.en_results); 
      Title = (TextView)findViewById(R.id.A1_title); 
      Content= (TextView) findViewById(R.id.A1_content); 
      text = ""; 

      Bundle b = this.getIntent().getExtras(); 
      if (b !=null){ 
        Utterance = b.getString("query"); 
      } 
      postData(Utterance); 
    } 

    /** 
* Handle the action of the Back button 
*/ 

public void sendback(View v) 
{ 
    Intent Sendback=new Intent(this, EnglishRecognizer.class); 
      startActivity(Sendback); 
} 

/** 
* Start HTTP Post call 
*/ 

public void postData(String Utterance){ 
      // Create a new HttpClient and Post Header 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost("http://hcc.cs.clemson.edu/~ignm/ignacio/Android_QueryResults.php"); 

      try { 
        // Add data to the HTTP Request data has to be named query since the PHP page in the server is expecting that name to run the query on the DB 
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
        nameValuePairs.add(new BasicNameValuePair("query", Utterance)); 
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

        // Execute HTTP Post Request and retrieve answer from PHP side. 
        HttpResponse response = httpclient.execute(httppost); 
        InputStream is = response.getEntity().getContent(); 
        BufferedInputStream bis = new BufferedInputStream(is); 
        ByteArrayBuffer baf = new ByteArrayBuffer(20); 
        int current = 0; 

        while((current = bis.read()) != -1){ 
          baf.append((byte)current); 
        } 

        // Convert the Bytes read to a String and display it in the Title Container 
        text = new String(baf.toByteArray()); 
        Title.setText(text); 

        //Send Text to 
        parseXML (text); 


      } catch (ClientProtocolException e) { 
        // TODO Auto-generated catch block 
        Toast.makeText(this, "Error in the connection", Toast.LENGTH_SHORT).show(); 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
        Toast.makeText(this,"IO Exception error", Toast.LENGTH_SHORT).show(); 
      } 
    } 


public void parseXML (String text){ 

    String AnswerExt = text; 

    try { 
      /* Create a URL we want to load some xml-data from. */ 
      URL url = new URL("http://hcc.cs.clemson.edu/~ignm/ignacio/"+AnswerExt.toString()); 

      Log.i(TAG, url.toString()); 

      /* 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. */ 
      Content.setText(parsedExampleDataSet.getExtractedString()); 


    } catch (Exception e) { 
      /* Display any Error to the GUI. */ 
      Content.setText("Error: " + e.getMessage()); 
      Log.e(TAG, "QueryError", e); 
    } 
} 
} 

实例处理程序修改,以适应我的XML的解析。

package com.ignacio.BilingualSTT; 
import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 
import android.content.Intent; 
import android.os.Bundle; 
import android.util.Log; 

public class ExampleHandler extends DefaultHandler{ 

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

    private boolean bodytag = false; 
    private static final String TAG = "TextToSpeechDemo"; 

    public ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet(); 
    public String myReturnString = null; 

    // =========================================================== 
    // 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("body")) { 
        this.bodytag = true; 
      } 
    } 

    /** Gets be called on closing tags like: 
    * </tag> */ 
    @Override 
    public void endElement(String namespaceURI, String localName, String qName) 
        throws SAXException { 
      if (localName.equals("body")) { 
        this.bodytag = false; 
      } 
    } 

    /** Gets be called on the following structure: 
    * <tag>characters</tag> */ 
    @Override 
public void characters(char ch[], int start, int length) { 
      if(this.bodytag){ 
      myParsedExampleDataSet.setExtractedString(new String(ch, start, length)); 
      //String Temp = myParsedExampleDataSet.getExtractedString(); 
      //Log.i(TAG, Temp);  
    } 
    } 

} 

ParsedExampleDataSet:

package com.ignacio.BilingualSTT; 

    public class ParsedExampleDataSet { 
    private String extractedString = "No content yet"; 

    public String getExtractedString() { 
      return extractedString; 
    } 
    public void setExtractedString(String extractedString) { 
      this.extractedString = extractedString; 
    }  
    public String toString(){ 
      return this.extractedString; 
    } 
} 

太谢谢你了!

+0

如果代码示例小得多([SSCE](http://sscce.org/)),读取会更容易 - 如果从数据库中获得的响应是​​正确的,那么我们不需要知道该代码的作用。 –

characters方法可以在标签内多次调用,特别是如果元素值包含空格。

您可能会看到发生这种情况的Logcat正在打印多行。

documentation

解析器将调用此方法来报告字符 每个数据块。 SAX解析器可能会将所有连续的字符数据返回到单个块中,或者它们可能会将其分割为多个块;但是,任何单个事件中的所有 字符都必须来自相同的外部实体 ,以便定位器提供有用的信息。

与其使用setExtractedString,您应该追加到正在构建的字符串中,可能使用StringBuilder

查看接受的答案here

+0

非常感谢马丁脚!它工作得很好。 我会小心不要发布完整的代码示例以减轻下次阅读时间:) – Ignacio