XmlPullParser는 Android에서 XML 문서를 이벤트 기반으로 순차적으로 읽어 들이는 경량 파서입니다. DOM 파서처럼 문서 전체를 메모리에 올리지 않기 때문에 메모리 사용량이 적고 속도가 빠르며, 리소스가 제한적인 모바일 환경에 특히 적합합니다. 이 글에서는 assets 폴더에 저장된 XML 파일을 XmlPullParser로 구문 분석한 뒤, 그 결과를 ListView에 표시하는 전체 과정을 단계별로 살펴보겠습니다.
1단계: 새 프로젝트 생성
Android Studio에서 File ⇒ New Project를 선택하고, 새 프로젝트 생성에 필요한 모든 정보를 입력합니다.
2단계: activity_main.xml 작성
res/layout/activity_main.xml에 다음 코드를 추가합니다. 파싱한 사용자 목록을 보여줄 ListView 하나만 배치하면 됩니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:dividerHeight="1dp"/>
</LinearLayout>
3단계: 리스트 항목 레이아웃(row.xml) 작성
res/layout 폴더에서 마우스 오른쪽 버튼을 클릭해 레이아웃 리소스 파일(row.xml)을 생성하고 다음 코드를 추가합니다. 각 리스트 항목은 이름, 직책, 지역을 표시하는 세 개의 TextView로 구성됩니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip">
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="17dp"/>
<TextView
android:id="@+id/tvDesignation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tvName"
android:layout_marginTop="7dp"
android:textColor="#343434"
android:textSize="14dp"/>
<TextView
android:id="@+id/tvLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/tvDesignation"
android:layout_alignBottom="@+id/tvDesignation"
android:layout_alignParentRight="true"
android:textColor="#343434"
android:textSize="14dp"/>
</RelativeLayout>
4단계: MainActivity.java 작성
src/MainActivity.java에 다음 코드를 추가합니다. XmlPullParserFactory로 파서 인스턴스를 생성한 후, getEventType()으로 이벤트를 순회하며 START_TAG·TEXT·END_TAG 이벤트를 처리합니다. name, designation, location 태그를 만나면 해당 값을 HashMap에 저장하고, user 태그가 닫힐 때마다 리스트에 추가한 뒤 SimpleAdapter를 통해 ListView에 바인딩합니다.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
ArrayList<HashMap<String, String>> userList = new ArrayList<>();
HashMap<String, String> user = new HashMap<>();
ListView lv = findViewById(R.id.listView);
InputStream inputStream = getAssets().open("userdetails.xml");
XmlPullParserFactory parserFactory = XmlPullParserFactory.newInstance();
XmlPullParser parser = parserFactory.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(inputStream, null);
String tag = "", text = "";
int event = parser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
switch (event) {
case XmlPullParser.START_TAG:
if (tag.equals("user"))
user = new HashMap<>();
break;
case XmlPullParser.TEXT:
text = parser.getText();
break;
case XmlPullParser.END_TAG:
switch (tag) {
case "name":
user.put("name", text);
break;
case "designation":
user.put("designation", text);
break;
case "location":
user.put("location", text);
break;
case "user":
if (user != null)
userList.add(user);
break;
}
break;
}
event = parser.next();
}
ListAdapter adapter = new SimpleAdapter(MainActivity.this, userList, R.layout.row,
new String[]{"name", "designation", "location"},
new int[]{R.id.tvName, R.id.tvDesignation, R.id.tvLocation});
lv.setAdapter(adapter);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
}
5단계: userdetails.xml 데이터 파일 준비
assets 폴더를 생성하고, 그 안에 userdetails.xml 파일을 만들어 다음 내용을 추가합니다. 각 user 요소는 이름(name), 직책(designation), 지역(location) 정보를 담고 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<users>
<user>
<name>Sehwag</name>
<designation>Vice Captain</designation>
<location>Delhi</location>
</user>
<user>
<name>Ashwin</name>
<designation>Off Spin Bowler</designation>
<location>Chennai</location>
</user>
<user>
<name>Dhoni</name>
<designation>Captain</designation>
<location>Ranchi</location>
</user>
</users>
</resources>
6단계: AndroidManifest.xml 설정
AndroidManifest.xml에 다음 코드를 추가합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
앱 실행 및 결과 확인
이제 애플리케이션을 실행해 보겠습니다. 실제 Android 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하고, 실행 대상으로 모바일 기기를 선택하세요. 그러면 기기 화면에 파싱된 사용자 목록이 아래와 같이 표시됩니다.
