블로그 이미지
Kanais
Researcher & Developer 퍼즐을 완성하려면 퍼즐 조각들을 하나 둘씩 맞춰나가야 한다. 인생의 퍼즐 조각들을 하나 둘씩 맞춰나가다 보면 인생이란 퍼즐도 완성되는 날이 오려나...?

calendar

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

Notice

03-29 13:04

Recent Post

Recent Comment

Recent Trackback

Archive

2016. 6. 22. 19:49 Programming/Android



 운영체제 : Windows 8.1 64bit

 개발툴 : Android Studio 1.5

 SDK Version : Min 21, Max 23

 작성날짜 : 2016-06-22




참고 : IT Reading - 안드로이드에서 xml 데이터 객체로 바꾸기


기상청 RSS 정보 파일을 사용하기 위해 Xml 파서를 구현하고 정리를 합니다.


기상청 RSS 정보 파일은 Xml로 되어 있으며, 안드로이드에서 사용하기 위해선 Xml 파서를 구현해야합니다.


xml을 다운받아 파일로 저장한 후 파서에서 파일을 읽고 파싱하는 구조로 구현하였습니다.



아래 url은 부여군 부여읍 rss날씨 를 받을 수 있는 url

다른 지역은 다음 페이지에서 링크를 얻을 수 있습니다.



기상청 RSS Xml 파일

일단 data 태그가 여럿있지만... 블로깅을 위해 한개만 올렸습니다.


<rss version="2.0">

<channel>

<title>기상청 동네예보 웹서비스 - 충청남도 부여군 부여읍 도표예보</title>

<link>http://www.kma.go.kr/weather/main.jsp</link>

<description>동네예보 웹서비스</description>

<language>ko</language>

<generator>동네예보</generator>

<pubDate>2016년 06월 22일 (수)요일 11:00</pubDate>

<item>

<author>기상청</author>

<category>충청남도 부여군 부여읍</category>

<title>동네예보(도표) : 충청남도 부여군 부여읍 [X=59,Y=99]</title>

<link>

http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=4476025000

</link>

<guid>

http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=4476025000

</guid>

<description>

<header>

<tm>201606221100</tm>

<ts>3</ts>

<x>59</x>

<y>99</y>

</header>

<body>

<data seq="0">

<hour>15</hour>

<day>0</day>

<temp>29.0</temp>

<tmx>30.0</tmx>

<tmn>-999.0</tmn>

<sky>4</sky>

<pty>1</pty>

<wfKor>비</wfKor>

<wfEn>Rain</wfEn>

<pop>60</pop>

<r12>0.0</r12>

<s12>0.0</s12>

<ws>2.0</ws>

<wd>2</wd>

<wdKor>동</wdKor>

<wdEn>E</wdEn>

<reh>60</reh>

<r06>1.0</r06>

<s06>0.0</s06>

</data>

</body>

</description>

</item>

</channel>

</rss> 



WeatherData.java
parser에서 저장할 데이터 클래스

public class WeatherData {
private double current_temp;
private double high_temp;
private double low_temp;
private String weather_code;
private String weather_desc;

public WeatherData(){
this.setCurrent_temp(-999.0);
this.setHigh_temp(-999.0);
this.setLow_temp(-999.0);
this.setWeather_code(null);
this.setWeather_desc(null);
}

public WeatherData(double current_temp, double high_temp, double low_temp, String weather_code, String weather_desc){
this.setCurrent_temp(current_temp);
this.setHigh_temp(high_temp);
this.setLow_temp(low_temp);
this.setWeather_code(weather_code);
this.setWeather_desc(weather_desc);
}

public double getCurrent_temp() {
return current_temp;
}

public void setCurrent_temp(double current_temp) {
this.current_temp = current_temp;
}

public double getHigh_temp() {
return high_temp;
}

public void setHigh_temp(double high_temp) {
this.high_temp = high_temp;
}

public double getLow_temp() {
return low_temp;
}

public void setLow_temp(double low_temp) {
this.low_temp = low_temp;
}

public String getWeather_code() {
return weather_code;
}

public void setWeather_code(String weather_code) {
this.weather_code = weather_code;
}

public String getWeather_desc() {
return weather_desc;
}

public void setWeather_desc(String weather_desc) {
this.weather_desc = weather_desc;
}
}




WeatherParser.java

저장된 xml 파일을 파싱하기 위한 클래스



public class WeatherParser {

    private static final String TAG "WeatherParser";

    public static 
ArrayList<WeatherData> getDatafromFile( String path )    {
        File xmlFile = 
new File(path);

        if
( !xmlFile.exists() ){
            Log.d(
TAG"!xmlFile.exists()");
            return null;
        
}
        Log.d(
TAG"xml data exist");

        try
{
            FileInputStream fis = 
new FileInputStream(xmlFile);
            return 
parse(fis);

        
}catch(Exception e)
        {
            Log.d(
TAG"error parsing");

            
StringWriter sw = new StringWriter();
            
e.printStackTrace( new PrintWriter(sw));
            
String exceptionAsString = sw.toString();

            
Log.e(TAGexceptionAsString);

            return null;
        
}
    }

    
static ArrayList<WeatherData> parse( InputStream in )

          throws XmlPullParserException, IOException
    {
        ArrayList<WeatherData> m_data =
new ArrayList<>();
        try
{
            XmlPullParser parser = Xml.newPullParser()
;
           
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            
parser.setInput(in, null);
            if
(parser.getEventType() != XmlPullParser.END_TAG){
                parser.nextTag()
;
           
}
           
m_data = readFeed(parser);

       
}finally{
            in.close()
;
       
}
       
return m_data;
   
}


   
static private ArrayList<WeatherData> readFeed( XmlPullParser parser)

          throws XmlPullParserException, IOException
    {
        ArrayList<WeatherData> entries =
new ArrayList<>();
       
parser.require(XmlPullParser.START_TAG, null, "rss");
       
Log.d(TAG, "TAG Name : " + parser.getName());
       
//parser.require(XmlPullParser.START_TAG, null, "channel");
       
boolean done = false;
        int
eventType = parser.getEventType();

        double
current_temp = 0.0;
        double
high_temp = 0.0;
        double
low_temp = 0.0;
       
String weather_code = null;
        
String weather_desc = null;

        while
(eventType != XmlPullParser.END_DOCUMENT && !done){
            String name =
null;
            switch
(eventType){
               
case XmlPullParser.START_DOCUMENT:
                   
// 스트림의 시작입니다. 리스트를 생성합니다.
                   
break;
                case
XmlPullParser.START_TAG:
                   
// 태그를 식별한 뒤 태그에 맞는 작업을 수행합니다.
                   
name = parser.getName();
                    if
(name.equals("temp")) current_temp = readCurrentTemp(parser);
                    else if
(name.equals("tmx")) high_temp = readHighTemp(parser);
                    else if
(name.equals("tmn")) low_temp = readLowTemp(parser);
                    else if
(name.equals("wfKor")) weather_code = readWeatherCode(parser);
                    break;
                case
XmlPullParser.END_TAG:
                   
// 태그의 마지막을 읽었습니다. ITEM을 처리하는 중이면 리스트에 Message를 추가합니다.
                   
name = parser.getName();
                    if
(parser.getName().equals("data")){
                        entries.add(
new WeatherData(current_temp, high_temp, low_temp, weather_code, weather_desc));
                   
}
                   
break;
           
}
            eventType = parser.next()
;
       
}
       
return entries;

    } 



XmlDownloader.java

기상청 rss 정보 파일을 다운로드하는 클래스

public class XmlDownloader extends AsyncTask<String, Void, Void> {

private static final String TAG = "xmlDownLoader";

String appPath;
AysnkTaskSynkListener listener = null;

public XmlDownloader(Context context) {
appPath = context.getApplicationContext().getFilesDir().getAbsolutePath();
}

@Override
protected Void doInBackground(String... params) {
String url = params[0];
String table_name = params[1];
Download(url, table_name);

return null;
}

protected void onPreExecute()
{

}

protected void onPostExecute( Void result )
{
if( listener != null ) listener.onPostExcute();
}

void Download(String urlAddr, String dbTableName)
{
URL url = null;
try {

url = new URL( urlAddr );

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setRequestMethod("GET");

urlConnection.setDoOutput(true);
urlConnection.connect();

File file = new File(appPath + "/" + dbTableName + ".xml");
if( file.exists() )
{
file.delete();
}

file.createNewFile();

FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();

int totalSize = urlConnection.getContentLength();

int downloadedSize = 0;

byte[] buffer = new byte[1024];
int bufferLength = 0;

while((bufferLength = inputStream.read(buffer)) > 0 )
{
fileOutput.write(buffer, 0, bufferLength);

downloadedSize += bufferLength;
int progress = (int)(downloadedSize * 100 / totalSize);
}
fileOutput.close();
}catch(Exception e)
{
Log.d(TAG, "fail to download / execption : " + e.getMessage());
}
}


public void SetOnPostExcuteListenrer( AysnkTaskSynkListener _listener )
{
listener = _listener;
}

public interface AysnkTaskSynkListener
{
public void onPostExcute();
}

}


MainActivity.java

XmlDownloader 와 WeatherParser를 사용하는 메인 클래스 안에서 사용하는 부분입니다.

private void Init_weather() {
Log.d(TAG, "Init_weather");
tv_currentTemp = (TextView)findViewById(R.id.main_weather_temperature);
tv_higlowTemp = (TextView)findViewById(R.id.main_weather_highlowtemp);
tv_weatherDesc = (TextView)findViewById(R.id.main_weather_desc);
iv_weather = (ImageView)findViewById(R.id.iv_weather);

xmlDownloader = new XmlDownloader(this);
xmlDownloader.SetOnPostExcuteListenrer(this);
xmlDownloader.execute("http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=4476025000", "weatherdata");
}

private String getWeatherDesc(String weather_code){
String s = " ";
switch (weather_code) {
case "맑음": s = getResources().getString(R.string.mainactivity_weather_clear); break;
case "구름 조금": s = getResources().getString(R.string.mainactivity_weather_partlycloude); break;
case "구름 많음": s = getResources().getString(R.string.mainactivity_weather_mostlycloudy); break;
case "흐림": s = getResources().getString(R.string.mainactivity_weather_cloudy); break;
case "비": s = getResources().getString(R.string.mainactivity_weather_rain); break;
case "눈/비": s = getResources().getString(R.string.mainactivity_weather_snowrain); break;
case "눈": s = getResources().getString(R.string.mainactivity_weather_snow); break;
default: s = getResources().getString(R.string.mainactivity_weather_none); break;
}
return s;
}

private Drawable getWeatherIconId(String weather_code){
Drawable weather_icon_id;
switch (weather_code) {
case "맑음": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon01); break;
case "구름 조금": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon02); break;
case "구름 많음": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon03); break;
case "흐림": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon04); break;
case "비": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon05); break;
case "눈/비": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon06); break;
case "눈": weather_icon_id = getResources().getDrawable(R.drawable.weather_icon07); break;
default: weather_icon_id = getResources().getDrawable(R.drawable.weather_icon08); break;
}
return weather_icon_id;
}

@Override
public void onPostExcute() {
String appPath = this.getApplicationContext().getFilesDir().getAbsolutePath();
ArrayList<WeatherData> weather_data = WeatherParser.getDatafromFile(appPath + "/weatherdata.xml");

if(weather_data != null){
Log.d(TAG, "weather_data != null");
assert tv_currentTemp != null;
String cur_temp = weather_data.get(0).getCurrent_temp() + "";
tv_currentTemp.setText(cur_temp);

assert tv_higlowTemp != null;
double high_temp_d = weather_data.get(0).getHigh_temp();
String high_temp;
if(high_temp_d == -999.0) high_temp = "-";
else high_temp = high_temp_d + "";

double low_temp_d = weather_data.get(0).getLow_temp();
String low_temp;
if(low_temp_d == -999.0) low_temp = "-";
else low_temp = low_temp_d + "";

String temp = high_temp + "/" + low_temp;
tv_higlowTemp.setText(temp);

assert tv_weatherDesc != null;
temp = getWeatherDesc(weather_data.get(0).getWeather_code());
tv_weatherDesc.setText(temp);

assert iv_weather != null;
iv_weather.setImageDrawable(getWeatherIconId(temp));
}

}







posted by Kanais