2011-10-20 170 views
0

我想解析一个非正常形成的DTD html文件,我通过JSOUP输入流检索,并获取TD字段中的所有数据。 我如何用JSoup做到这一点? 我已经看过http://jsoup.org/cookbook/,但我应该需要som例子才能开始。JSoup解析HTML

预先感谢您。

我已经尝试过saxparser,但是我不能让DTD工作。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-    strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="nl" lang="nl"> 
<TABLE class=personaltable cellSpacing=0 cellPadding=0> 
<TBODY> 
    <TR class=alternativerow> 
    <TD>Nieuw beltegoed:</TD> 
    <TD>€ 1,00</TD></TR> 
    <TR> 
    <TD>Tegoed vorige periode: 
    <TD>€ 2,00</TD></TD></TR> 
    <TR class=alternativerow> 
    <TD>Tegoed tot 09-11-2011: 
    <TD>€ 10,00</TD></TD></TR> 
    <TR> 
    <TD> 
    <TD height=25></TD> 
    <TR class=alternativerow> 
    <TD>Verbruik sinds nieuw tegoed:</TD> 
    <TD>€ 0,33</TD></TR> 
    <TR> 
    <TD>Ongebruikt tegoed:</TD> 
    <TD>€ 12,00</TD></TR> 
    <TR class=alternativerow> 
    <TD class=f-Orange>Verbruik boven bundel:</TD> 
    <TD class=f-Orange>€ 0,00</TD></TR> 
    <TR> 
    <TD>Verbruik dat niet in de bundel zit*:</TD> 
    <TD>€ 0,00</TD></TR> 
    </TBODY> 
</TABLE> 
</html> 

编辑: 我得到一个强制关闭,我需要的JSoup在我的AsyncTask。 这里是logcat的:

10-20 21:07:36.679: ERROR/AndroidRuntime(1396): FATAL EXCEPTION: main 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396): java.lang.NullPointerException 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at com.sencide.AndroidLogin$MyTask.onPostExecute(AndroidLogin.java:276) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at com.sencide.AndroidLogin$MyTask.onPostExecute(AndroidLogin.java:1) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at android.os.AsyncTask.finish(AsyncTask.java:417) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at android.os.AsyncTask.access$300(AsyncTask.java:127) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at android.os.Looper.loop(Looper.java:130) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at android.app.ActivityThread.main(ActivityThread.java:3835) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at java.lang.reflect.Method.invoke(Method.java:507) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 
10-20 21:07:36.679: ERROR/AndroidRuntime(1396):  at dalvik.system.NativeStart.main(Native Method) 

这里是的AsyncTask代码:

public class MyTask extends AsyncTask<String, Integer, String> { 
    private Elements tdsFromSecondColumn=null; 
} 

protected String doInBackground(String... params) { 
     InputStream inputStreamActivity = response.getEntity().getContent(); 

       BufferedReader reader = new BufferedReader(new InputStreamReader(inputStreamActivity)); 
       StringBuilder sb = new StringBuilder(); 
       String line = null; 

       while ((line = reader.readLine()) != null) { 
        sb.append(line + "\n"); 
       } 

       /******* CLOSE CONNECTION AND STREAM *******/ 

       System.out.println(sb); 
       inputStreamActivity.close(); 

       String kpn; 
       kpn = sb.toString(); 

       Document doc = Jsoup.parse(kpn); 
       Elements tdsFromSecondColumn = doc.select("table.personaltable td:eq(1)"); 
} 

@Override 
    protected void onPostExecute(String result) { 
     //publishProgress(false); 
     TextView tv = (TextView)findViewById(R.id.lbl_top); 

     for (Element tdFromSecondColumn : tdsFromSecondColumn) { 
      //System.out.println(tdFromSecondColumn.text()); 
      tv.setText(""); 
      tv.setText(tdFromSecondColumn.text()); 
     } 
} 
} 

回答

5

所以,你有一个InputStream,而不是一个网址?然后,您应该使用Jsoup#parse()方法,它需要一个InputStream

Document document = Jsoup.parse(inputStream, charsetName, baseUri); 
// ... 

charsetName应该是文档在原始编码字符集,您可以把它null让Jsoup决定或退回到UTF-8。 baseUri应该是最初提供HTML的URL。你可以离开它null,你只会无法解析相关链接。

但是,如果你确实有原始URL,那么你也可以只使用Jsoup#connect()

Document document = Jsoup.connect(url).get(); 
// ... 

不管你的方式获得的Document,您可以用CSS selectors选择的文档中感兴趣的元素。另请参阅Jsoup cookbook on that subject。下面是其提取从<table>的第2列中的所有数据与personaltable类名的例子:

Elements tdsFromSecondColumn = document.select("table.personaltable td:eq(1)"); 

for (Element tdFromSecondColumn : tdsFromSecondColumn) { 
    System.out.println(tdFromSecondColumn.text()); 
} 

导致:

€ 1,00 
€ 2,00 
€ 10,00 

€ 0,33 
€ 12,00 
€ 0,00 
€ 0,00 
+0

嗨BalusC, 非常感谢您的回答,当我从工作中返回时,我会马上尝试。 我还有一个问题,有没有办法在TD元素中搜索类似“Nieuw”的字符串,然后执行如tv.setText(“Nieuw beltegoed:”+ tdFromSecondColumn.text())的操作。 预先感谢您 – Lars

+0

您可以使用':contains()'伪选择器:'document.select(“table.personaltable td:contains('Nieuw')”)'。另请参阅有关该主题的Jsoup食谱:http://jsoup.org/cookbook/extracting-data/selector-syntax。 – BalusC

+0

Hi BalusC, Thx工作正常,但我有一个AsyncTask中的JSoup,我正在接近部队。 我用Logcat和AsyncTask代码编辑我的代码。 你有时间帮忙吗? Thx提前。 – Lars