3일차_DOM, 원격XML
-----------------------------------------------------
원격 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 -> 결과 출력 페이지
-----------------------------------------------