XML

3일차_DOM, 원격XML

알 수 없는 사용자 2015. 6. 22. 23:17

-----------------------------------------------------

원격 XML 데이터 읽기 (Java 프로그램)

- 기상청 육상 중기예보

http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109


stnId=108 (전국)

stnId=109 (서울, 경기)

stnId=105 (강원)

stnId=131 (충청북도)

stnId=133 (충청남도)

stnId=146 (전라북도)

stnId=156 (전라남도)

stnId=143 (경상북도)

stnId=159 (경상남도)

stnId=184 (제주특별자치도)



//WeatherData.java

package com.test;


import javax.xml.parsers.*;


import org.w3c.dom.*;


import java.net.URL;


import org.xml.sax.InputSource;


public class WeatherData {


public static void main(String[] args) {


//1. 원격 XML 정보를 요청하고, 그 결과를 메모리에 로드 -> XML DOM 형성

//2. 루트 엘리먼트 접근

//3. 특정 하위 엘리먼트 접근 -> 위치, 이름을 기준으로 접근

//4. 텍스트 노드(속성 노드)를 접근 -> 데이터 획득

//5. 결과 출력.

//rss(루트)->channel->item->description->body->location

//->city(서울)->data(12시간)

//->data->tmEf(날짜)

//->data->wf(날씨)

//->data->tmn(최저기온)

//->data->tmx(최고기온)

try {

//원격 XML 정보를 요청하고, 그 결과를 메모리에 로드

DocumentBuilderFactory factory 

= DocumentBuilderFactory.newInstance();

DocumentBuilder builder

= factory.newDocumentBuilder();

Document xmlObj = null;

String str = "http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109";

URL url = new URL(str);

InputSource is = new InputSource(url.openStream());

xmlObj = builder.parse(is);

//루트 엘리먼트 접근

Element root = xmlObj.getDocumentElement();

//System.out.println(root.getNodeName()); //rss

NodeList itemNodes = root.getElementsByTagName("item");

Node itemNode = itemNodes.item(0);

Element itemElement = (Element)itemNode;

System.out.println(getText(itemElement, "title"));

NodeList locationNodes = root.getElementsByTagName("location");

//System.out.println(locationNodes.getLength());  //4

Node locationNode = locationNodes.item(0);

Element locationElement = (Element)locationNode;

//System.out.println(getText(locationElement, "city")); //서울

NodeList dataNodes = locationElement.getElementsByTagName("data");

for (int i=0; i<dataNodes.getLength(); ++i) {

Node dataNode = dataNodes.item(i);

Element dataElement = (Element)dataNode;

System.out.printf("%s %s %s %s %n"

, getText(dataElement, "tmEf") //날짜

, getText(dataElement, "wf") //날씨

, getText(dataElement, "tmn") //최저기온

, getText(dataElement, "tmx") //최고기온

);

}

}catch(Exception e){

e.printStackTrace();

}

}

private static String getText(Element parent, String tagName) {

String result = "";

//특정 태그 이름을 가진 객체의 첫 번째 자식 노드를 얻는 과정

Node node = parent.getElementsByTagName(tagName).item(0);

Element element = (Element)node;

//특정 엘리먼트의 자식 노드(Text Node)의 값(nodeValue)를 얻는 과정

result = element.getChildNodes().item(0).getNodeValue();

return result;

}


}




-----------------------------------------------------

원격 XML 데이터 읽기 (Java 프로그램)

- RSS.xml 정보를 읽어내서 아래와 같이 출력하는 프로그램 작성

- http://rss.hankooki.com/daily/dh_it_tech.xml


//RSS.java

package com.test;


import java.net.URL;


import javax.xml.parsers.*;


import org.w3c.dom.*;

import org.xml.sax.InputSource;


public class RSS {


public static void main(String[] args) {

//1. 원격 XML 정보를 요청하고, 그 결과를 메모리에 로드 -> XML DOM 형성

//2. 루트 엘리먼트 접근

//3. 특정 하위 엘리먼트 접근 -> 위치, 이름을 기준으로 접근

//4. 텍스트 노드(속성 노드)를 접근 -> 데이터 획득

//5. 결과 출력.


try {


//원격 XML 정보를 요청하고, 그 결과를 메모리에 로드

DocumentBuilderFactory factory 

= DocumentBuilderFactory.newInstance();

DocumentBuilder builder

= factory.newDocumentBuilder();

Document xmlObj = null;

String str = "http://rss.hankooki.com/daily/dh_it_tech.xml";

URL url = new URL(str);

InputSource is = new InputSource(url.openStream());

xmlObj = builder.parse(is);

Element root = xmlObj.getDocumentElement(); // root 접근

NodeList channelNodes = root.getElementsByTagName("channel");

Node channelNode = channelNodes.item(0);

Element channelElement = (Element)channelNode;

System.out.println("--------------------------------------------------");

System.out.printf("title> %s %n", getText(channelElement, "title"));

System.out.printf("link> %s %n", getText(channelElement, "link"));

System.out.printf("description> %s %n%n",getText(channelElement, "description"));

System.out.println("주요 기사 ------------------------");

NodeList itemNodes = channelElement.getElementsByTagName("item");

for (int i=0; i<itemNodes.getLength(); i++) {

Node itemNode = itemNodes.item(i);

Element itemElement = (Element)itemNode;

System.out.printf("title> %s %n", getText(itemElement, "title"));

System.out.printf("link> %s %n", getText(itemElement, "link"));

System.out.printf("description> %s %n%n", getText(itemElement, "description"));

}

}catch(Exception e){

e.printStackTrace();

}


}

private static String getText(Element parent, String tagName) {

String result = "";

// 특정 태그 이름을 가진 객체의 첫 번째 자식 노드를 얻는 과정

Node node = parent.getElementsByTagName(tagName).item(0);

Element element = (Element) node;

// 특정 엘리먼트의 자식 노드(Text Node)의 값(nodeValue)를 얻는 과정

result = element.getChildNodes().item(0).getNodeValue();

return result;

}


}












-----------------------------------------------------

원격 XML 데이터 읽기 (JSP 프로그램)

- 기상청 육상 중기예보

http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109


stnId=108 (전국)

stnId=109 (서울, 경기)

stnId=105 (강원)

stnId=131 (충청북도)

stnId=133 (충청남도)

stnId=146 (전라북도)

stnId=156 (전라남도)

stnId=143 (경상북도)

stnId=159 (경상남도)

stnId=184 (제주특별자치도)



1. 프로그램 구성

//Weather.java -> 사용자 정의 자료형 클래스.

//WeatherDAO.java -> 날씨 정보 확인 액션 클래스.

//Weather.jsp -> 지역 선택. 서브밋 액션. 날씨 정보 확인 및 출력.


2. 프로그램 소스 코드

//Weather.java -> 사용자 정의 자료형 클래스.

package com.test;


//자료형 클래스

public class Weather {

//날짜, 날씨, 최저기온, 최고기온

private String tmEf, wf, tmn, tmx;


public String getTmEf() {

return tmEf;

}


public void setTmEf(String tmEf) {

this.tmEf = tmEf;

}


public String getWf() {

return wf;

}


public void setWf(String wf) {

this.wf = wf;

}


public String getTmn() {

return tmn;

}


public void setTmn(String tmn) {

this.tmn = tmn;

}


public String getTmx() {

return tmx;

}


public void setTmx(String tmx) {

this.tmx = tmx;

}

}








//WeatherDAO.java -> 날씨 정보 확인 액션 클래스.

package com.test;


import java.util.*;

import javax.xml.parsers.*;

import org.w3c.dom.*;

import java.io.*;

import java.net.URL;

import org.xml.sax.*;


public class WeatherDAO {

//메소드들 간에 데이터 공유->멤버변수 등록

private Document xmlObj = null;

public void init(String stnId) throws ParserConfigurationException, IOException, SAXException {

//문제)

//원격 XML 요청 액션 

//결과를 xmlObj 변수에 저장

DocumentBuilderFactory factory 

= DocumentBuilderFactory.newInstance();

DocumentBuilder builder

= factory.newDocumentBuilder();

String str = String.format("http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=%s",stnId); //"날씨 정보 요청URL";

//http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109

URL url = new URL(str);

InputSource is = new InputSource(url.openStream());

xmlObj = builder.parse(is);

}

public ArrayList<Weather> weatherList() {

ArrayList<Weather> result = new ArrayList<Weather>();

//문제)

//xmlObj 변수를 이용해서 XML 객체(엘리먼트) 분석

//날짜, 날씨, 최저기온, 최고기온 정보를 읽어내서

//컬렉션에 저장 및 반환

Element root = xmlObj.getDocumentElement();

NodeList weatherNodes = root.getElementsByTagName("location");

Node weatherNode = weatherNodes.item(0);

Element weatherElement = (Element)weatherNode;

NodeList dataNodes= weatherElement.getElementsByTagName("data");


for(int i=0; i<dataNodes.getLength(); ++i){


Node dataNode = dataNodes.item(i);

Element dataElement = (Element)dataNode;


Weather wt = new Weather();

wt.setTmEf(getText(dataElement,"tmEf"));

wt.setWf(getText(dataElement,"wf"));

wt.setTmn(getText(dataElement,"tmn"));

wt.setTmx(getText(dataElement,"tmx"));


result.add(wt);

}

return result;

}

public String getTitle() {

String result = "";

//문제)

//xmlObj 변수를 이용해서 XML 객체(엘리먼트) 분석

//타이틀 정보를 읽어내서

//result 변수에 저장 및 반환

       Element root = xmlObj.getDocumentElement();


       NodeList itemNodes = root.getElementsByTagName("item");

       Node itemNode = itemNodes.item(0);

       Element itemElement = (Element)itemNode;


       result = getText(itemElement, "title");   

      

return result;

}


private static String getText(Element parent, String tagName) {

String result = "";

//특정 태그 이름을 가진 객체의 첫 번째 자식 노드를 얻는 과정

Node node = parent.getElementsByTagName(tagName).item(0);

Element element = (Element)node;

//특정 엘리먼트의 자식 노드(Text Node)의 값(nodeValue)를 얻는 과정

result = element.getChildNodes().item(0).getNodeValue();

return result;

}


}








//Weather.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ page import="com.test.*" %>

<%

String stnId = request.getParameter("stnId");


String title = "";

StringBuilder sb = new StringBuilder();


if (stnId == null) {

stnId = "108"; //"전국" 날씨 기본값 처리

}


WeatherDAO dao = new WeatherDAO();

try {

dao.init(stnId); //XML 요청 액션 전용 메소드

title = dao.getTitle(); //타이틀 정보 요청 메소드

for (Weather w : dao.weatherList()) { //날씨 정보 요청 메소드

sb.append(String.format("<tr>"));

sb.append(String.format("<td>%s</td>", w.getTmEf()));

sb.append(String.format("<td>%s</td>", w.getWf()));

sb.append(String.format("<td>%s</td>", w.getTmn()));

sb.append(String.format("<td>%s</td>", w.getTmx()));

sb.append(String.format("</tr>"));

}

}catch(Exception e){

e.printStackTrace();

}


%>    

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>날씨 정보</title>


<link rel="stylesheet" type="text/css" href="TableStyle.css">

<link rel="stylesheet" type="text/css" href="DivStyle.css">


<script type="text/javascript">

window.onload=function() {

   var stnIds = document.getElementsByName("stnId");

   for (var i=0; i<stnIds.length; ++i) {

      var stnId = stnIds[i];

      if (stnId.value == "<%=stnId%>") {

         stnId.checked = true;

      }

   }

};

</script>


</head>

<body>

<div>

<div>

<h1>기상청 육상 중기예보</h1>

<h2>지역 선택</h2>

<form method="post">

<input type="radio" name="stnId" value="108"> 전국

<input type="radio" name="stnId" value="109"> 서울,경기

<input type="radio" name="stnId" value="105"> 강원

<input type="radio" name="stnId" value="131"> 충청북도

<input type="radio" name="stnId" value="133"> 충청남도

<br>

<input type="radio" name="stnId" value="146"> 전라북도

<input type="radio" name="stnId" value="156"> 전라남도

<input type="radio" name="stnId" value="143"> 경상북도

<input type="radio" name="stnId" value="159"> 경상남도

<input type="radio" name="stnId" value="184"> 제주특별자치도

<br>

<input type ="submit">

</form>

<h2>날씨 정보</h2>

<p>TITLE : <%=title%></p>

<table id="t01">

<tr>

<th>날짜</th><th>날씨</th>

<th>최저기온</th><th>최고기온</th>

</tr>

<%=sb.toString()%>

</table>

</div>


</div>

</body>

</html>





//요청주소

http://localhost:8090/프로젝트이름/Weather.jsp




------------------------------------------

팀별과제) RSS 정보 요청 JSP 페이지 작성할 것.


한국일보 - http://rss.hankooki.com/daily/dh_it_tech.xml

한겨레 - http://kr.hani.feedsportal.com/c/34762/f/640640/index.rss

조선일보 - http://www.chosun.com/site/data/rss/sports.xml

동아일보 - http://rss.donga.com/science.xml

노컷뉴스 - http://rss.nocutnews.co.kr/nocutnews.xml



//RSSInfo.java -> 자료형 클래스

//RSSDOM.java -> 액션 클래스. RSS 정보 요청 액션.


//RSSSend.jsp -> 주소 요청 페이지. 메인 페이지.

//RSSReceive.jsp -> 결과 출력 페이지




-----------------------------------------------