XPath 의 개요
■■■ XPath (XML Path Language) ■■■
○ XPath 개요
- XPath 는 XSLT 표준의 주요 요소이다.
- XPath 를 사용하여 XML 문서의 요소 및 속성을 탐색할 수 있다.
- XPath 는 경로 표현식을 활용하여 XML 문서에 노드를 식별하고 탐색한다.
- XPath 는 W3C 권장 사항이다.
○ XPath 의 경로 표현식 (XPath Path Expressions)
- XPath 는 경로 표현식을 사용하여 XML 문서에서 Node 또는 NodeSet(NodeList) 을 선택한다.
- 이러한 경로 표현식은 기존 파일 시스템에서 사용하는 경로 표현식과 매우 유사하다
○ XPath 의 표준 기능 (XPath Standard Functions)
- XPath 에는 200 개 이상의 내장 기능이 포함되어 있다.
- 문자열 값 (string value), 숫자 값(numeric values)
, 부울(booleans), 날짜 및 시간 비교(date and time comparison)
, 노드 조작(node manipulation), 시퀀스 조작(sequence manipulation) 등을 위한 기능이 있다.
- 현재 XPath 표현식은 Javascript, JAVA, XML 스키마, PHP, Python, C, C++ 및 기타 여러 언어에서도 사용할 수 있다.
○ XPath 주요 용어
- 노드
· XPath 에는 요소, 속성, 텍스트, 네임스페이스, 처리명령, 주석, 문서 이렇게 총 7가지 노드가 있다.
· XML 문서는 노드 트리로 다루어지며 트리의 최상위 요소를 루트 요소라고 한다.
- 원자값 (Atomic values)
· 원자 값은 자식이나 부모가 없는 노드이다.
- 아이템 (Items)
· 아이템(Items)은 원자값 또는 노드이다.
<bookstore> → <bookstore> → Node (root Element)
<book> → <book> → Node (element node)
<title lang="en">Harry Potter</title> → <title> → Node (element node)
--------- → lang="en" → Node (attribute node)
--------- → lang="en" → 원자 값(automic values)
<author>J K. Rowling</author>
------------ → J K. Rowling → 원자 값(automic values)
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
○ 노드의 관계 (Relationship of Nodes)
- 부모
- 자식
- 형제, 자매
- 선조, 조상
- 자손
○ 노드 선택 (Selection Nodes)
- XPath 는 경로 표현식을 사용하여 XML 문서에서 Node 를 선택한다
- 경로 또는 단계에 따라 Node 가 선택된다
=================== ===============================================================
Expression Description
=================== ===============================================================
nodename 이름이 "nodename" 인 모든 노드를 선택한다
------------------- ---------------------------------------------------------------
/ 루트 노드에서 선택한다
------------------- ---------------------------------------------------------------
// 현재 노드에서 선택한 위치에 상관없이 문서의 노드를 선택한다.
------------------- ---------------------------------------------------------------
. 현재 노드를 선택한다
------------------- ---------------------------------------------------------------
.. 현재 노드의 부모노드를 선택한다.
------------------- ---------------------------------------------------------------
@ 속성을 선택한다.
=================== ===============================================================
▼
=================== ===============================================================
Expression Description
=================== ===============================================================
bookstore 이름이 "bookstore" 인 모든 노드를 선택한다.
------------------- ---------------------------------------------------------------
/bookstore 루트 요소인 bookstore를 선택한다
이 때, 표현식으로 사용되는 경로가
『/』 로 시작하면 요소의 절대 경로를 나타낸다.
------------------- ---------------------------------------------------------------
bookstore/book bookstore 의 하위인 모든 book 요소를 선택한다.
------------------- ---------------------------------------------------------------
//book 문서 상 어느 위치에 존재하든 모든 book 요소를 선택한다.
------------------- ---------------------------------------------------------------
bookstore//book bookstore 의 하위 요소인 모든 book 요소를 선택한다.
------------------- ---------------------------------------------------------------
//@lang lang 이라는 모든 속성을 선택한다.
=================== ===============================================================
※ 경로 표현식의 추가 옵션
- 표현식 : /bookstore/book[1]
내용 : bookstore 요소의 하위 첫 번째 book 요소를 선택한다.
단, IE 5 ~ 9 브라우저에서 첫 번째 노드는 [0] 이다.
하지만, W3C 규칙을 준수하는 다른 브라우저에서 첫 번째 노드는 [1] 이다.
따라서 IE 에서 발생하는 이 문제를 해결하기 위해서는
SelectionLanguage 를 XPath 로 설정해야한다.
- 표현식 : /bookstore/book[last()]
내용 : bookstore 요소의 하위인 마지막 book 요소를 선택한다.
- 표현식 : /bookstore/book[position()<3]
내용 : bookstore 요소의 하위인 처음 두 개의 book 요소를 선택한다.
- 표현식 : //title[@lang]
내용 : lang 이라는 속성을 가진 모든 title 요소를 선택한다.
- 표현식 : //title[@lang='en']
내용 : lang 속성의 값이 en 인 모든 title 요소를 선택한다.
- 표현식 : /bookstore/book[price>35.00]
내용 : price 가 35.00 보다 큰 요소가 있는 bookstore 요소의 모든 book 요소를 선택한다.
XmlApp08 - 날씨 RSS
Weather.jsp - 뷰 페이지 구성 (정적 템플릿) WeatherInfo.jsp - 데이터 바인딩한 뷰 페이지
더보기
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Weather.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<!-- jQuery 추가 -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- 부트스트랩 CDN // 부가적 테마만 제외 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</head>
<body>
<!--
https://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 // 제주특별자치도
-->
<div class="container">
<h2>
기상 정보 <small>중기 예보</small>
</h2>
<div class="panel-group" role="group">
<div class="panel panel-default" role="group">
<div class="panel-heading">지역 선택</div>
<div class="panel-body">
<form method="get" role="form">
<input type="radio" name="stnId" value="108" checked="checked"> 전국
<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"> 충남
<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"> 제주특별자치도
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div><!-- close .panel-body -->
</div><!-- close. panel-default -->
<br>
<div class="panel panel-default" role="group">
<div class="panel-heading">기상 정보 출력 </div>
<div class="panel-body">
<p>
<b> 전국 육상 중기예보 - </b>
</p>
<p>
○ (강수) 29일..<br>
○ (기온) <br>
○ (주말전망) <br>
* 이번 예보기간에는..<br>
</p>
<h3>서울</h3>
<table class="table">
<thead>
<tr>
<th>날짜</th>
<th>날씨</th>
<th>최저/최고 기온</th>
<th>강수확률</th>
</tr>
</thead>
<tbody>
<tr>
<td>2023-07-29 00:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-30 00:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
</tbody>
</table>
<h3>인천</h3>
<table class="table">
<thead>
<tr>
<th>날짜</th>
<th>날씨</th>
<th>최저/최고 기온</th>
<th>강수확률</th>
</tr>
</thead>
<tbody>
<tr>
<td>2023-07-29 00:00</td>
<td><img src="images/NB08.png"/>흐리고 비</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-30 00:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
</tbody>
</table>
</div><!-- close .panel-body -->
</div><!-- close. panel-default -->
</div><!-- close .panel-group -->
</div>
</body>
</html>
<%@page import="com.test.xml.WeatherDTO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.test.xml.WeatherDAO"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<%
// 사용자가 선택한 지역 데이터 수신
String stnId = request.getParameter("stnId");
if (stnId==null) // 최초 요청일 때
stnId = "108"; //-- 전국 날씨 정보
StringBuffer sb = new StringBuffer();
WeatherDAO dao = new WeatherDAO(stnId);
// 타이틀
String title = dao.weatherTitle();
// 날씨 예보 개요
String weatherInfo = dao.weatherInfo();
// 도시 정보 및 날짜 시간 별 날씨 정보
ArrayList<String> cityList = dao.weatherCityList();
for (int i=0; i<cityList.size(); i++)
{
sb.append(String.format("<h3>%s</h3>", cityList.get(i)));
//-- 1 부터 시작!
ArrayList<WeatherDTO> weatherList = dao.weatherList(String.valueOf(i+1));
// 테이블 동적 생성
sb.append("<table class='table'>");
sb.append("<tr>");
sb.append("<th>날짜</th>");
sb.append("<th>날씨</th>");
sb.append("<th>최저/최고 기온</th>");
sb.append("<th>강수확률</th>");
sb.append("</tr>");
for (WeatherDTO w : weatherList)
{
sb.append("<tr>");
sb.append(String.format("<td>%s</td>", w.getTmEf())); // 날짜
sb.append(String.format("<td><img src='images/%s'>%s</td>", w.getImg(),w.getWf())); // 날씨
sb.append(String.format("<td>%s℃ / %s℃</td>", w.getTmn(), w.getTmx())); // 최저 / 최고 기온
sb.append(String.format("<td>%s%%</td>", w.getRnSt())); // 강수확률
sb.append("</tr>");
}
sb.append("</table>");
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WeatherInfo.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<!-- jQuery 추가 -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<!-- 부트스트랩 CDN // 부가적 테마만 제외 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function()
{
//확인
//alert("확인");
// 선택한 라디오 버튼의 상태를
// 요청 이후에도 선택된 상태로 유지할 수 있도록 처리
//$(":radio:eq(0)").attr("checked","checked"); //-- 전국
//$(":radio:eq(2)").attr("checked","checked"); //-- 강원
//$(":radio:eq(9)").attr("checked","checked"); //-- 제주
//$(":radio[value='109']").attr("checked","checked"); //-- 서울,경기
//$(":radio[value='131']").attr("checked","checked"); //-- 충북
//$(":radio[value='184']").attr("checked","checked"); //-- 제주
$(":radio[value='<%=stnId %>']").attr("checked","checked");
});
</script>
</head>
<body>
<div class="container">
<h2>
기상 정보 <small>중기 예보</small>
</h2>
<div class="panel-group" role="group">
<div class="panel panel-default" role="group">
<div class="panel-heading">지역 선택</div>
<div class="panel-body">
<!-- action 속성 지정 안함 → 요청페이지/데이터 수신처 는 자기자신 -->
<form method="get" role="form">
<label><input type="radio" name="stnId" value="108"> 전국 </label>
<label><input type="radio" name="stnId" value="109"> 서울, 경기 </label>
<label><input type="radio" name="stnId" value="105"> 강원 </label>
<label><input type="radio" name="stnId" value="131"> 충북 </label>
<label><input type="radio" name="stnId" value="133"> 충남 </label>
<label><input type="radio" name="stnId" value="146"> 전북 </label>
<label><input type="radio" name="stnId" value="156"> 전남 </label>
<label><input type="radio" name="stnId" value="143"> 경북 </label>
<label><input type="radio" name="stnId" value="159"> 경남 </label>
<label><input type="radio" name="stnId" value="184"> 제주특별자치도 </label>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div><!-- close .panel-body -->
</div><!-- close. panel-default -->
<br>
<div class="panel panel-default" role="group">
<div class="panel-heading">기상 정보 출력 </div>
<div class="panel-body">
<p>
<!-- <b> 전국 육상 중기예보 - </b> -->
<b> <%=title %> </b>
</p>
<p>
<!--
○ (강수) 29일..<br>
○ (기온) <br>
○ (주말전망) <br>
* 이번 예보기간에는..<br>
-->
<%=weatherInfo %>
</p>
<!--
<h3>서울</h3>
<table class="table">
<thead>
<tr>
<th>날짜</th>
<th>날씨</th>
<th>최저/최고 기온</th>
<th>강수확률</th>
</tr>
</thead>
<tbody>
<tr>
<td>2023-07-29 00:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-30 00:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
</tbody>
</table>
<h3>인천</h3>
<table class="table">
<thead>
<tr>
<th>날짜</th>
<th>날씨</th>
<th>최저/최고 기온</th>
<th>강수확률</th>
</tr>
</thead>
<tbody>
<tr>
<td>2023-07-29 00:00</td>
<td><img src="images/NB08.png"/>흐리고 비</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-30 00:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
<tr>
<td>2023-07-29 12:00</td>
<td><img src="images/NB03.png"/>구름많음</td>
<td>25 / 31</td>
<td>30</td>
</tr>
</tbody>
</table>
-->
<%=sb.toString() %>
</div><!-- close .panel-body -->
</div><!-- close. panel-default -->
</div><!-- close .panel-group -->
</div>
</body>
</html>
/*====================
WeatherDTO.java
=====================*/
package com.test.xml;
public class WeatherDTO
{
// 주요 속성 구성
private String tmEf, wf, tmn, tmx, rnSt, img;
//-- tmEf → 날짜와 시간 태그
// 2013-11-24 00:00
//-- wf → 날씨 예보 태그
// ○ 맑음
// ○ 구름조금
// ○ 구름많음, 구름많고 비, 구름많고 비/눈, 구름많고 눈/비,구름많고 눈
// ○ 흐림, 흐리고 비, 흐리고 비/눈, 흐리고 눈/비, 흐리고 눈
//-- tmn → 최저온도 태그
// (21 → 21℃) →『ㄹ』
//-- tmx → 최고온도 태그
// (30 → 30℃) →『ㄹ』
//-- rnSt → 강수확률 태그
// (40 → 40%)
//-- img → 날씨 예보에 따른 이미지
// getter / setter 구성
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;
}
public String getRnSt()
{
return rnSt;
}
public void setRnSt(String rnSt)
{
this.rnSt = rnSt;
}
public String getImg()
{
return img;
}
public void setImg(String img)
{
this.img = img;
}
}
/*============================================================================
WeatherDAO.java
- DAO 구성
- XML DOM 활용 → 원격 XML 읽어내기
(https://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108)
============================================================================ */
package com.test.xml;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath; //check
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; // check
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class WeatherDAO
{
// 주요 속성 구성 (공통 멤버)
private Document xmlObj;
private XPath xPath;
private HashMap<String, String> map;
// 생성자 정의 → 기본 생성자
public WeatherDAO() throws ParserConfigurationException, IOException, SAXException
{
this("108"); // 전국 기준
/*
stnId=108 // 전국
stnId=109 // 서울,경기
stnId=105 // 강원
stnId=131 // 충북
stnId=133 // 충남
stnId=146 // 전북
stnId=156 // 전남
stnId=143 // 경북
stnId=159 // 경남
stnId=184 // 제주특별자치도
*/
}
// 생성자 정의 → 매개 변수 있는 생성자
public WeatherDAO(String stnId) throws ParserConfigurationException, IOException, SAXException
{
map = new HashMap<String, String>();
/*
맑음, 구름조금, 구름많음, 구름많고 비, 구름많고 비/눈, 구름많고 눈/비,구름많고 눈
, 흐림, 흐리고 비, 흐리고 비/눈, 흐리고 눈/비, 흐리고 눈
*/
map.put("맑음", "W_DB01.png");
map.put("흐림", "W_DB04.png");
map.put("비", "W_DB05.png");
map.put("구름조금", "W_NB02.png");
map.put("구름많음", "W_NB03.png");
map.put("흐리고 비", "W_NB08.png");
map.put("구름많고 비", "W_NB20.png");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//-- DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// 와 같은 구문
String str = String.format("https://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=%s"
, stnId);
URL url = new URL(str);
InputSource is = new InputSource(url.openStream());
xmlObj = builder.parse(is);
xPath = XPathFactory.newInstance().newXPath(); //-- check
//-- XPathFactory xFactory = XPathFactory.newInstance();
// xPath = xFactory.newXPath();
// 와 같은 구문
/*
○ XPath 생성
- XPathFactory 의 정적 메소드(static) 『newInstance()』 호출을 통해
XPath 의 생성을 지원하는 XPathFactory 를 생성하고
- 이 XPathFactory 의 정적 메소드(static) 『newPath()』 호출을 통해
XPath 객체를 생성한다.
○ 노드 선택 (Selecting Nodes)
- 브라우저마다 XPath 를 처리하는 방법에서 차이를 보인다.
- Chrome, FireFox, Edge, Opera, Safari 등은
『evaluation()』 메소드를 사용하여 노드를 처리한다.
→ xmlDoc.evaluation(xPath, xmlDoc, null, XPathResult.ANY_TYPE, null)
- IE 는 『selectNodes()』 메소드를 사용하여 노드를 선택한다.
○ XPath 의 『compile(XPath 경로 표현식)』
- XML 데이터 Parsing
1. XML 이 제공되는 URL 로 접속하여 데이터를 수신한다.
2. DocumentBuilderFactory ... newInstance() 로 factory 를 생성한다.
3. DocumentBuilder ... newDocumentBuilder() 로 builder 를 생성한다.
4. InputSource is ... new InputSource() 로 InputSource 를 생성한다.
이 때, 파일로 수신한 경우라면 File 객체를 넘겨준다.
5. Document xmlObj = builder.parse(is) 로 XML 을 파싱(Parsing)한다.
6. XPath xPath = XPathFactory.newInstance().newXPath() 로
XPath 객체를 생성하고
7. XPathExpression expr = XPath.compile( XPath 경로 표현식 ) 으로
가져올 Element 를 선택하게 된다.
8. 해당 노드(Element) 에 접근하여 필요한 데이터를 추출한다.
*/
}
// 단일 값 처리
// <title>중기예보~~~</title>
public String weatherTitle() throws XPathExpressionException
{
String result = "";
result = xPath.compile("/rss/channel/item/title").evaluate(xmlObj);
return result;
}
// <wf><![CDATA[ ○ ~~~~ ]]></wf>
public String weatherInfo() throws XPathExpressionException
{
String result = "";
result = xPath.compile("/rss/channel/item/description/header/wf").evaluate(xmlObj);
return result;
}
// check -- XPath 사용시 가장 많이 사용하는 방법
// 다중 엘리먼트 city (도시 이름) → 배열 구성
public ArrayList<String> weatherCityList() throws XPathExpressionException
{
ArrayList<String>result = new ArrayList<String>();
NodeList cityNodeList = (NodeList)xPath
.compile("/rss/channel/item/description/body/location/city")
.evaluate(xmlObj, XPathConstants.NODESET);
/*
○ XPath 의 『evaluate()』 메소드 두 번째 파라미터 (리턴 타입)
- XPathConstants.NODESET -- NodeList
- XPathConstants.NODE
- XPathConstants.BOOLEAN
- XPathConstants.NUMBER
- XPathConstants.STRING
*/
for (int i=0; i<cityNodeList.getLength(); i++)
{
Node cityNode = cityNodeList.item(i);
result.add(cityNode.getTextContent());
}
return result;
}
// check
// 날씨 정보 리스트 -- 반환 자료형 주의
public ArrayList<WeatherDTO> weatherList(String idx) throws XPathExpressionException
{
ArrayList<WeatherDTO> result = new ArrayList<WeatherDTO>();
// check! 특정 지역의 data들 반환
NodeList dataNodeList = (NodeList)xPath
.compile(String.format("/rss/channel/item/description/body/locatios[%s]/data", idx))
.evaluate(xmlObj, XPathConstants.NODESET);
// check! → 『int i=1;』
//for (int i=0; i<dataNodeList.getLength(); i++)
//-- W3C 의 권고에 따라 잘 만들어진 웹 페이지의 경우... 1부터 시작
for (int i=1; i<=dataNodeList.getLength(); i++)
{
// tmEf
String tmEf = (String)xPath
.compile(String.format("/rss/channel/item/description/body/locations[%s]/data[%s]/tmEf", idx, i))
.evaluate(xmlObj);
// wf
String wf = (String)xPath
.compile(String.format("/rss/channel/item/description/body/locations[%s]/data[%s]/wf", idx, i))
.evaluate(xmlObj);
// tmn
String tmn = (String)xPath
.compile(String.format("/rss/channel/item/description/body/locations[%s]/data[%s]/tmn", idx, i))
.evaluate(xmlObj);
// tmx
String tmx = (String)xPath
.compile(String.format("/rss/channel/item/description/body/locations[%s]/data[%s]/tmx", idx, i))
.evaluate(xmlObj);
// rnSt
String rnSt = (String)xPath
.compile(String.format("/rss/channel/item/description/body/locations[%s]/data[%s]/rnSt", idx, i))
.evaluate(xmlObj);
// DTO 구성
WeatherDTO w = new WeatherDTO();
w.setTmEf(tmEf);
w.setWf(wf);
w.setTmn(tmn);
w.setTmx(tmx);
w.setRnSt(rnSt);
// ++ HashMap 에 구성해둔 img 가져오기
w.setImg(map.get(wf));
result.add(w);
}
return result;
}
}