nueijeel
[Android] XML, JSON 데이터 가져오기 본문
안드로이드에서는 xml 문서와 json 문서의 데이터를 파싱해 가져올 수 있다.
1. XML 데이터 가져오기
xml은 마크업 언어이고 문서 내용이 태그로 구성되어 있다.
xml 문서를 파싱하는데는 DOM, SAX, XmlPullParser의 3가지 방법이 있다.
DOM 방식은 우선 문서를 처음부터 끝까지 읽어온 후 데이터를 트리구조로 만든 다음 필요한 처리를 하기 때문에, 모든 데이터가 메모리에 존재하고 있어 사용이 용이하고 속도도 빠르다.
여기서는 간단하게 DOM 방식을 이용한 예제를 소개하려고 한다.
1) AndroidManifest.xml에 인터넷 사용 권한 추가
<uses-permission android:name="android.permission.INTERNET"/>
해당 안드로이드 앱에서 인터넷 접속을 할 수 있도록 권한을 추가해준다.
2) 접속할 주소로 변수 선언
val serverAddress = " 접속할 주소 url "
3) 접속 주소 관리 객체 생성
//주소 관리 객체
val url = URL(serverAddress)
//접속
val httpUrlConnection = url.openConnection() as HttpURLConnection
//브라우저 확인
httpUrlConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
주소 변수를 관리하는 url 객체를 생성하고, 해당 객체로 접속을 시도한다.
이때, 접속하려는 서버에서 브라우저를 확인할 수 있기 때문에 User Agent를 헤더 필드로 추가해준다.
addRequestProperty()는 설정할 헤더 필드의 key, value를 매개변수로 받아 서버에 헤더를 설정하고 원하는 요청을 받을 수 있게 해주는데, 여기서 value 값으로 전달된 문자열은 클라이언트가 Chrome 브라우저로 인식되게 설정한 코드이다.
그리고 네트워크 관련된 코드들은 전부 메인 스레드에 작성하는 것을 잊지 말자!
4) xml 데이터를 DOM 파싱
//도구 생성
val documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
//document 객체 생성
val document = documentBuilder.parse(httpUrlConnection.inputStream)
먼저 xml 문서를 분석해 데이터를 파싱하여 dom 트리를 생성하는 역할을 하는 DocumentBuilder 객체를 생성한다.
httpUrlConnection.inputStream으로 서버로부터 받은 xml 데이터를 읽어와 documentBuilder로 파싱하면 dom 트리의 구조를 담은 document 객체를 반환한다.
5) 태그 객체와 데이터 가져오기
//최상위 태그 가져옴
val root = document.documentElement
// data tag를 가져온다.
val dataTag = root.getElementsByTagName("data")
// METAR tag를 가져온다.
val dataElement = dataTag.item(0) as Element
val METARTag = dataElement.getElementsByTagName("METAR")
document의 최상위 태그를 가져와 하위 태그 중 원하는 태그를 getElementsByTagName()으로 구한다.
실제 xml 파일이 가지고 있던 데이터 구조인데, 최상위 태그인 <response>아래 <data> 태그가 있고, 그 아래에 <METAR> 태그가 있는 모습이다.
따라서 코드에서는 data 태그를 먼저 가져온 뒤, 해당 태그 하위에 위치한 METAR 태그를 가져왔다.
이렇게 원하는 태그를 가져왔으면, 해당 태그 객체를 생성하고 데이터에 접근한다.
//태그 수 만큼 반복
for(idx in 0 until METATag.length){
//idx번째 태그 객체 가져온다
val METAElement = METATag.item(idx) as Element
//META 태그 내에서 필요한 태그들을 가져온다.
val rawTextList = METAElement.getElementsByTagName("raw_text")
val latitudeList = METAElement.getElementsByTagName("latitude")
val rowTextTag = rawTextList.item(0) as Element
val latitudeTag = latitudeList.item(0) as Element
//태그 내의 데이터를 가져온다.
val rowText = rowTextTag.textContent
val latitude = latitudeTag.textContent.toDouble()
}
앞서 가져온 METAR 태그는 NodeList형이므로 리스트 크기만큼 순회하여 태그 객체를 받아 해당 객체 내의 데이터들을 가져온다.
이때, xml 문서에서 추출한 모든 데이터들은 문자열이므로 원하는 데이터 타입으로 변환해 사용하면 된다.
6) 데이터 출력
runOnUiThread {
textView.append("rowText : ${rowText}\n")
textView.append("latitude : ${latitude}\n")
}
서버에 데이터를 요청해 xml 문서를 파싱하는 과정은 메인 스레드에서 이루어졌지만, 데이터를 안드로이드 앱 내 UI 요소에 출력할 경우 UI 스레드를 이용해야 한다.
받아온 데이터를 텍스트 뷰에 출력했다.
2. JSON 데이터 가져오기
JSON은 JavaScript Object Notation의 약자로 자바스크립트에서 객체를 표현하는 문법을 사용해 데이터를 표현하는 문서이다.
JSON 문서는 다양한 데이터 타입을 표현할 수 있는데 정수, 실수, 문자열, 논리형과 더불어 객체와 배열도 표현한다.
1) ~ 3) 과정은 XML 데이터 가져오는 부분과 동일하다
4) 스트림 객체 생성
val inputStreamReader = InputStreamReader(httpURLConnection.inputStream, "UTF-8")
val bufferedReader = BufferedReader(inputStreamReader)
InputStreamReader는 httpURLConnection.inputStream을 통해 JSON 데이터를 읽어와 문자열로 변환한다.
이렇게 변환한 문자열을 BufferedReader를 통해 문자 스트림으로 변환한다.
5) 모든 데이터를 하나의 문자열로 변환
var str:String? = null
val stringBuffer = StringBuffer()
//문서의 마지막까지 읽어온다
do{
str = bufferedReader.readLine()
if(str!=null){
stringBuffer.append(str)
}
}while(str!=null)
val data = stringBuffer.toString()
bufferedReader에 저장된 문자 스트림을 한줄씩 읽어와 stringBuffer에 추가해 하나의 문자열로 만든다.
6) 데이터 추출
val root = JSONObject(data)
//count
val count = root.getInt("count")
runOnUiThread {
textView.text = "count : ${count}\n"
}
//country
val countryArray = root.getJSONArray("country")
for(idx in 0 until countryArray.length()){
//idx번째 JSONObject를 추출
val countryObject = countryArray.getJSONObject(idx)
//country_idx
val country_id = countryObject.getString("country_id")
runOnUiThread {
textView.append("country_id : ${country_id}\n\n")
}
}
우선 저장된 JSON 데이터를 살펴보면 최상위 JSON Object가 있고 하위에 정수형 데이터 count, 문자열 데이터 name, JSON Array country가 있다.
따라서 JSONObject를 생성해 root 변수에 담아주고, 각 데이터 타입에 맞게 값을 추출하기 위해 JSON Object의 메서드를 호출한다. (getInt, getString, getJSONArray등..)
JSON Array를 받아온 countryArray 변수는 0부터 1씩 증가하는 순서값을 가지기 때문에 순회를 통해 내부 데이터를 추출한다.
마찬가지로 UI thread를 사용해서 뷰에 데이터를 출력한다.
'Android > 개념' 카테고리의 다른 글
[Android] Activity 생명주기 (0) | 2023.07.23 |
---|---|
[Android] RecyclerView와 ViewHolder (0) | 2023.06.30 |
[Android] Button과 뷰 이벤트 (0) | 2023.06.26 |
[Android] ImageView (0) | 2023.06.20 |
[Android] ScrollView (0) | 2023.06.15 |