아래 공공데이터 자료를 xml로 다운받아 웹에서 파싱을 해보자.
편의상 파일 이름은 wifi.xml로 변경하였다.
용량이 커서 잘 열리지 않아서 윈도우 탐색기의 미리보기로 대충 구조를 훑었다.
디테일한 데이터는 엑셀에서 xml 형식으로 열어보면 된다.
혹은 인내를 가지고 office xml handler로 열어보아도 된다. 버벅임이 심하지만...
준비된 xml 파일을 서버로 올린다.
이제 wifi_parsing.jsp 코드를 작성하자.
임포트
<!DOCTYPE html>
<meta charset="utf-8">
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.sql.*, javax.sql.*,java.io.*,java.net.*"%>
<%@ page import="javax.xml.parsers.*,org.w3c.dom.*"%>
javax.xml.parsers : DOM파서 객체의 클래스인 DocumentBuilde 클래스를 제공한다
org.w3c.dom : XML 데이터 처리용 Java Api 컴퍼넌트 API인 DOM 인터페이스를 제공한다
틀 만들기
<html>
<head>
<title>xml 파싱</title>
</head>
<body>
<h1>공공와이파이</h1>
<table border=1px>
<tr>
<td width=50px>순번</td>
<td width=100px>설치장소명</td>
<td width=200px>소재지 지번주소</td>
<td width=100px>위도</td>
<td width=100px>경도</td>
</tr>
// 여기서 반복문 돌릴 것!
</table>
</bodY>
</html>
여기까지 쳐 두면 위처럼 제목만 있는 테이블이 덜렁 만들어진다.
주석 부분에서 xml을 파싱한 데이터를 출력할 것인데, 그에 앞서 파싱할 준비를 해야 한다.
파싱을 위한 준비과정
이 코드는 반복문을 돌리기 전에 미리 준비해준다.
<%
//DOM parser 객체 생성
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// 서버로 올린 xml 파일의 local path(전체경로) 지정
Document doc = docBuilder.parse(new File("/var/lib/tomcat8/webapps/ROOT/xml/wifi.xml"));
// Element root = doc.getDocumentElement(); //root 태그를 가져오기도 하지만 이 소스에서는 쓰이는 곳이 없다.
NodeList tag_loc = doc.getElementsByTagName("설치장소명"); //xml name tag
NodeList tag_addr = doc.getElementsByTagName("소재지지번주소"); //xml name tag
NodeList tag_addr_road = doc.getElementsByTagName("소재지도로명주소"); //xml name tag
NodeList tag_lat = doc.getElementsByTagName("위도"); //xml name tag
NodeList tag_long = doc.getElementsByTagName("경도"); //xml name tag
%>
파싱하여 가져오고자 하는 요소들을 getElementsByTagName(str)로 지정해서 가져올 준비를 마친다.
* addr_road는 지번주소가 없을 경우 대체하기 위하여 받아온다.
파싱한 데이터 출력하기
이 코드를 반복문 돌릴 것! 이라고 쓴 주석 자리에 채워준다.
<%
for(int i=0; i<tag_loc.getLength(); i++){
out.println("<tr>");
out.println("<td>"+i+"</td>");
out.println("<td>"+tag_loc.item(i).getFirstChild().getNodeValue()+"</td>");
// 지번주소 있으면 출력
if(tag_addr.item(i).getFirstChild()!=null){
out.println("<td>"+tag_addr.item(i).getFirstChild().getNodeValue()+"</td>");
// 지번주소 없으면 도로명주소
} else if(tag_addr_road.item(i).getFirstChild()!=null){
out.println("<td>"+tag_addr_road.item(i).getFirstChild().getNodeValue()+"*</td>");
// 둘다 없으면 주소없음!
} else {
out.println("<td> *** 주소정보없음 *** </td>");
}
out.println("<td>"+tag_lat.item(i).getFirstChild().getNodeValue()+"</td>");
out.println("<td>"+tag_long.item(i).getFirstChild().getNodeValue()+"</td>");
out.println("</tr>");
}
%>
xml 데이터가 불완전하여 지번주소가 없는 데이터가 다수 존재한다.
이경우 Failed to load resource: net::ERR_INCOMPLETE_CHUNKED_ENCODING 라는 에러가 뜨면서 파싱이 중단된다.
이를 방지하기 위하여 중간에 조건문을 두어 지번주소가 없는 경우 도로명주소, 또는 주소정보없음으로 대체해준다.
NodeList.item(int).getFirstChilde()가 null일 때,
여기에 getNodeValue()를 하면 NullPointException 에러가 발생한다.
그러므로 if문의 조건에 getNodeValue()까지 써서는 안된다.
혹은 이를 이용하여 if문 대신 try-catch문으로 대체해도 된다.
실행결과(브라우저)
'IT > 웹프로그래밍' 카테고리의 다른 글
ajax 사용하여 비동기 데이터 받아오기 (0) | 2019.08.08 |
---|---|
Open API로 json 데이터 받아서 파싱하기 (json-simple 라이브러리) (0) | 2019.08.02 |
세션 이용하여 로그인 구현하기, 로그인이 필요한 데이터에 접근하기. (0) | 2019.07.31 |
HttpClient 라이브러리 사용하기 (0) | 2019.07.31 |
xml 기초 1. DataBase 내용을 xml로 만들기 (0) | 2019.07.30 |