마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

실무에서 XmlPullParser 많이 쓰이나요?

0 추천

앱 개발 중 궁금해서 여쭤봅니다 xml 파싱중 성공하고 젤 쉬운 방법이 XmlPullParser인데

retrofit이 좋다고 들어서 XmlPullParser은 어떤지 궁금합니다

당당 (810 포인트) 님이 2020년 12월 17일 질문

2개의 답변

0 추천
 
채택된 답변
simplexml parser외의 라이브러리는 Retrofit adapter를 만드셔야 할 것 같은데요.

https://riptutorial.com/android/example/18965/retrofit-2-custom-xml-converter

위의 링크를 보면 다른 라이브러리를 이용해서 adapter를 만드는 예제가 있습니다. 해당 코드를 참고하면 다른 xml parser 또한 사용하기가 쉽겠네요.
spark (227,530 포인트) 님이 2020년 12월 18일 답변
당당님이 2020년 12월 18일 채택됨
답변 감사합ㄴ다! 혹시 둘 중 실무에서 많이 쓰이는 게 어떤 것일까요? xml도 요즘은 안쓴다고는 하는데 취업대비 앱 개발 중이라 궁금해서 답변 남깁니다
한국의 현업 상황이 어떤지는 제가 몰라서 말씀 드릴 수가 없지만, REST API를 쓴다면 대부분은 JSON형태로 포맷을 쓸거라고 봅니다. 그리고 모바일이나 웹 같은 클라이언트와 통신할 때는 XML을 사용하는 경우는 아주 드물 거라고 봅니다. 모발일 통신에 xml을 사용하는 건 기본적으로 JSON에 비해서 무거워요.
그리고 많이 쓰는 거 보다도, 본인이 직접 테스트 해보시면서 님의 상황에 더 적합하다고 여겨지는 걸 골라 쓰시면 될 듯합니다.
0 추천

SimpleXmlParser를 지난번에 소개했는데, 잘 안되시나보네요.
제가 테스트해보니, SimpleXmlParser로 코로나19 정보 파싱 매우 잘 됩니다.
윗분의 말처럼, json이 일반적입니다.
그러나 공공데이터API에서 코로나19 정보를 xml로만 주기 때문에
별도 파서를 추가하기 보다는, SimpleXmlParser를 사용하는게
말그대로 가장 심플하죠.

아래와 같이 구현이 가능합니다.

import android.util.Log;

import com.appcognito.retrofit.api.models.SidoInfo;

import okhttp3.OkHttpClient;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.Query;

public class Covid19 {
    private String serviceKey = "여기에 키를 넣는데, 사이트에서 준 urlencoded된 키를 decode해서 넣어야 합니다. 실행시 urlencoding 되기 때문입니다. 쉽게 이야기하면, 문자열에 %가 들어가 있으면 안됩니다.";

    public void getSidoInfo() {
        try {

            // base url - url of web site
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://openapi.data.go.kr/")
                    .client(new OkHttpClient())
                    .addConverterFactory(SimpleXmlConverterFactory.create())
                    .build();

            ApiDataInterface apiService = retrofit.create(ApiDataInterface.class);


            Call<SidoInfo> call = apiService.getData(serviceKey, 10, 1, "20201201", "20201210");
            call.enqueue(new Callback<SidoInfo>() {

                @Override
                public void onResponse(Call<SidoInfo> call, Response<SidoInfo> response) {
                    SidoInfo resp = response.body();
                    Log.e("Response success", response.message());

                }

                @Override
                public void onFailure(Call<SidoInfo> call, Throwable t) {
                    Log.e("Response fail", t.getMessage());
                }
            });

        } catch (Exception e) {
            Log.e("Exception", e.getMessage());
        }
    }

    public interface ApiDataInterface{
        @GET("openapi/service/rest/Covid19/getCovid19SidoInfStateJson")
        @Headers({"Accept: application/xml"})
        Call<SidoInfo> getData(@Query("serviceKey") String serviceKey,
                               @Query("numOfRows") int numOfRows,
                               @Query("pageNo") int pageNo,
                               @Query("startCreate_dt") String startCreate_dt,
                               @Query("endCreateDt") String endCreateDt);
    }


}

아래가 데이터 클래스 파일입니다.

import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

import java.util.List;

@Root(name="response", strict = false)
public class SidoInfo {
    @Element(name="header")
    public Header header;
    @Element(name="body")
    public SidoBody body;

    @Root(name="header", strict = false)
    public static class Header {
        @Element(name = "resultCode")
        public String resultCode;
        @Element(name = "resultMsg")
        public String resultMsg;
    }

    @Root(name="body", strict = false)
    public static class SidoBody {
        @ElementList(entry = "items")
        public List<SidoItem> items;
        //    public SidoList items;
        @Element(name="numOfRows")
        public String numOfRows;
        @Element(name="pageNo")
        public String pageNo;
        @Element(name="totalCount")
        public String totalCount;

    }

    @Root(name="item", strict = false)
    public static class SidoItem {
        @Element(name = "createDt", required = false)
        public String createDt;
        @Element(name = "deathCnt", required = false)
        public String deathCnt;
        @Element(name = "defCnt", required = false)
        public String defCnt;
        @Element(name = "gubun", required = false)
        public String gubun;
        @Element(name = "gubunCn", required = false)
        public String gubunCn;
        @Element(name = "gubunEn", required = false)
        public String gubunEn;
        @Element(name = "incDec", required = false)
        public String incDec;
        @Element(name = "isolClearCnt", required = false)
        public String isolClearCnt;
        @Element(name = "isolIngCnt", required = false)
        public String isolIngCnt;
        @Element(name = "localOccCnt", required = false)
        public String localOccCnt;
        @Element(name = "overFlowCnt", required = false)
        public String overFlowCnt;
        @Element(name = "qurRate", required = false)
        public String qurRate;
        @Element(name = "seq", required = false)
        public String seq;
        @Element(name = "stdDay", required = false)
        public String stdDay;
        @Element(name = "updateDt", required = false)
        public String updateDt;

    }
}


 

편하게 하기 위해서 하나의 파일에 넣었습니다.

실제로는 각 클래스를 따로 분리해서 사용하는게 좋습니다.
저는 일부러 합쳤네요. 합칠때는 클래스에 static 을 넣어야 하고요.
분리할 때는 static을 빼주세요.

그리고 데이터가 null로 올 경우에는 required = false 체크를 하면 됩니다.

호출할 때는 Activity나 Fragment에서 아래와 같이 하세요.
ServiceKey 때문에, 클래스에 문제가 있는 줄 알고 생각보다 오래걸렸네요..

Covid19 covid19 = new Covid19();
covid19.getSidoInfo();
Will Kim (43,170 포인트) 님이 2020년 12월 22일 답변
제가 테스트하느라고 날짜와 페이징 정보를 하드코딩했는데,
실제로 구현하실 때는 getSidoInfo()에 파라미터를 추가하셔서 던져서 처리하면 됩니다.
음.. 그 이전 질문을 못봤네요.
simple xml converter가 deprecated군요.
더 이상 지원을 안한다고 합니다.
미래를 위해서 다른 컨버터를 활용하시는게 나을 듯 싶습니다.
질문을 제대로 이해해야 제대로된 답변을 하는데,
시간을 들였음에도 무모한 답변을 추가로 했네요~

다양한 컨버터가 있으니, 시도해 보세요~~
헉 ㅠㅠ꼼꼼하게 알려주시려고 해서 감사합니다
제가 아직 공부하는 입장이다보니 헷갈리고 정보가 부족해서 이것저것
물어봤는데 덕분에 또 배워가네요
위에서 구현해 주신 부분도 제가  모르는 부분이라 구현하면서 한번 공부해보겠습니다
제가 정보가 정말 없는데 자세하게 알려주시려고 해주셔서 감사합니다!
...