'파싱'에 해당되는 글 3

  1. 2014.03.21 기본적인 JSONObject, JSONArray 사용법 (3)
  2. 2014.02.20 XmlPullParser 사용하기
  3. 2013.07.24 XmlPullParser를 이용한 파싱 예제 (2)

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


JSONObjectJSON형태의 데이터를 관리해 주는 메서드이다.

주의점은 맵의 특성으로 인해 순서를 보장하지 않는다는것. 즉 똑같이 뽑아내도 내용물의 순서가 섞일 수 있다.



간단한 사용법은 다음과 같다.


먼저 제이슨 생성 후 데이터 집어넣기


JSONObject obj = new JSONObject();

obj.put("이름","덩치");

obj.put("거주지","서울");


출력해보면


String data = obj.toString();

System.out.println(data);


결과값 - {"이름":"덩치","거주지":"서울"} 

이렇게 표시된다.


키값에 해당하는 벨류만 뽑고싶다면

String data = obj.get("key");

하면 "key"에 해당하는 벨류를 반환한다.



JSON형태의 StringJSONobject에 넣는법은


String data = {"이름":"덩치","거주지":"서울"};

(실제로는 자바에서는 "를 못읽기때문에  String data = "{\"이름\":\"덩치\",\"거주지\":\"서울\"}";  이런식으로 해줘야 될것임)

JSONObject obj = new JSONObject(data);

쓸때는 위와 같이 뽑아서 사용하면 된다.



JSONArray 는 JSONObject가 들어가는 배열이라고 보면 된다.


예제를 먼저 보자

- 예제출처 : (http://aroundck.tistory.com/215)


String Json = "[{\"Product\" : \"Mouse\", \"Maker\":\"Samsung\", \"Price\":23000},"
               + "{\"Product\" : \"KeyBoard\", \"Maker\":\"LG\", \"Price\":12000},"
               + "{\"Product\":\"HDD\", \"Maker\":\"Western Digital\", \"Price\":156000}]";
try{
   String result = "";
   JSONArray ja = new JSONArray(Json);
   for (int i = 0; i < ja.length(); i++){
      JSONObject order = ja.getJSONObject(i);
      result += "product: " + order.getString("Product") + ", maker: " + order.getString("Maker") +
                  ", price: " + order.getInt("Price") + "\n";
   }
}
catch (JSONException e){ ;}


결과값 :   result : product: Mouse, maker: Samsung, price: 23000
product: KeyBoard, maker: LG, price: 12000
product: HDD, maker: Western Digital, price: 156000

이렇게 만들어진 JSONArray 객체를 JSONObject에 넣을 수 있으며

위와같은 방식으로 제이슨오브젝트에 그냥 오브젝트와 어레이를 모두 넣어가며
작업할 수 있다.






'Android > 입/출력' 카테고리의 다른 글

기본적인 JSONObject, JSONArray 사용법  (3) 2014.03.21
SharedPreferences 사용법을 알아보자.  (1) 2014.01.14
Android/소스코드 | Posted by 덩치 2014.02.20 09:07

XmlPullParser 사용하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO



Study_Parsing.zip


한경닷컴 뉴스 rss페이지를 파싱하여 출력하는 예제


퍼미션은 android.permission.INTERNET


예제를 실행시켜보고 소스를 뜯어보고


이해 안가는부분은 질문 주세요




Android/예제 | Posted by 덩치 2013.07.24 13:05

XmlPullParser를 이용한 파싱 예제

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

14년 1월 17일 수정내용 ----- 예제 프로젝트 실행이 안된다고 해서 알아보니 다른 패키지가 섞여있었네요.

weather 패키지 삭제한 상태이며 정상작동합니다.



net2.zip



사용한 기능 - XmlPullParser , AlertDialog 등등


매니패스트 퍼미션은 

<uses-permission android:name="android.permission.INTERNET"/>

추가입니다.


InputStreamReader로 웹사이트 내용을 읽어와 URL로 넘겨주고

XmlPullParser를 이용해 한경닷컴 뉴스 제목과 내용을 파싱



MainActivity.java


package com.example.net2;


import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.StringReader;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.ArrayList;


import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserFactory;


import android.app.Activity;

import android.app.AlertDialog;

import android.app.AlertDialog.Builder;

import android.content.DialogInterface;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.Toast;


public class MainActivity extends Activity {

private Builder listDialog;

EditText urltest;

String urlStr,tv,readLine,item;

String tagName,title,body,link = null;

ListView screen;

StringBuffer sb;

Button bt;

int eventType;

XmlPullParser xpp;

XmlPullParserFactory factory;

AlertDialog.Builder dialogBuilder;

ArrayList<String> arrList,arrList2;

ArrayAdapter<String> adapter,adapter2;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);

bt = (Button)findViewById(R.id.bt);

screen = (ListView)findViewById(R.id.screen);

urltest = (EditText)findViewById(R.id.urltest);


arrList = new ArrayList<String>();

arrList2 = new ArrayList<String>();

adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arrList);

screen.setAdapter(adapter);

dialog();

urltest.setOnLongClickListener(new View.OnLongClickListener() {

@Override

public boolean onLongClick(View arg0) { //주소창을 길게 터치하면 다이얼로그창 뷰

dialog();

return false;

}});

screen.setOnItemClickListener(new OnItemClickListener() {  //리스트 목록을 터치하면 이벤트 실행

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

dialogBuilder.setTitle(parent.getItemAtPosition(position).toString());

       dialogBuilder.setMessage(arrList2.get(position).toString());

       dialogBuilder.setPositiveButton("확인", null);

       dialogBuilder.show();

}});

bt.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

adapter.clear(); //어뎁터,리스트를 초기화시켜 새로운 데이터를 받음

arrList.clear();

adapter.notifyDataSetChanged(); //이까지. 초기화된걸 어뎁터로 리스트와 연결시켜줌

urlStr = urltest.getText().toString();

NetworkThread thread = new NetworkThread(); //스레드 선언과 호출

thread.setDaemon(true); //이거해줘야 종료될때 스레드가 죽는다는데 잘모르겠음

thread.start();

}});}


class NetworkThread extends Thread {

public void run() {

stream();

}}

Handler handler = new Handler(){

public void handleMessage(Message msg){

if(msg.what ==0){

adapter.notifyDataSetChanged();

}}};

public void parsing(){

try{

factory = XmlPullParserFactory.newInstance();

factory.setNamespaceAware(true);

xpp = factory.newPullParser();

xpp.setInput(new StringReader (tv.trim()));

eventType = xpp.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT){ //최초 title테그안에 쓸데없는 내용이 있어서 추가해줬음. 

if(eventType == XmlPullParser.START_TAG){             //ex)RSS 한경닷컴어쩌구저쩌구 제목과상관없는내용

String tagName2 = xpp.getName();

if(tagName2.equals("item")){ //아이템 테그 이후부터 검색시작

while (eventType != XmlPullParser.END_DOCUMENT){

if(eventType == XmlPullParser.START_TAG){ //스타트테그를 만나면 테그값 저장

tagName = xpp.getName();

}

else if(eventType == XmlPullParser.TEXT){ //스타트테그가 아니라 텍스트일경우

if(tagName!=null){ //텍스트가 쓰래기값인경우를 배제

if(tagName.equals("title")){ //필요한건 타이틀과 본문이기때문에 스타트테그는 타이틀일때 실행

title = xpp.getText().trim();

if (title.length() > 0) { //여기도 한경닷컴특성상 제목 \n 공백 \n 제목 이런식으로돼있어서 추가

arrList.add(title);

}

}else if(tagName.equals("description")){  //스타트테그가 타이틀이 아니라 본문이면 마찬가지로 수행

link = xpp.getText().trim();

if(link.length()>0){

arrList2.add(link);

}}}}

eventType = xpp.next();

}}}

eventType = xpp.next();

}

}catch (Exception e){}}

public void stream(){  //홈페이지 정보를 읽어들여 파서로 넘겨주기위한 매서드

HttpURLConnection urlConnection = null;

try {

URL url = new URL(urlStr);

urlConnection = (HttpURLConnection) url.openConnection(); //url 연결

InputStream in = urlConnection.getInputStream(); //url내용을 비트형으로읽어옴

InputStreamReader isr = new InputStreamReader(in); // 뭐더라 다시 리더로 변환해주는과정

BufferedReader buf = new BufferedReader(isr); //줄단위로 읽어주기위해 실행

sb = new StringBuffer(); //buf의 한줄 한줄 값을 입력받아 한꺼번에 출력시키기 위해 사용


while (true) {

readLine = buf.readLine();

if (readLine == null) //읽어올 값이 없으면

break; //멈춤 그렇지않으면

sb.append(readLine); //스트링버퍼에 리드라인 내용 계속 추가

sb.append("\n"); //이게없으면 줄바꿈이없어서 알아보기가힘듦. buf의 줄바꿈단위마다 실행

}

tv = sb.toString();

parsing();


handler.sendEmptyMessage(0); //핸들러호출

}

catch (Exception e) {

}

finally {

if (urlConnection != null) {

urlConnection.disconnect();

}}}

public void dialog(){ //다이얼로그 메시지 출력부

final String[] items = {"증권","경제/금융","부동산","산업","국제","정치","사회","스포츠/문화","사설/칼럼"}; //다이얼로그에 리스트 추가

listDialog = new AlertDialog.Builder(this); //다이얼로그 선언

listDialog.setTitle("목차").setItems(items, new DialogInterface.OnClickListener() { //다이얼로그 내에 items값을 갖는 리스트 추가

@Override

public void onClick(DialogInterface arg0, int val) {

// TODO Auto-generated method stub

Toast.makeText(MainActivity.this, "선택 : "+items[val], Toast.LENGTH_SHORT).show();

if(items[val].equals("증권")){  //리스트 내용을 클릭하면 그에 맞게 에디트뷰의 주소를 설정한대로 입력

urltest.setText("http://rss.hankyung.com/new/news_stock.xml");

}else if(items[val].equals("경제/금융")){  //여기서 equals로 비교하지 않고 인덱스를 받아서 하면 더 편리함

urltest.setText("http://rss.hankyung.com/new/news_economy.xml");

}else if(items[val].equals("부동산")){

urltest.setText("http://rss.hankyung.com/new/news_estate.xml");

}else if(items[val].equals("산업")){

urltest.setText("http://rss.hankyung.com/new/news_industry.xml");

}else if(items[val].equals("국제")){

urltest.setText("http://rss.hankyung.com/new/news_intl.xml");

}else if(items[val].equals("정치")){

urltest.setText("http://rss.hankyung.com/new/news_politics.xml");

}else if(items[val].equals("사회")){

urltest.setText("http://rss.hankyung.com/new/news_society.xml");

}else if(items[val].equals("스포츠/문화")){

urltest.setText("http://rss.hankyung.com/new/news_sports.xml");

}else if(items[val].equals("사설/칼럼")){

urltest.setText("http://rss.hankyung.com/new/news_column.xml");

}}

}).setNegativeButton("직접입력",null).show();

}}




activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
   <EditText
       android:id="@+id/urltest"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="http://rss.hankyung.com/new/news_economy.xml"
       android:layout_weight="4" />
   <Button
       android:id="@+id/bt"
       android:layout_width="150dp"
       android:layout_height="wrap_content"
       android:text="검색"
       android:layout_weight="1"/>
    </LinearLayout>
   
    <ListView
        android:id="@+id/screen"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>