Archives
Recent Posts
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Today
Total
관리 메뉴

안드로이드 개발자의 창고

[52일차 Android] XML/JSON Parsing 본문

카테고리 없음

[52일차 Android] XML/JSON Parsing

Wise-99 2023. 7. 27. 18:42

 

 

 

출처 : 안드로이드 앱스쿨 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")
                        }
                    }
                }
            }
        }
    }
}