一般在解析 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();
}
}
}
參考資料: