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

XmlPullParser 질문드립니다 ㅠㅠ

0 추천
안녕하세요 어플개발을 좋아하기만하는 초보개발자인데요 ㅠㅠ..
고등학교 어플리케이션을 만들려고 학교홈페이지에 잇는 급식을 파싱해서 어플에 맛깔나게 사용하고싶은데..
워낙초보라서 정말노력안한것처럼 보일수잇으시지만.. 일주일동안 파서예제만 계속보고 이게 어떤동작인지
공부를햇는데도 너무 어렵더라고요 ㅠㅠ 이게 학교홈페이지가 xml형식이아니라 html이라서 애가 잘안먹히는거같아요..
그래도 어찌어찌 이것저것 손봐서 여기까진왓는데 저기 출력까진 해결이됬습니다
그런데 파싱내용이 if문에서 갈라지는게 아니라 그대로 합쳐져서 나와서 미치겟습니다 ㅠㅠ
이걸 해결할수잇는 방법을 알려주시면 정말 감사드리겠습니다..
혹시 XmlPullParser말고도 더효과적인 방법  dom이나 sax htmlclean  jericho 말고 잇다면 알려주시길바랍니다 ㅠㅠ
 
 
 
 
package com.example.donggwanghighschool;
 
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
 
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
 
import android.R.string;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.NetworkOnMainThreadException;
import android.widget.TextView;
import android.widget.Toast;
 
public class FoodActivity extends Activity {
ProgressDialog mProgress;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.food);
mProgress = ProgressDialog.show(FoodActivity.this, "준비중","잠시만기달려주세요 ^^");
 
Calendar cal =Calendar.getInstance();
cal.setTime(new Date(System.currentTimeMillis()));
String date = new SimpleDateFormat("yyyy.MM.dd").format(cal.getTime());
//DownThread thread = new DownThread(urlAdd);
thread.start();
 
}
 
class DownThread extends Thread{
String mAddr;
 
public DownThread(String addr) {
mAddr = addr;
}
 
public void run(){
String result = DownloadHtml(mAddr);
Message message = mAfterDown.obtainMessage();
message.obj = result;
mAfterDown.sendMessage(message);
}
 
@SuppressLint("NewApi")
String DownloadHtml(String addr){
StringBuilder html = new StringBuilder();
try{
URL url = new URL(addr);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
if(conn != null){
conn.setConnectTimeout(10000);
conn.setUseCaches(false);
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(),"euc-kr"));
for(;;){
String line = br.readLine();
if(line == null)break;
html.append(line + '\n');
}
br.close();
}
conn.disconnect();
}
}catch (NetworkOnMainThreadException e){
return "Error : 메인 스레드 네트워크 작업 에러 - " +e.getMessage();
}catch(Exception e){
return "Error : " + e.getMessage();
}
return html.toString();
}
}
 
Handler mAfterDown = new Handler(){
public void handleMessage(Message msg){
mProgress.dismiss();
TextView result1 = (TextView)findViewById(R.id.TextViewFood01);
TextView result2 = (TextView)findViewById(R.id.TextViewFood02);
String html = (String)msg.obj;
boolean initem = false;
String ItemName01 = "";
String ItemName02 = "";
String str[] = new String[20];
int count = 1;
//result.setText(""+html);
try{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
parser.setInput(new StringReader(html));
 
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT){
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.END_DOCUMENT:
break;
case XmlPullParser.START_TAG:
if(parser.getName().equals("p")) initem = true;
break;
 
case XmlPullParser.END_TAG:
if(parser.getName().equals("p"))
initem = false;
 
 
}
break;
case XmlPullParser.TEXT:
if(initem){
if(count == 1){
ItemName01 += parser.getText();
 
}
else{
ItemName02 += parser.getText();
}
 
}
 
break;
 
}
eventType = parser.next();
 
}
ItemName01 = ItemName01.replace("평균점수:", "");
ItemName01 = ItemName01.replace("(명)", "");
ItemName01 = ItemName01.replace("이 페이지는 자바스크립트가 지원되지 않는 브라우저에서 일부 기능이 제대로 작동하지 않습니다.", "");
result1.setText(""+ ItemName01);
 
ItemName02 = ItemName02.replace("평균점수:", "");
ItemName02 = ItemName02.replace("(명)", "");
ItemName02 = ItemName02.replace("이 페이지는 자바스크립트가 지원되지 않는 브라우저에서 일부 기능이 제대로 작동하지 않습니다.", "");
result2.setText(""+ ItemName02);
}
catch(Exception e){
Toast.makeText(getApplicationContext(),e.getMessage(), 0).show();
}
}
};
 
 
 
 
 
}
 
 
 
 
 
코코아주스 (230 포인트) 님이 2013년 7월 25일 질문

4개의 답변

+1 추천
 
채택된 답변
만드시려는게, 급식 홈페이지의 내용을 긁어오시려는거 아닌가요?

급식 홈페이지는 HTML인데, XML파서를 써서 읽어오다뇨?

HTML에서 필요한 부분만 잘라와서 읽어오면 될 것 같은데...

홈페이지가 어떻게 생겼는지를 모르니...
mg2000 (2,640 포인트) 님이 2013년 7월 25일 답변
코코아주스님이 2013년 8월 5일 채택됨
네  급식홈페이지에 내용을 긁어서 필요한 부분만 깔끔하게 정리하고싶었는데.. 저기 보시면 홈페이지는 나와있습니다 주석을 걸어야 하는데 시간이없어서 ㅠㅠ 일단 댓글에 쓰고 한번확인해주시면 감사드리겠습니다..  
http://dong.hs.kr/?act=lunch.main2&month=2013.08.20&mcode=
굳이 파서를 어렵게 만드실 필요는 없다고 보고요.
중식의 경우
<div id="lunch" class="menuBox"> </div>
석식의 경우
<div id="dinner" class="menuBox"> </div>
로 구분되어 있는 것 같습니다.

아마도 html 코드를 가져오는 부분까지는 구현을 하셨을테고,
그렇다면, html코드에서
"<div id=\"lunch\" class=\"menuBox\">" 부분의 index를 찾아서 앞부분 날려 버리고...
필요한 내용은 중식 내용인데...
그 부분은 <p> </p>에 있는 내용 같습니다.
아까 앞부분 날리고 남은 내용중에,
가장 먼저 나오는 "<p>"부터, 가장 먼저 나오는 "</p>"까지 추출하시면, 중식 메뉴를 가져오실 수 있을겁니다.
("<br />"이야 "\n"으로 치환하시면 되고...)
석식도 비슷한 원리로 하시면 될테고요.

HTML는 Formatting을 위한 언어이기 때문에, XML처럼 태그를 분석해서는 원하는 데이터를 가져오기 힘들겁니다.
굳이 그렇게 하기 보다는 필요한 부분을 긁어오기 위한 특정 패턴(위에서 예를 든 <div id="lunch">같은 패턴) 을 찾아내시는게, 개발하시는데 훨씬 수월하실겁니다.

본인 학교의 앱을 개발하시려는건지?
고등학생이신데, 대단하네요.
모교을 위해 유용한 앱 만드시길...

p.s. string에서 index를 찾고, 문자열 추출은 하실 줄 아실 것이라보고.. ^^
우와 감사드립니다 ㅠㅠ 정말 요즘엔 중학생들도 잘만드는데 저는 왜이렇게 재능이없는거지 자학감도 들고있었는데 방법 알려주셔서 감사합니다! 바로 실천하고 성공하면 댓글남기게습니다 감사합니다!!!!
저도 고등학생때 게임 만들겠다고 이런 저런 삽질했던 시절이 생각나네요.
포기하지 않고 꾸준히 해보시길... ^^
저기 죄송합니다만 ㅠㅠ 한가지만 더질문드리겠습니다
시간이 되신다면 답변바랍니다..
제가 mg2000님 말씀대로 index위치를 찾은뒤 로
substring 1차적으로 크기를줄이고 1차적으로 줄인 String값에서 다시
substring을 사용하여 <p> </p>값을 찾은뒤 출력할려고햇습니다..
그런데 이게 실행해보면

length=15247; regionStart=-1; regionLenght=3364 라는 예외처리값이
뜨면서 실행이 되지않습니다.. 어떡해야지 될까요..문법에 오류가있는걸까요 ㅜㅜ 정말 죄송하지만 부탁드립니다..


Handler mAfterDown = new Handler(){
        public void handleMessage(Message msg){
            TextView result1 = (TextView)findViewById(R.id.TextViewFood01);
            //TextView result2 = (TextView)findViewById(R.id.TextViewFood02);
            String html = (String)msg.obj;
            try{
                int lunchpos01 = html.lastIndexOf("<menuName>");
                int lunchpos02 = html.indexOf("</div>");
                String ItemName01 = html.substring(lunchpos01,lunchpos02);
               
                int lunchpos03 = ItemName01.lastIndexOf("<p>");
                int lunchpos04 = ItemName01.indexOf("</p>");
                String ItemName02 = ItemName01.substring(lunchpos03,lunchpos04 );
               
                mProgress.dismiss();
                result1.setText(""+ItemName02);
           
               
            }
            catch(StringIndexOutOfBoundsException e){
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
       
    };
Exeption이 발생한 위치를 확인하려면 logcat을 확인해봐야 할텐데요.
제가보기에는 substring을 하면서 잘못 잘려나간게 아닌가 생각되는데,
Substring한걸 파일로 저장하던가 해서, 문자열 분할이 제대로 되었는지 확인해 보세요
아이고 죄송합니다 제가 이런게 처음이라 채택을 해야하는건지 몰랏네요ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ 뒤늦게 채택합니다 죄송합니다 ㅠㅠ 아그리고 mg2000님이 말씀하신대로 힌트를 활용해서 약간에? 삽질을 통해 해결되었습니다! 감사합니다 !
+1 추천

html 파서를 하시는거면 제리코 파서를 추천해드려요.

https://www.google.co.kr/?gws_rd=cr#newwindow=1&safe=off&output=search&sclient=psy-ab&q=android+jericho&oq=android+jericho&gs_l=hp.3..35i39l2j0l2.606.4537.0.5623.15.15.0.0.0.0.145.1301.12j3.15.0....0.0..1c.1j4.20.psy-ab.yy0ERk22GuE&pbx=1&bav=on.2,or.r_cp.r_qf.&bvm=bv.49784469%2Cd.aGc%2Cpv.xjs.s.en_US.MpiVkF51mpA.O&fp=ff58658cf56a1d0c&biw=1680&bih=989

구글 검색만 하셔도 사용방법은 많이 잘 나오니깐. xml파서로는 html 파싱하는거 자체가 굉장히 어려울거 같습니다.

덤으로 정규식도 같이 하시면 하실 수 있을거요.

gusdn9 (1,560 포인트) 님이 2013년 7월 25일 답변
0 추천
안녕하세요!

IF문이 안먹히는거라면, 경로를 로그로 한번 찍어보세요^^ 어떤 경로를 타고 나가는지..

그리고 저같은 경우는 XMLPullparser로 작업하는게 더 낫고 쉽던데요.

받아오신 xml을 hashmap이나 ArrayList에 담으셔서 작업하시는 편이 더 간단하고 나으실 듯 보입니다.

받아오신 값의 key값으로 구분하면, 더 간단하게 출력하실 수 있을 듯 합니다.

도움이 되시길 바랍니다.
안드로메다개발자 (8,830 포인트) 님이 2013년 7월 25일 답변
아아 감사합니다 ㅠㅠ 그런데 최적화시키는 방법보단 지금 제가 원하는 방향이 나오지않아서요.. 일단 말씀대로 로그를 찍고 다시 노력좀해보겠습니다 ㅠㅠ 감사합니다
0 추천
XML 이랑 HTML 이 형식이 다른건데..... -_-;;
건방진프로그래머 (26,630 포인트) 님이 2013년 7월 25일 답변
네 ㅠㅠㅠㅠㅠ 다른건 알고있지만 html파싱을 구글에 쳐도 위에 질문에 말씀드린 dom이나 sax htmlclean  jericho 이런거밖에 안나오는데 ㅠㅠㅠㅠ
책도 안드로이드정복 4.2버전 1,2권이랑 그림으로배우는 안드로이드서적에서도 xml에 관한것만나오고  html방법이 나오지않습니다 혹시 아신다면 설명글 링크나 방법좀 찾아서 알수잇을정도만 알으켜주시면 정말 감사드리겠습니다 ㅠㅠ
...