一般在解析 XML 資料大致上有分成 DOM、SAX、JDOM、DOM4J 四種解析方式,我比較有接觸過的 DOM、SAX 這兩種,所以只就介紹介紹 DOM、SAX 的差異。接著本範例會使用 OKHttp 來讀取政府提供的XML格式資料(顯著有感地震報告資料),並由 DOM 來解析 XML 格式資料,在由App顯示出相關訊息。
呈現效果:
1.build.gradle(picasso和okhttp 衝突到,需要加okhttp-urlconnection )
2.layout.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="gae.melvin.com.app_okhttp_xml.MainActivity"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/imageView" android:layout_gravity="left|top" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:text="Large Text" android:layout_marginTop="30dp" android:id="@+id/textView" android:textColor="#e12222" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:textSize="26sp" android:text="Large Text" android:textColor="#5500aa" android:id="@+id/textView2" /> </LinearLayout> </FrameLayout>
3.MainActivity.java
package gae.melvin.com.app_okhttp_xml; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; import android.widget.TextView; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import com.squareup.picasso.Picasso; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; public class MainActivity extends AppCompatActivity { private TextView textView,textView2; private Context context; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context= this; findViews(); new RunWork().start(); } private void findViews(){ textView = (TextView)findViewById(R.id.textView); textView2 = (TextView)findViewById(R.id.textView2); imageView = (ImageView)findViewById(R.id.imageView); } /*上網抓資料,需要另外開執行緒做處理(Android機制)*/ private class RunWork extends Thread { //宣告變數 String result_xml = ""; String path = "http://opendata.cwb.gov.tw/govdownload?dataid=E-A0015-001R&authorizationkey=rdec-key-123-45678-011121314"; Runnable task = new Runnable(){ @Override public void run() { parseXml(result_xml); } }; //OkHttpClient官網範例使用 OkHttpClient client = new OkHttpClient(); String run(String url) throws IOException { Request request = new Request.Builder() .url(url) .build(); Response response = client.newCall(request).execute(); return response.body().string(); } @Override public void run() { try{ //1.抓資料 result_xml = run(path); //2.改變畫面內容只能用主執行緒(Android機制) runOnUiThread(task); } catch(IOException e) { e.printStackTrace(); } } } //DOM來解析XML格式資料 private void parseXml(Stringresult_xml){ try { //取得XML根節點 InputStream is = new ByteArrayInputStream(result_xml.getBytes(StandardCharsets.UTF_8));DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(is); Element root = document.getDocumentElement(); //取得 TagName 裡的內容 String reportContent = root.getElementsByTagName("reportContent").item(0).getTextContent();String magnitudeValue = root.getElementsByTagName("magnitudeValue").item(0).getTextContent();String shakemapImageURI = root.getElementsByTagName("shakemapImageURI").item(0).getTextContent(); StringBuilder sb = new StringBuilder(); //取得 Node List NodeList shakingAreas = root.getElementsByTagName("shakingArea");//取得 Node for(int i=0;i<shakingAreas.getLength();i++){ Element element = (Element) shakingAreas.item(i); String areaName = element.getElementsByTagName("areaName").item(0).getTextContent(); String areaIntensity = element.getElementsByTagName("areaIntensity").item(0).getTextContent(); //取得 Node內參數值 String unit = element.getElementsByTagName("areaIntensity").item(0).getAttributes().getNamedItem("unit").getTextContent(); sb.append(areaName).append(" ").append(areaIntensity).append(unit).append("\n"); } //設定顯示畫面資料 /*Picasso第三方套件:用來抓 url 圖片*/ Picasso.with(context).load(shakemapImageURI).into(imageView); textView.setText(reportContent +"\n" + magnitudeValue); textView2.setText(sb); } catch(ParserConfigurationException e) {e.printStackTrace(); } catch(SAXException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } }
參考資料: