[XmlStudy] 20240202 [프로그램 소스]
XmlStudy
체크할 사항
Ⅰ. 대상 태그를 이용한 자식 노드, 자식 노드의 텍스트 노드 얻어오기
XMLDOM 클래스에 선언한 메소드
`String getText(Element parent, String tagName)`
대상 태그(tagName) 객체의 첫 번째 자식 노드 얻어오기
Node node = parent.getElementsByTagName(tagName).item(0);
Element element = (Element)node;
대상 엘리먼트(element)의 자식 노드(텍스트 노드)의 값 얻어오기
String result = element.getChildNodes().item(0).getNodeValue();
Ⅱ. 기상전망에 해당하는 `wf` 노드에 접근하여, 텍스트 노드의 `<br />` 문자열을 `\n` 으로 변경
Node wfNode = root.getElementsByTagName("wf").item(0);
Element wfElement = (Element)wfNode;
System.out.println("기상전망 : " + wfElement.getTextContent().replaceAll("<br />", "\n"));
★────────── ======== ======
변경할 대상 변경할 문자
Ⅲ. 원격(remote) XML 읽어내기 (`https://fs.jtbc.co.kr/RSS/newsflash.xml`)
로컬(local) XML 파일을 읽어낼 때와의 유일한 차이점
① 문자열로 구성한 요청 주소를 URL 객체로 구성한다. → 절대 경로 지정 방식
String str = "http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=156";
URL url = new URL(str);
이때, 웹 상의 요청 방식은 절대 경로 지정방식이다.
URL 객체로 구성하는 이유는, 해당 URL 주소로 접근하여 XML 형식으로 작성된 문자열(String)을
얻어오기 위함이다.
② 구성한 URL 로 접근하여 데이터 내용 읽어오기 → 스트림(Stream)
InputSource is = new InpurSource(url.openStream());
xmlObj = builder.parse(is);
`InputSource` 객체를 생성한 후, 생성자의 매개변수로 `InputStream`을 넘겨준다.
URL 객체의 openStream() 메소드를 호출하면, url 객체에 해당하는 inputStream 을 얻어낼 수 있다.
Ⅳ. `getElementsByTagName("name")` 메소드를 사용하지 않고 특정 노드의 각기 다른 하위 노드들의 노드명과, 텍스트 노드 값을 가져오기
가져와야 하는 XML 파일이 아래와 같은 형식일 경우, `<item>` 태그 내부의 하위 노드들의 정보를
모두 출력하기 위해서는 root 엘리먼트인 `<rss>` 에 접근한 후 `<item>` 엘리먼트에서 `getElementsByTagName("name")`
처리를 하는 것이 일반적일 것이다.
<rss version="2.0">
<channel>
<title>JTBC News</title>
<link>https://fs.jtbc.co.kr/RSS/newsflash.xml</link>
<description>속보 RSS</description>
<language>ko</language>
<copyright>Copyright(C) JTBC All rights reserved.</copyright>
<category>속보</category>
<pubDate>2024년 2월 5일 월요일 오후 11:55:00</pubDate>
『출력하고 싶은 XML 의 노드 → <item> 노드 내부의 모든 항목』
───────────────────────────────────────────────────────────────────
<item>
<title>2월 5일 (월) 뉴스룸 다시보기</title>
<link>https://news.jtbc.co.kr/article/article.aspx?news_id=NB12164050</link>
<description> 시청자 여러분 JTBC 뉴스룸을 시작하겠습니다. 삼성전자 이재용 회장이 '경영권 불법 승계 의혹'과 관련해 1심에서 무죄를 선고받았습니다. 경영권을 물려받기 위해 그룹 내 회사들을 불공정하게 합병했고, 이 과정</description>
<pubDate>2024.02.05</pubDate>
</item>
───────────────────────────────────────────────────────────────────
....
그런데, 만약 태그가 현재처럼 4개가 아니라 굉장히 많은 숫자이고 일일이 태그명을 `getElementsByTagName("name")` 메소드의 매개변수로 넣어주는 것은 굉장히 번거로울 것이다.
이때는, `getChildNodes()` 메소드와 `item(i)`, `getNodeName()` 메소드를 이용하여 태그명을 일일이 나열하지 않고도
처리할 수 있다.
- ① 루트 엘리먼트에서 `<item>` 노드에 해당하는 NodeList itemList 를 반환받는다.
- ② itemList의 길이만큼 반복하면서 아래를 반복한다. `『for i』`
- ⑴ itemNode를 얻어낸다.
- ⑵ itemNode 를 다운캐스팅하여 itemElement 를 얻어낸다.
- ⑶ itemElement 에 해당하는 자식 노드들의 NodeList childNodeList 를 얻어낸다.
- ⑷ ⑶에서 반환받은 childNodeList 의 길이만큼 반복하면서 `『for j』` item(j)를 통해 ★childNodeList의 j번째 노드명을 구한다.
- ⑸ i번째에 해당하는 itemNode에 대한 itemElement에서 위에서 구한 노드명에 해당하는 텍스트 노드를 구해낸다.
NodeList itemList = root.getElementsByTagName("item");
for (int i = 0; i < itemList.getLength(); i++)
{
Node itemNode = itemList.item(i);
Element itemElement = (Element)itemNode;
NodeList childNodeList = itemElement.getChildNodes();
// <item> 노드 하위에 있는 자식 노드들의 개수만큼 아래를 반복한다.
for (int j = 0; j<childNodeList.getLength(); j++)
{
System.out.printf("%s>%s%n"
//-- <item> 노드의 자식 노드들 노드명을 하나씩 꺼내온다.
, childNodeList.item(j).getNodeName()
//-- 위에서 꺼낸 <item> 노드의 자식 노드명에 해당하는 태그의
// 텍스트 노드를 꺼내온다.
, XmlDom.getText(itemElement, String.valueOf(childNodeList.item(j).getNodeName())));
}
}
XmlApp05
XML DOM 활용 → 로컬(local) XML 읽어내기 (rss.xml)
※ 기상청 날씨누리로부터 얻어낸 데이터
기상청 날씨누리 페이지에서 기상정보 xml 조회
실행 결과 콘솔창
Java Resources > src > com.test
XmlDom
/*=====================
XMLDOM.java
=======================*/
package com.test;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class XmlDom
{
public static String getText(Element parent, String tagName)
{
String result = "";
// 대상 태그(tagName) 객체의 첫 번째 자식 노드 얻어오기
Node node = parent.getElementsByTagName(tagName).item(0);
Element element = (Element)node;
// 대상 엘리먼트(element)의 자식 노드(텍스트 노드)의 값 얻어오기
result = element.getChildNodes().item(0).getNodeValue();
// result = String.format("%s : %s"
// , element.getChildNodes()
// , element.getChildNodes().item(0).getNodeValue());
//
// result.replaceAll("text", "");
return result;
}
}
Java Resources > src > com.test
XmlDomTest06
/*=================================================
XmlDomTest06.java
- 콘솔 기반 자바 프로그램
- XML DOM 활용 → 로컬(local) XML 읽어내기
(rss.xml)
※ 기상청 날씨누리로부터 얻어낸 데이터
===================================================*/
package com.test;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XmlDomTest06
{
public static void main(String[] args)
{
try
{
// 1. XML 파일 메모리에 로드
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
String url = "rss.xml";
Document xmlObj = builder.parse(url);
// 2. 루트 엘리먼트 접근
Element root = xmlObj.getDocumentElement();
// 3-1. 타이틀 추출하기
Node itemNode = root.getElementsByTagName("item").item(0);
Element itemElement = (Element)itemNode;
System.out.printf("%s%n%n", XmlDom.getText(itemElement, "title"));
//--==>> 전국 육상 중기예보 - 2024년 02월 02일 (금)요일 06:00 발표
// 3-2. 기상전망 추출하기
Node wfNode = root.getElementsByTagName("wf").item(0);
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
// itemElement → description → header → wf 로 접근하는 것이 아니라
// root 엘리먼트를 통해 곧바로 wf 노드에 접근할 수 있다는 것을 알아두도록 하자!
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Element wfElement = (Element)wfNode;
System.out.println("[기상전망] ------------------------------------------------------");
System.out.printf("%s%n%n", wfElement.getTextContent().replaceAll("<br />", "\n"));
// 3-3. 도시별 기상 예보 추출하기
System.out.println("[육상날씨] ------------------------------------------------------");
NodeList locationNodeList = root.getElementsByTagName("location");
for (int i = 0; i < locationNodeList.getLength(); i++)
{
Node locationNode = locationNodeList.item(i);
Element locationElement = (Element)locationNode;
System.out.printf("도시 : %s%n", XmlDom.getText(locationElement, "city"));
System.out.println("----------------------------------------------------");
NodeList dataNodeList = locationElement.getElementsByTagName("data");
//Node dataNode = dataNodeList.item(0);
//Element dataElement = (Element)dataNode;
//NodeList subNodeList = dataElement.getChildNodes();
/*
<mode>A02</mode>
<tmEf>2024-02-05 00:00</tmEf> // 날짜 시간
<wf>흐리고 비/눈</wf> //
<tmn>2</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>70</rnSt>
*/
// [선생님 풀이]
for (int k = 0 ; k < dataNodeList.getLength(); k++)
{
Node dataNode = dataNodeList.item(k);
Element dataElement = (Element)dataNode;
System.out.printf(" %s / %s / %s℃ ~ %s℃ / %s%%%n"
, XmlDom.getText(dataElement, "tmEf")
, XmlDom.getText(dataElement, "wf")
, XmlDom.getText(dataElement, "tmn")
, XmlDom.getText(dataElement, "tmx")
, XmlDom.getText(dataElement, "rnSt"));
}
// [내 풀이] - 잘못됨, 시간별로 하나씩만 나온다.
// for (int j = 0; j < dataNodeList.getLength(); j++)
// {
// Node subNode = subNodeList.item(j);
//
// if (subNode.getNodeType() == 1)
// {
// Element subElement = (Element)subNode;
//
// // reliablility(신뢰도) 값이 없으므로, 태그명을 이용하여 이 항목 제외하기.
// if (!subElement.getNodeName().equals("reliability"))
// {
// System.out.printf("%s : %s %n", subElement.getNodeName(), subElement.getTextContent());
// }
// // 태그 안의 텍스트 노드 값이 존재하지 않을 때 항목 제외하기
// if (!subElement.getTextContent().equals(""))
// {
// System.out.printf("%s : %s %n", subElement.getNodeName(), subElement.getTextContent());
// }
// }
//
// }
Node rnStNode = locationElement.getElementsByTagName("rnSt").item(0);
Element rnStElement = (Element)rnStNode;
System.out.printf("%s : %s%n", rnStElement.getNodeName(), XmlDom.getText(locationElement, "rnSt"));
System.out.println();
}
} catch (Exception e)
{
System.out.println(e.toString());
}
}
}
XmlApp05
rss.xml [기상청 날씨누리에서 받아온 전국 육상 중기예보 xml 파일]
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>기상청 육상 중기예보</title>
<link>http://www.kma.go.kr/weather/forecast/mid-term_01.jsp</link>
<description>기상청 날씨 웹서비스</description>
<language>ko</language>
<generator>기상청</generator>
<pubDate>2024년 02월 02일 (금)요일 06:00</pubDate>
<item>
<author>기상청</author>
<category>육상중기예보</category>
<title>전국 육상 중기예보 - 2024년 02월 02일 (금)요일 06:00 발표</title>
<link>http://www.kma.go.kr/weather/forecast/mid-term_01.jsp</link>
<guid>http://www.kma.go.kr/weather/forecast/mid-term_01.jsp</guid>
<description>
<header>
<title>전국 육상중기예보</title>
<tm>202402020600</tm>
<wf>
<![CDATA[ ○ (강수) 5일(월)은 전국에 비 또는 눈이 오겠으며, 강원영동은 6일(화) 오전까지 이어지겠습니다.<br />○ (기온) 이번 예보기간 아침 기온은 -9~5도, 낮 기온은 2~10도로 평년(최저기온 -9~1도, 최고기온 3~10도)과 비슷하거나 조금 높겠습니다.<br />○ (해상) 5일(월)~6일(화)은 대부분 해상에서 물결이 1.0~4.0m로 매우 높게 일겠습니다.<br /><br />* 5일(월)~6일(화)은 기압골의 발달 정도와 이동 속도에 따라 강수지역과 시점, 강수형태(비/눈)가 변동될 가능성이 있으니, 앞으로 발표되는 최신 예보를 참고하기 바랍니다. ]]>
</wf>
</header>
<body>
<location wl_ver="3">
<province>서울ㆍ인천ㆍ경기도</province>
<city>서울</city>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 00:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>2</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 12:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>2</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 00:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 12:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 00:00</tmEf>
<wf>맑음</wf>
<tmn>-2</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 12:00</tmEf>
<wf>맑음</wf>
<tmn>-2</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-10 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-11 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-12 00:00</tmEf>
<wf>맑음</wf>
<tmn>-5</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
</location>
<location wl_ver="3">
<province>서울ㆍ인천ㆍ경기도</province>
<city>인천</city>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 00:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>2</tmn>
<tmx>2</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 12:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>2</tmn>
<tmx>2</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 00:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 12:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-10 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-11 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-12 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
</location>
<location wl_ver="3">
<province>서울ㆍ인천ㆍ경기도</province>
<city>수원</city>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 00:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>3</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 12:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>3</tmn>
<tmx>3</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 00:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 12:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 12:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 12:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-10 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-11 00:00</tmEf>
<wf>맑음</wf>
<tmn>-4</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-12 00:00</tmEf>
<wf>맑음</wf>
<tmn>-6</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
</location>
<location wl_ver="3">
<province>서울ㆍ인천ㆍ경기도</province>
<city>파주</city>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 00:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>1</tmn>
<tmx>2</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 12:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>1</tmn>
<tmx>2</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 00:00</tmEf>
<wf>구름많음</wf>
<tmn>-4</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 12:00</tmEf>
<wf>구름많음</wf>
<tmn>-4</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 00:00</tmEf>
<wf>맑음</wf>
<tmn>-6</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 12:00</tmEf>
<wf>맑음</wf>
<tmn>-6</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 00:00</tmEf>
<wf>맑음</wf>
<tmn>-6</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 12:00</tmEf>
<wf>맑음</wf>
<tmn>-6</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 00:00</tmEf>
<wf>맑음</wf>
<tmn>-7</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 12:00</tmEf>
<wf>맑음</wf>
<tmn>-7</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-10 00:00</tmEf>
<wf>맑음</wf>
<tmn>-7</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-11 00:00</tmEf>
<wf>맑음</wf>
<tmn>-7</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-12 00:00</tmEf>
<wf>맑음</wf>
<tmn>-8</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
</location>
<location wl_ver="3">
<province>서울ㆍ인천ㆍ경기도</province>
<city>이천</city>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 00:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-05 12:00</tmEf>
<wf>흐리고 비/눈</wf>
<tmn>3</tmn>
<tmx>4</tmx>
<reliability />
<rnSt>70</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 00:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>6</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-06 12:00</tmEf>
<wf>구름많음</wf>
<tmn>-2</tmn>
<tmx>6</tmx>
<reliability />
<rnSt>30</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 00:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-07 12:00</tmEf>
<wf>맑음</wf>
<tmn>-3</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 00:00</tmEf>
<wf>맑음</wf>
<tmn>-5</tmn>
<tmx>6</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-08 12:00</tmEf>
<wf>맑음</wf>
<tmn>-5</tmn>
<tmx>6</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 00:00</tmEf>
<wf>맑음</wf>
<tmn>-5</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A02</mode>
<tmEf>2024-02-09 12:00</tmEf>
<wf>맑음</wf>
<tmn>-5</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-10 00:00</tmEf>
<wf>맑음</wf>
<tmn>-5</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-11 00:00</tmEf>
<wf>맑음</wf>
<tmn>-6</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
<data>
<mode>A01</mode>
<tmEf>2024-02-12 00:00</tmEf>
<wf>맑음</wf>
<tmn>-7</tmn>
<tmx>5</tmx>
<reliability />
<rnSt>10</rnSt>
</data>
</location>
....(중략)
</channel>
</rss>
XmlApp06
XML DOM 활용
Remote XML 읽어내기 (http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108)
※ 기상청 날씨누리로부터 얻어낸 데이터
사용자의 지역 선택값 (1 ~ 10) 에 따라 웹 브라우저에서 읽어들이는 xml 링크가 달라진다. (GET 방식!)
실행 결과 콘솔창
Java Resources > src > com.test
XmlDomTest07
/*=================================================
XmlDomTest07.java
- 콘솔 기반 자바 프로그램
- XML DOM 활용 → 로컬(local) XML 읽어내기
(http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108)
※ 기상청 날씨누리로부터 얻어낸 데이터
===================================================*/
/*
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108 전국
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=109 서울·경기도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=105 강원도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=131 충청북도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=133 충청남도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=146 전라북도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=156 전라남도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=143 경상북도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=159 경상남도
http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=184 제주특별자치도
*/
package com.test;
import java.net.URL;
import java.util.Scanner;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class XmlDomTest07
{
// 1. 사용자에게 원하는 지역 선택값을 입력받는다.
// 2. 사용자가 선택하면, 그 지역에 해당하는 XML 을
// 실시간으로 웹 사이트에서 불러와서 정보를 뿌려주도록 처리한다.
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String[] stnId = {"108", "109", "105", "131", "133", "146", "156", "143", "159", "184"};
do
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document xmlObj = null;
// Local XML 파일인 경우...
// 내부 파일 경로 파일명, builder.parse(url) 사용.
/*
String url = "rss.xml";
xmlObj = builder.parse(url);
*/
// Remote XML 파일인 경우...
// 안내 → 외부의 입력값 처리
System.out.println("■■■ 기상청 육상 중기 예보 ■■■");
System.out.println("-----------------------------------");
System.out.println("1. 전국 ");
System.out.println("2. 서울·경기도 ");
System.out.println("3. 강원도 ");
System.out.println("4. 충청북도 ");
System.out.println("5. 충청남도 ");
System.out.println("6. 전라북도 ");
System.out.println("7. 전라남도 ");
System.out.println("8. 경상북도 ");
System.out.println("9. 경상남도 ");
System.out.println("10. 제주특별자치도 ");
System.out.println("-----------------------------------");
System.out.print(">> 지역 선택(종료 0) : ");
String m = sc.next();
if (m.equals("0"))
break;
//System.out.println("계속 진행");
String str = String.format("http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=%s"
, stnId[Integer.parseInt(m)-1]);
// 확인
System.out.println("요청 주소 : " + str);
// 『3. 강원도』 선택 시
//--==>> 요청 주소 : http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=105
// 『7. 전라남도』 선택 시
//--==>> 요청 주소 : http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=156
// * (웹 상의 요청 방식은 절대 경로 지정 방식이다.)
// 문자열로 구성한 요청 주소를 URL 객체 구성 → 절대 경로 지정 방식
URL url = new URL(str);
//==================================================================================
// [Why?] 왜 URL 객체로 구성? → 해당 URL 에 접근해서 String 을 얻어오기 위함이다.
//==================================================================================
// 구성한 URL 로 접근하여 데이터 내용 읽어오기 → 스트림(stream)
InputSource is = new InputSource(url.openStream());
} catch (Exception e)
{
System.out.println(e.toString());
}
} while (true);
}
}
XmlApp07
- XML DOM 활용 → 원격(remote) XML 읽어내기 (https://fs.jtbc.co.kr/RSS/newsflash.xml)
※ 언론사 뉴스로부터 얻어낸 데이터
JTBC 뉴스 RSS 페이지에서 속보 xml 조회
실행 결과 콘솔창
( * 선생님 해설은 내일! 2024/02/03~)
Java Resources > src > com.test
XmlDomTest08.java
/*=================================================
XmlDomTest08.java
- 콘솔 기반 자바 프로그램
- XML DOM 활용 → 원격(remote) XML 읽어내기
(https://fs.jtbc.co.kr/RSS/newsflash.xml)
※ 언론사 뉴스로부터 얻어낸 데이터
===================================================*/
/*
title> JTBC News
link>https://fs.jtbc.co.kr/RSS/newsflash.xml
description>속보 RSS
copyright>Copyright(C) JTBC All rights reserved.
주요 기사 -----------------------------------------------------------
title>[날씨] 전국 대체로 흐림…곳곳 미세먼지 '나쁨'
description> 오늘(2일)은 전국이 대체로 흐린 가운데, 일부 지역의 미세먼지가 '나쁨' 수준을 보이겠습니다.낮 최고기온은 3도에서 10도로 포근한 날씨가 예상됩니다.
link>https://news.jtbc.co.kr/article/article.aspx?news_id=NB12163616
pubDate>2024.02.02
title>외식비 급등에 인기 '쑥'…냉동치킨 '영양성분' 꼭 확인하세요
description> [앵커]프랜차이즈 치킨값이 2만 원을 훌쩍 넘는 요즘, 대체품으로 마트의 냉동 치킨을 찾는 경우가 늘어났습니다. 그런데 잘 살펴보셔야 합니다. 인기 제품들 가운데 포화지방과 나트륨이 과하게 들어 있거나, 원산
link>https://news.jtbc.co.kr/article/article.aspx?news_id=NB12163595
pubDate>2024.02.02
*/
package com.test;
import java.net.URL;
import java.util.Scanner;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;
public class XmlDomTest08
{
// public static void main(String[] args)
// {
// /*
// 1. 원격 XML 정보를 요청하고, 그 결과를 메모리에 로드
// → XML DOM 구성
// ·DB 활용
// ·DBF 활용
// ·XML 로딩
// 2. 루트 엘리먼트 접근
// 3. 특정 하위 엘리먼트 접근
// 4. 텍스트 노드 접근
// → 필요한 데이터 획득
// 5. 결과 처리(출력)
// */
//
// try
// {
// // ※ DOM(Document Object Model)
// // - XML 이나 HTML Document(문서)를 응용프로그램에서 사용하기 위한 API 규칙
// // - DOM 은 Document(문서)의 각 부분들을 객체(Object)로 표현한 API
//
// // ※ DOM(Document Object Model) 파서(Parser)
// // - XML 문서를 읽고, 해석한 후,
// // 해석한 결과를 메모리에 DOM 객체 트리 구조로 생성시키는 파서(Parser)
// // - 원하는 데이터에 접근할 수 있도록 해주어
// // 대상 데이터를 검색, 수정, 삭제할 수 있도록 지원
//
//
//
// } catch (Exception e)
// {
// System.out.println(e.toString());
// }
// }
public static void main(String[] args)
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document xmlObj = null;
String str = "https://fs.jtbc.co.kr/RSS/newsflash.xml";
URL url = new URL(str);
InputSource is = new InputSource(url.openStream());
xmlObj = builder.parse(is);
Element root = xmlObj.getDocumentElement();
// 타이틀, 날짜
System.out.printf("title> %s%n", XmlDom.getText(root, "title"));
System.out.printf("link> %s%n", XmlDom.getText(root, "pubDate"));
System.out.printf("description> %s%n", XmlDom.getText(root, "description"));
System.out.printf("copyright> %s%n", XmlDom.getText(root, "copyright"));
System.out.println();
System.out.println("주요 기사 ---------------------------------------------------");
/*
title>외식비 급등에 인기 '쑥'…냉동치킨 '영양성분' 꼭 확인하세요
description> [앵커]프랜차이즈 치킨값이 2만 원을 훌쩍 넘는 요즘, 대체품으로 마트의 냉동 치킨을 찾는 경우가 늘어났습니다. 그런데 잘 살펴보셔야 합니다. 인기 제품들 가운데 포화지방과 나트륨이 과하게 들어 있거나, 원산
link>https://news.jtbc.co.kr/article/article.aspx?news_id=NB12163595
pubDate>2024.02.02
*/
NodeList itemList = root.getElementsByTagName("item");
for (int i = 0; i < itemList.getLength(); i++)
{
Node itemNode = itemList.item(i);
Element itemElement = (Element)itemNode;
NodeList childNodeList = itemElement.getChildNodes();
for (int j = 0; j<childNodeList.getLength(); j++)
{
//System.out.println("테스트: " + itemElement.getChildNodes().item(i).getNodeName());
System.out.printf("%s>%s%n"
, childNodeList.item(j).getNodeName()
, XmlDom.getText(itemElement, String.valueOf(childNodeList.item(j).getNodeName())));
}
// System.out.printf("title>%s%n", XmlDom.getText(itemElement, "title"));
// System.out.printf("description>%s%n", XmlDom.getText(itemElement, "description"));
// System.out.printf("link>%s%n", XmlDom.getText(itemElement, "link"));
// System.out.printf("pubDate>%s%n", XmlDom.getText(itemElement, "pubDate"));
System.out.println("-------------------------------------------------------------");
}
} catch (Exception e)
{
System.out.println(e.toString());
}
}
}