안드로이드 개발자의 창고
[52일차 Android] XML/JSON Parsing 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 XML Parsing
-
eXtensible Markup Language
-
데이터를 태그라는 것으로 묶어 관리하는 기법
- XML 문서에서 추출한 모든 데이터는 문자열이므로 적당한 타입으로 변환하여 사용해야 한다.
예제 코드
파싱에 사용할 XML 문서
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
// XML 파싱을 할 주소
val serverAddress = "https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25&stationString=KDE"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
activityMainBinding.run {
button.setOnClickListener {
thread {
// 접속 주소를 관리하는 객체 생성
val url = URL(serverAddress)
// 접속
val httpUrlConnection = url.openConnection() as HttpURLConnection
// 웹 브라우저 종류를 확인할 수도 있기 때문에
httpUrlConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
// DOM 방식으로 XML 문서를 분석할 수 있는 도구 생성
val documentBuilderFactory = DocumentBuilderFactory.newInstance()
val documentBuilder = documentBuilderFactory.newDocumentBuilder()
// 분석 도구를 이용해 XML 문서를 분석하여 각 태그들을 모두 객체로 생성한다.
// 태그들을 관리하는 객체를 반환한다.
val document = documentBuilder.parse(httpUrlConnection.inputStream)
// 최상위 태그를 가져온다.
val root = document.documentElement
// data tag를 가져온다.
val dataTag = root.getElementsByTagName("data")
// METAR tag를 가져온다.
val dataElement = dataTag.item(0) as Element
val METATag = dataElement.getElementsByTagName("METAR")
runOnUiThread {
textView.text = ""
}
// 태그의 수 만큼 반복한다.
for (idx in 0 until METATag.length){
// idx번째 태그 객체를 가져온다.
val METAElement = METATag.item(idx) as Element
// METAR 태그 내에서 필요한 태그들을 가져온다.
val rawTextList = METAElement.getElementsByTagName("raw_text")
val stationIdList = METAElement.getElementsByTagName("station_id")
val latitudeList = METAElement.getElementsByTagName("latitude")
val longitudeList = METAElement.getElementsByTagName("longitude")
val rowTextTag = rawTextList.item(0) as Element
val stationIdTag = stationIdList.item(0) as Element
val latitudeTag = latitudeList.item(0) as Element
val longitudeTag = longitudeList.item(0) as Element
// 질문 내의 데이터를 가져온다.
val rowText = rowTextTag.textContent
val stationId = stationIdTag.textContent
val latitude = latitudeTag.textContent.toDouble()
val longitude = longitudeTag.textContent.toDouble()
runOnUiThread {
textView.append("rowText : ${rowText}\n")
textView.append("stationId : ${stationId}\n")
textView.append("latitude : ${latitude}\n")
textView.append("longitude : ${longitude}\n\n")
}
}
}
}
}
}
}
📖 JSON Parsing
- JavaScript Object Notation의 약자
- JavaScript 언어에서 객체를 표현하는 문법을 사용해 데이터를 표현하는 비표준 문서
- 다양한 데이터 타입 표현 가능
JSON 데이터 분석
- { } : JSONObject, 이름 - 값 형태
- [ ] : JSONArray, 0부터 1씩 증가하는 순서값을 가지고 관리
예제 코드
파싱할 JSON 문서
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
// 사용할 JSON 문서 주소
val serverAddress = "https://api.nationalize.io/?name=michael"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
activityMainBinding.run{
button.setOnClickListener {
thread {
// URL 객체 생성
val url = URL(serverAddress)
// 접속 후 스트림 추출
val httpURLConnection = url.openConnection() as HttpURLConnection
val inputStreamReader = InputStreamReader(httpURLConnection.inputStream, "UTF-8")
val bufferedReader = BufferedReader(inputStreamReader)
var str:String? = null
val stringBuffer = StringBuffer()
// 문서의 마지막까지 읽어온다.
do{
str = bufferedReader.readLine()
if(str != null){
stringBuffer.append(str)
}
}while(str != null)
val data = stringBuffer.toString()
runOnUiThread {
textView.text = ""
}
// 최상위가 { }이므로 JSONObject를 생성한다.
val root = JSONObject(data)
// count
val count = root.getInt("count")
// name
val name = root.getString("name")
runOnUiThread {
textView.text = "count : ${count}\n"
textView.append("name : ${name}\n")
}
// country
val countryArray = root.getJSONArray("country")
for(idx in 0 until countryArray.length()){
// idx번째 JSONObject 추출
val countryObject = countryArray.getJSONObject(idx)
// country_id 추출
val country_id = countryObject.getString("country_id")
// probability 추출
val probability = countryObject.getDouble("probability")
runOnUiThread {
textView.append("country_id : ${country_id}\n")
textView.append("probability : ${probability}\n\n")
}
}
}
}
}
}
}