DOM
DOM(Document Object Model)
- W3C's definition
"The Document Object Model is a platform- and language-neutral interface that will allow programs and scripts to dynamically access and update the content, structure and style of documents.
- DOM 의 역할
- dynamic access and update
- XML/HTML 문서의 접근 및 수정 => 내용/구조/스타일 정보의 검색 및 수정
- 대상 문서 : XML1.0 또는 HTML4.0, 기타 웹문서
- 컨텐츠의 조작 : 문서 요소에서 text 등 컨텐츠의 검색/질의, 추가/수정/삭제
- 구조의 탐색 및 조작 : 각 요소와 속성에 대한 검색/질의, 추가/수정/삭제
- interface
- 응용 프로그램 인터페이스 (API) - 각종 메소드 및 속성을 정의
- 플랫폼 및 언어 중립적(스크립트 포함) : Java, JavaScript, ASP, ...
- DOM level
- DOM level 1 : 1998.10 W3C 표준안
- DOM level 2 : 2000.11 W3C 표준안
- DOM level 3 : 2004.4 W3C 표준안
DOM and XML Parser
- Parser
의 역할
- XML 문서를 읽고 해석 : well-formed, valid 검사
- 응용프로그램 개발시 파서 사용 이유
- 파서가 메모리에 DOM 트리를 생성 : XML 문서트리와 일치
- 세부적인 XML 문법으로부터 프로그램 격리
- DOM 기반 Parser
- JAXP(Java API for XML Processing) : http://java.sun.com/xml/jaxp/index.html
- XML4J(XML Parser for Java) : http://www.alphaworks.ibm.com/tech/xml4j
- Xerces Java Parser : http://xml.apache.org
- MSXML : http://msdn.microsoft.com/xml
- [참고] SAX 기반 Parser
DOM 구조적 모델
- DOM 트리에서 노드/객체의 종류
- Document : 문서 객체, 최상위 노드
- Element, Attribute : 문서의 구조를 구성하고 있는 요소
- Text : 컨텐츠의 내용, 항상 단말 노드
- Collection : 일종의 노드 집합
- DOM 트리의 예
|
|
<parent> |
- 인터페이스(API)의 예
- 객체의 속성과 메소드를 사용하기 위한 사양
- DOM 인터페이스 예
- 문서.childNodes[1].nodeName
- 문서.firstChild.firstCild.firstCild.nodeName
- 문서.firstChild.firstCild.firstCild.nodeValue
- DOM Core Interface (Object Hierachy) 교재 p.414 (표9-3)
DOM 주요 API
- DOM 인터페이스의 공통 속성
- type, name, value
- 예) Node 객체의 경우 nodeType, nodeName, nodeValue 속성
- nodeType은 위 그림과 같이 여러 가지가 있다 (p.418 표 9-6, 9-7)
- 주요 객체/속성/메소드 - 진행하면서 지속적으로 참조
|
객체(Object) |
속성(Properties) |
메소드(methods) |
|
Node 객체 |
nodeName,
nodeType, nodeValue, childNodes, parentNode, childNode, firstChild, lastChild,
previousSibling, nextSibling, attributes, ownerDocument,
..., |
[표9-10] 노드 정보 구하기 |
| Document 객체 |
doctype, (async, readyState) |
[표9-13] 문서관련 정보 |
|
DOMImplementation 객체 |
|
[표 9-16] hasFeature(), createDocument(), ... |
| DocumentFragment 객체 |
* Node 객체와 동일 |
* Node 객체와 동일 |
|
NodeList 객체 |
length |
[표 9-17] getLength(), item() |
|
Element 객체 |
tagName |
[표 9-18] Element의 속성에 접근 |
|
NamedNodeMap 객체 |
length |
[표 9-19] NamedNodeMap 인터페이스 |
|
Attribute 객체 |
name, value |
[표 9-20] getName(), getValue(), setValue(), .. |
|
CharacterData 객체 |
data, length |
[표 9-21] appendData(), deleteData(), insertData(), replaceData(), ... |
DOM 프로그래밍 시작 - Document 객체에 문서 로드하기
- 문서 객체 새로 만들기 : MSXML 파서의 DOMDocument 객체를 생성
- Msxml.DOMDocument 객체를 새로 만들기
- 또는 HTML에서 <xml> 태그 이용
|
JavaScript (ECMAScript) |
<Script language="Javascript"> var xdoc1,xdoc2 xdoc1 = new ActiveXObject("Msxml.DOMDocument"); xdoc2 = new ActiveXObject("Msxml.DOMDocument"); ... xdoc1.load("ex08.xml"); xdoc2.load("ex09.xml"); </script> |
| VBScript 의 경우 |
<Script
language="VbScript"> Dim xdoc1,xdoc2 Set xdoc1 = CreateObject("Msxml.DOMDocument") Set xdoc2 = CreateObject("Msxml.DOMDocument") ... xdoc1.load("ex08.xml"); xdoc2.load("ex09.xml"); </Script> |
|
HTML에서 <xml> 태그 이용 - MSXML 파서 설치안한 경우 |
<HTML> <HEAD> <Script language="Javascript"> xdoc1.load("ex08.xml"); </script> </HEAD> <BODY> <xml id="xdoc1"></xml> <xml id="xdoc2" src="ex09.xml"></xml> </BODY> </HTML> |
|
Java의 경우 |
import java.xml.parsers.*; |

- 기존의 XML 문서 읽기
- DOMDocument 객체 읽기 - async 속성, load 메소드, xml 속성 : MSXML에서 제공
| xml 객체 생성하는 경우 (JavaScript) | <xml> 태그 이용하는 경우 |
| <HTML> <HEAD> <Script language="Javascript"> function xload0() { var xdoc = new ActiveXObject("Msxml.DOMDocument"); xdoc.async = false; xdoc.load("ex08.xml"); alert(xdoc.xml); } </script> </HEAD> <BODY> <input type="button" value="XML 로드0" onClick="xload0()"> </BODY> </HTML> |
<HTML> <HEAD> <Script language="Javascript"> function xload1() { xdoc.async = false; xdoc.load("ex08.xml"); alert(xdoc.xml); } </script> </HEAD> <BODY> <input type="button" value="XML 로드1" onClick="xload1()"> <xml id="xdoc"></xml> </BODY> </HTML> |
| VBScript 의 경우 | |
| <Script
language="VbScript"> Dim xdoc Set xdoc = CreateObject("Msxml.DOMDocument") xdoc.async = False; xdoc.load("ex08.xml"); MsgBox xdoc.xml </Script> |
|
- 신규 XML 문서의 작성
- loadXML 메소드
|
xdoc.async = false; xdoc.loadXML( "<book><title>XML 입문</title><author>일지매</author></book>"); alert(xdoc.xml); |
|
xdoc.async = false; xdoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>"); alert(xdoc.xml); |
- 공백의 처리 : preserveWhiteSpace 속성
|
xdoc.async = false; xdoc.preserveWhiteSpace = true; xdoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>"); alert(xdoc.xml); |
|
xdoc.async = false; xdoc.preserveWhiteSpace = true; xdoc.load("ex08.xml"); alert(xdoc.xml); |
- XML 문서의 저장 : save 메소드
- 에러 처리 : parseError 속성
- parseError.errorCode, parseError.line, parseError.linepos, parseError.reason
|
xdoc.async = false; xdoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </authors> </book>"); alert(xdoc.xml); |
| xdoc.async = false; xdoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </authors> </book>"); if (xdoc.parseError) alert("에러 위치 : " + xdoc.parseError.line + "번째 라인 " + xdoc.parseError.linepos + "번째 문자\n\n에러 이유 : " + xdoc.parseError.reason); else alert(xdoc.xml); |
- 루트 노드 찾기 (루트 엘리먼트)
- documentElement 속성
|
xdoc.async = false; xdoc.load("ex08.xml"); var xroot = xdoc.documentElement; alert(xroot.nodeName); |
|
xdoc.async = false; xdoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>"); var xroot = xdoc.documentElement; alert(xroot.nodeName); |
Node 객체의 정보구하기 - Node 객체
- 속성 : nodeName, nodeType, nodeValue, attributes, text 속성
- nodeType
- 1 (element), 2 (attribute), 3 (text) , 4 (CDATA), 5 (Entity Reference)...
- 예
|
xdoc.load("ex08.xml"); var xroot = xdoc.documentElement; alert('nodeName: '+xroot.nodeName+'\nnodeType: '+xroot.nodeType+ '\nnodeValue: '+xroot.nodeValue+'\nattributes: '+xroot.attributes.length); alert('xroot.text :\n\n' + xroot.text); |
실습 예제 1 : 파일 LOAD 및 DOM 명령 실행
|
XML 파일 경로를 직접 입력하거나 '찾아보기'로 선택,
'LOAD'로 파일을 메모리에 로드 또는 미리 작성되어 있는 파일 사용하기 사용하고자 하는 DOM 구문을 아래에 입력하고 '확인' 버튼을
클릭 |
원하는 노드 찾아가기
- Node 객체의 운행(Traversal) 관련 속성
- 관련속성

- hasChildNodes() 메소드
- 관련속성
- NodeList 객체
- 노드들의 리스트, 예: childNodes 객체
- length 속성, item(번호) 메소드
|
xdoc.load("ex08.xml");
/* childNodes, child, length
*/
var xroot = xdoc.documentElement; if (xroot.hasChildNodes) { alert('child 노드 개수: ' + xroot.childNodes.length); var curr = xroot.firstChild; alert('ownerDoc: '+ curr.ownerDocument.nodeName +'\n\n현재노드:\n\n'+ curr.xml); alert(curr.nodeName + curr.nodeTypeString + curr.nodeValue + curr.attributes.length); } else alert('No Child'); |
|
xdoc.load("ex08.xml"); /* sibling */ var xroot = xdoc.documentElement; var curr = xroot.firstChild.nextSibling; alert(curr.xml); curr = curr.childNodes.item(2); alert(curr.xml); curr = curr.previousSibling; alert(curr.text); alert(curr.nodeName + curr.nodeTypeString + curr.nodeValue + curr.attributes.length); |
임의 노드의 검색
- Document 객체에서
태그 이름으로
검색
- 노드리스트 = 문서.getElementsByTagName("tagName");
|
xdoc.load("ex08.xml"); var nlist = xdoc.getElementsByTagName("book"); for (i=0; i<nlist.length; i++) alert(nlist.item(i).xml); |
|
xdoc.load("ex08.xml"); var nlist = xdoc.getElementsByTagName("title"); for (i=0; i<nlist.length; i++) alert(nlist.item(i).xml); |
|
xdoc.load("ex08.xml"); /* 한번에 다 보여주기 */ var nlist = xdoc.getElementsByTagName("author"); var result = ""; for (i=0; i<nlist.length; i++) result = result + nlist.item(i).xml + "\n"; alert(result); |
- Node객체에서
패턴으로 검색
- 노드리스트 = 노드.selectNodes("pattern");
- 노드 = 노드.selectSingleNode("pattern");
|
xdoc.load("ex08.xml"); var xroot = xdoc.documentElement; var node1 = xroot.selectSingleNode("title"); alert(node1.text); |
|
/* title 과 author를 같이 적기 */
var xroot = xdoc.documentElement; var tlist = xroot.selectNodes('//title'); var alist = xroot.selectNodes('//author'); for (i=0; i<alist.length; i++) alert('[' + i + '] ' + alist.item(i).text + ', ' + tlist.item(i).text); |
|
var xroot = xdoc.documentElement; var node1 = xroot.selectSingleNode('//book[@InStock=0]'); alert(node1.xml+'\n=> 재고가 없습니다.'); |
|
var xroot = xdoc.documentElement; var tlist = xroot.selectNodes('//book[@InStock!=0]/title'); var result=""; for (i=0; i<tlist.length; i++) result = result + tlist.item(i).text + "\n"; alert("재고 있음 =>\n" + result); |
실습 예제 2 : 도서 검색
|
XML 파일 경로 입력 또는 '찾아보기'로 선택 원하는 검색 조건을 입력하고 '검색' 버튼 클릭 1) 엘리먼트 또는 속성 이름
검색 : |
<div id="resDiv">검색 결과</div> |
문서에 새로운 노드 추가하기
|
- Document 객체에 노드 신규생성 메소드
- createElement(name), createAttribute(name)
- createTextNode(data), createCDATASection(data),
- createComment(data), createProcessingInstruction(target,data), ...
|
xdoc.async = false; xdoc.loadXML( "<book> <title> XML 입문 </title> <author> 일지매 </author> </book>"); elmt = xdoc.createElement("pages"); alert(elmt.xml); pg = xdoc.createTextNode("386"); alert(pg.xml); stock = xdoc.createAttribute("Instock"); alert(stock.xml); cmt = xdoc.createComment("노드추가"); alert(cmt.xml); pi = xdoc.createProcessingInstruction("xml-stylesheet", "type='text/xsl' href='ex8.xsl'"); alert(pi.xml); cd = xdoc.createCDATASection("<1>"); alert(cd.xml); alert('[결과] : \n' + xdoc.xml); /* 최종 결과 */ |
- 노드의 추가 (Node, Document 객체 메소드)
- appendChild(child)
- insertBefore(child,before)
|
xdoc.loadXML(
"<book> <title> XML
입문 </title> <author> 일지매 </author> </book>"); elmt = xdoc.createElement("pages"); // (1) 요소 신규생성 pg = xdoc.createTextNode("386"); // (2) 텍스트 신규생성 elmt.appendChild(pg); alert(elmt.xml +'\n----------\n' + xdoc.xml); // (3) 붙이기 xroot = xdoc.documentElement; xroot.appendChild(elmt); alert(xdoc.xml); // (a) 원하는 위치에 |
|
xdoc.loadXML(
"<book> ... </book>"); cmt = xdoc.createComment("노드추가"); // (1) xdoc.appendChild(cmt); alert(xdoc.xml); // 문서에 노드 연결 (b) xroot = xdoc.documentElement; alert('[PI 삽입전 root] : '+xroot.nodeName); pi = xdoc.createProcessingInstruction("xml-stylesheet", "type='text/xsl' href='ex7.xsl'"); // (1) xdoc.insertBefore(pi,xroot); alert('[PI 삽입후] : '+xmldoc.xml); // 문서에 노드 연결 (b) xroot = xdoc.documentElement; alert('[PI 삽입후 root] : '+xroot.nodeName); |
- 중간에 노드 삽입할 때 주의
|
cmt =
xdoc.createComment("노드추가"); xdoc.insertBefore(cmt, xdoc.firstChild); alert('[xdoc] :\n'+xdoc.xml); xroot = xdoc.documentElement; alert('[root] : '+xroot.nodeName); elmt = xdoc.createElement('list'); // (1) elmt.appendChild(xroot); alert('[elmt] :\n\n'+elmt.xml); // (2) xdoc.documentElement = elmt; alert('[xdoc] :\n\n'+xdoc.xml); // (3) |
노드의 삭제/수정 (Node, Document 객체 메소드)
- removeChild(child), replaceChild(child,toReplace)
원하는 경우: 
|
xdoc.loadXML( "<book> <title> XML
입문 </title> <author> 일지매 </author>
</book>"); xroot = xdoc.documentElement; elmt = xroot.firstChild; node=elmt.removeChild(elmt.firstChild); alert('[삭제] :\n\n'+node.nodeValue); alert('[결과] :\n\n'+xdoc.xml); elmt = xroot.lastChild; node=xroot.removeChild(elmt); alert('[삭제] :\n\n'+node.xml); alert('[결과] :\n\n'+xdoc.xml); |
속성 읽어오기
- NamedNodeMap 객체
- 이름="값"의 쌍으로 구성된 객체의 모임, 순서 상관 없음
- getNamedItem("속성명"), setNamedItem(속성노드), removeNamedItem("속성명") 메소드
- Attribute 노드 객체
- getAttributeNode(“속성명”), setAttributeNode(속성노드), removeAttributeNode(속성노드)
- Element 노드 객체
- getAttribute(“속성명”), setAttribute(“속성명”, “속성값”), removeAttribute(“속성명”)
|
xdoc.load("ex08.xml"); var xroot = xdoc.documentElement; var attrs = xroot.firstChild.attributes; var attr0 = attrs.getNamedItem("InStock"); // name , value 와 동일한 결과 alert('[getNamedItem] : ' + attr0.xml + '\n' + attr0.nodeName + attr0.nodeValue); |
|
var xroot=xdoc.documentElement;
|
|
var xroot=xdoc.documentElement;
|
새로운 속성 추가하기
|
속성의 수정/삭제
- nodeName, nodeValue, nodeType 등 속성 (name, value, type 동일)
- NamedNodeMap 객체 :
- getNamedItem("속성명"), setNamedItem(속성노드), removeNamedItem("속성명")
|
xdoc.loadXML(
"<book> ... </book>"); elmt = xdoc.createElement('price'); cur = xdoc.createAttribute('currency'); alert(cur.xml); // (1) elmt.attributes.setNamedItem(cur); alert(elmt.xml); // (3) cur.nodeValue = 'won'; elmt.text = '33000'; alert(elmt.xml); // (2) stock = xdoc.createAttribute('InStock'); stock.value=7; alert(stock.xml); // (1), (2) xroot = xdoc.documentElement; xroot.appendChild(elmt); xroot.attributes.setNamedItem(stock); alert(xdoc.xml); // (3) |
- Element 노드 :
- getAttribute(“속성명”), setAttribute(“속성명”, “속성값”), removeAttribute(“속성명”)
|
xdoc.loadXML(
"<book> ... </book>"); elmt = xdoc.createElement('price'); elmt.setAttribute('currency','won'); elmt.text = '33000'; alert(elmt.xml); // 신규속성 추가 xroot = xdoc.documentElement; xroot.appendChild(elmt); xroot.setAttribute('InStock','7'); alert(xdoc.xml); // 신규속성 추가 st1 = xroot.getAttribute('InStock'); st2 = xroot.attributes.getNamedItem('InStock'); alert('[1] '+st1+'\n[2] '+st2.xml); xroot.setAttribute('InStock','9'); alert(xroot.xml); // 속성값 변경 xroot.removeAttribute('InStock'); alert(xdoc.xml); |
*문서의 변환*
- transformNode(스타일시트)
|
<HTML> |
xdoc.async =
false; xdoc.load('ex08.xml'); alert(xdoc.xml); xsldoc.async = false; xsldoc.load('ex08.xsl'); alert(xsldoc.xml); var newdoc = xdoc.transformNode(xsldoc.XMLDocument); alert(newdoc); var anwin = window.open('', ' ', 'width=500, height=400'); anwin.document.write(newdoc); |
|
|
<div id="result"> ... </div>
|





::: 사람과 사람의 교감! 人터넷의 첫 시작! 댓글을 달아주세요! :::