Dev/JS & Jquery

Ajax - Document Object Model과 XML

창문닦이 2019. 4. 3. 09:49

DOM이란? 

DOM(Document Object Model)은 문서를 객체로 표현하기 위한 표준.

HTML 이나 XML등의 문서를 객체로 표현할 때 사용되는 API이다.

자바스크립트 ,자바,C,C# 등 다양한 언어에서 DOM API를 제공하고있다.

DOM은 문서를 트리구조로 표현하기 때문에 쉽게 이해할 수 있다.

XMLHttpRequest 객체는 응답 텍스트 대신 XML 응답 결과를 사용할 수 있다.

이 때, DOM API를 사용해서 서버가 생성한 XML로부터 데이터를 추출할 수 있다.

 XML문서와 DOM트리 구조

 

 

브라우저는 HTML의 모든 요소를 객체화하고 이 객체를 계층구조로 묶어, 어떤 요소가 다른요소 내부에 포함되어 있을때, 이 요소는 자신을 포함한 요소의 자손 요소로써 구조화한다.

예를 들어, author 요소는 book요소의 자식이며 title의 형제 관계를 맺는다. 이렇게 객체화된 요소는 여러 속성을 가질 수 있으며 HTML 요소 속성을 그대로 사용하기도 한다. 즉, 객체 속성 이름으로 속성에 접근하여 상호작용을 통해 속성을 바꿀 수도 있다. DOM의 상세 명세를 보면 DOM객체의 특정 타입 속성에 대한 정의를 확인할 수 있다.

주요 DOM API

DOM(Document Object Model) : 마크업 문서의 특정 노드를 객체 단위로 접근하고 조작할 수 있는 일관된 방법 제공. 웹 페이지를 편집하지 않은 채로 브라우저에 보이는 특정 부분을 편집하는 자바스크립트다. 브라우저에 출력된 웹페이지는 모두 DOM객체로 구성되어 있다. 객체화 시키는 작업 > DOM객체로 바꾼다.

Document : 전체 문서

Element : 각 태그.. <books>나 <book>과 같이 태그에 해당하는 노드가 Element로 매핑된다

Text : 문자열데이터가 Text노드로 표현된다. <author>이승재</author> 의 경우 '이승재' 문자열은 text노드에 저장된다.

CDataSection : XML문서의 CDATA 영역의 문자열 값을 저장한다. 이 영역에 해당하는 내용은 모두 텍스트로 인식된다. [!CDATA]

① XML문서를 처리하기 위한 DOM 요소의 속성

childNodes 현재 요소의 자식을 배열로 표현한다.
firstChild 현재 요소의 첫 번째 자식이다.
lastChild 현재 요소의 마지막 자식이다.
nextSibling 현재 요소와 바로 다음의 요소를 의미한다.
nodeValue 해당 요소의 값을 읽고 쓸 수 있는 속성을 정의한다.(=data)
parentNode 해당 요소의 부모 노드이다.
previousSibling 현재 요소와 바로 이전의 요소를 의미한다.

② XML문서를 다루는 유용한 DOM 요소의 메소드

getElementById(id)  도큐먼트에서 특정한 id 속성 값을 가지고 있는 요소를 반환한다.
getElementsByTagName(name) 특정한 태그 이름을 가지고 있는 자식 요소로 구성된 배열을 리턴 한다.
⋅hasChildNodes()  해당 요소가 자식 요소를 포함하고 있는지를 나타내는 Boolean 값을 리턴 한다.
getAttribute(name) 특정한 name 에 해당하는 요소의 속성 값을 리턴 한다

 

HTML로 DOM객체 구조화

파일 업로드시 여러개의 첨부파일을 해야하는 경우 이 기능이 활용. HTML보다 XML 파싱하는 경우가 더 자주 쓰인다.

책을 보고 공부하는 거보다 실제로 소스코드를 작성해보자!

DOM API를 이용해서 HTML 화면 변경 하는 예제

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>DOM</title>
<script type="text/javascript">
var count = 0;
function addItem(){
count++;
var newItemE = document.createElement("div");//createElement 지정한 태그이름을 갖는 Element노드 생성
newItemE.setAttribute("id", "item_"+count);


var html = "새로 추가된 아이템[" +count+ "]&nbsp;";
html += "<input type=\"button\" value=\"삭제\" onclick=\"removeItem('item_"+count+"');\"/>";
작성되는 태그
<div id="item_1">
새로 추가된 아이템[1]<input type="button" value="삭제" onclick="removeItem('item_1');"/>
</div>
newItemE.innerHTML = html;
var itemListDiv = document.getElementById("itemList");
itemListDiv.appendChild(newItemE);
}
function removeItem(itemId){
var removeItem = document.getElementById(itemId);
removeItem.parentNode.removeChild(removeItem);
}
</script>
</head>
<body>
<h1>HTML DOM을 이용한 화면 변경</h1>
<hr/>
<input type="button" value="추가" onclick="addItem();"/>
<div id="itemList"></div>
</body>
</html>

DB에 있는 데이터를 가져와서 XML 파일로 변환하거 읽을 수 있다.

또는 특정 위치에 있는 데이터(API)를 http://~ 주소에 접근하여 읽을 수 있다.

공용데이터 api를 읽어와서 화면에 출력하는 방식으로 활용이 가능하니 추후 프로젝트에서 사용해보자.

출력 페이지

 

 


XML파일을 읽어와 웹페이지에 출력하기

① xml 파일 생성(books.xml)

XMLHttpRequest 객체는 서버로부터 XML문서를 응답으로 읽어올 수 있으며 서버에서 읽어온 XML문서는 DOM트리로 변환되어 저장된다.

DOM API를 이용하면 서버가 생성한 XML문서로부터 원하는 정보를 읽어올 수 있다. XML파일을 읽어 출력하는 기능을 구현해보자.

<?xml version="1.0" encoding="UTF-8"?>
<books>
<book>
<title>겨울왕국</title>
<author>디즈니</author>
</book>
<book>
<title>오늘은 화요일</title>
<author>EBS</author>
</book>
<book>
<title>이솝우화</title>
<author>미드</author>
</book>
<book>
<title>힐러리의 삶</title>
<author>클린턴</author>
</book>
</books>

② 출력 페이지 생성 - getBooksXML.jsp 

웹브라우져가 응답문서를 XML로 인식해서 출력하는 것을 알수있다.

<%@ 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="<%=cp%>/data/js/httpRequest.js"></script>
<script type="text/javascript">
function getBookList(){
sendRequest("books.xml",null,displayBookList,"GET");
}


function displayBookList(){
if(httpRequest.readyState==4){
if(httpRequest.status==200){


//전달받은 XML을 DOM 객체에 넣음
var Document = httpRequest.responseXML;
//DOM 객체에서 Elements 추출
var booksE = Document.documentElement;
//book의 갯수 추출
var bookNL = booksE.getElementsByTagName("book");
alert(bookNL.length+"개");
//전체 데이터 읽고 HTML로 출력
var html = "";
html +="<ol>";
for(var i=0;i<bookNL.length;i++){
var bookE = bookNL.item(i);
var titleStr = bookE
.getElementsByTagName("title")
.item(0)
.firstChild
.nodeValue;//title에는 Text데이터가 하나만 들어있음


var authorStr = bookE
.getElementsByTagName("author")
.item(0)
.firstChild
.nodeValue;


html += "<li>"
+ titleStr + "-"
+ authorStr + "</li>";
}
html += "</ol>";
document.getElementById("bookDiv").innerHTML = html;
}
}
}
window.onload = function(){
getBookList();
}
</script>
</head>
<body>
<h1 id="list">Book List</h1>
<hr/>
<div id="bookDiv" style="display: block;margin: 0 auto;"></div>
</body>
</html>

 

 

텍스트파일을 XML로 변환하여 웹페이지에 출력하기

① 출력 페이지 생성 - newsTitleXML.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="<%=cp%>/data/js/httpRequest.js"></script>
<script type="text/javascript">
function newsTitle(){
sendRequest("newsTitleXML_ok.jsp", null, displayNewsTitle, "GET");
setTimeout("newsTitle()", 3000)
}


function displayNewsTitle(){
if(httpRequest.readyState==4){
if(httpRequest.status==200){
var doc = httpRequest.responseXML;//response를 xml파일로 받음
//alert(doc);//알람창으로 object XMLDocument 뜸
var count =
doc.getElementsByTagName("count")
.item(0)
.firstChild
.nodeValue;
//alert(count);//7


if(count>0){
var titleNL =doc.getElementsByTagName("title");
var htmlData = "<ol>";
for(var i=0; i<titleNL.length;i++){
htmlData +="<li>" +
titleNL.item(i).firstChild.nodeValue
+ "</li>";
}
htmlData += "</ol>";
var newsDiv = document.getElementById("news");
newsDiv.innerHTML = htmlData;
}
}else{
alert(httpRequest.status+":"+httpRequest.statusText);
}
}
}
window.onload = function(){
newsTitle();
}
</script>
<style type="text/css">
div{
margin:auto;
border:1px solid #0000ff;
width:600px;
height:70%;
padding:10px;
}
</style>
</head>
<body>
<div id="news"></div>
<br/>
<input type="text">
</body>
</html>

 

② 호출 페이지 생성 - newsTitleXML_ok.jsp

특정 텍스트 데이터를 xml데이터로 변환하여 전송하고자 한다. DB에 있는 특정 텍스트 데이터를 xml데이터로 변환하여 전송하는 것도 가능하다.

쉼표로 된 데이터(CSV)보다 xml데이터를 전송받는 것이 편리하다.

<%@page import="java.util.Date"%>
<%@ page contentType="text/xml; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
//클라이언트 캐쉬 제거
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-store");//HTTP 1.0버전
response.setHeader("Cache-Control", "no-cache");//HTTP 1.1버전
//세션 삭제 후(로그아웃) 뒤로가기 방지
response.setDateHeader("Expires", 0);
%>
<result>
<count><%=newsTitle.length %></count>
<data>
<%for(int i=0;i<newsTitle.length;i++){ %>
<title><%=newsTitle[i]+"|"+new Date() %></title>
<%} %>
</data>
</result>
<%!
String[] newsTitle = {
"2000호 특별기획 '핀테크' 성지 룩셈부르크를 가다 ...",
"강화된 외감... 대기업마저 '회계포비아'",
"반도체株 바닥 다지고 상승할까 ...",
"알아두면 유용한 보험계약 관리 노하우",
"[신율의 정치 읽기] '민족주의' '이념대립' ...",
"[나기자의 Activity] 일렉트로복싱 해보니",
"[카드뉴스] 'SUV 게 섰거라' 세단의 반격"
};
%>

③ 실행 화면

var doc = httpRequest.responseXML; 를 alert로 띄운 메세지이다.

반환데이터가 XMLDocument로 Object로 전달되는 걸 알 수있다.

 

input태그에 데이터를 입력하더라도 비동기식을 이용해 전달된 데이터는 reload된 개념이 아니기 때문에 데이터가 사라지지 않는다.