'DOM'에 해당되는 글 1건

  1. [2009/03/19] [DOM] DOM

[DOM] DOM

[■Web Programing/OO JavaScript OO]
http://mm.sookmyung.ac.kr/~sblim/lec/xml-int04/xml06-61dom.htm DOM

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 문법으로부터 프로그램 격리

  • [참고] SAX 기반 Parser

DOM 구조적 모델

  • DOM 트리에서 노드/객체의 종류
    • Document : 문서 객체, 최상위 노드
    • Element, Attribute : 문서의 구조를 구성하고 있는 요소
    • Text : 컨텐츠의 내용, 항상 단말 노드
    • Collection : 일종의 노드 집합
  • DOM 트리의 예

    <parent>
        <child  id="123">text here</child>
     </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, ..., 
    (
    text, xml) [표9-8]

    [표9-10] 노드 정보 구하기
    getNodeName(), ..., getAttributes(), ...
    [표 9-11] 문서 조작
    appendChild(), insertBefore(),
    removeChild(), replaceChild(), cloneNode()
    [표 9-12] 트리 순회 관련
    getParentNode(), getChildNode(), ...
    hasChildNodes(), ...

    Document 객체

    doctype,
    documentElement, implementation, ...

    (async, readyState)
    *W3C 표준이 아니라  MS에서 제공하는 인터페이스

    [표9-13] 문서관련 정보
    getDoctype(), getImplementation(), ...
    [표 9-14] 트리 순회 관련
    getDocumentElement(), getElemenmtByID(),
    getElementByTagName(), ...
    [표 9-15] 문서 작성
    createElement(), createAttribute(), createTextNode(), createCDATASection(), createComment(), createEntityReference(), ...

    DOMImplementation 객체

     

    [표 9-16] hasFeature(), createDocument(), ...

    DocumentFragment 객체

    * Node 객체와 동일

    * Node 객체와 동일

    NodeList 객체

    length

    [표 9-17] getLength(), item()

    Element 객체

    tagName

    [표 9-18] Element의 속성에 접근
    getAttribute(), setAttribute(), getAttributeNode(), setAttributeNode(), removeAttribute(), ...,
    getTagName(), hasAttribute(), ...

    NamedNodeMap 객체

    length

    [표 9-19] NamedNodeMap 인터페이스
    getNamedItem(), setNamedItem(), removeNamedItem(), item(), getLength()

    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.*;
    ...
    class xxxxxx
    {
      public static void main(String[] args) throws Exception
      {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder  db = dbf.newDocumentBuilder();
        Document  xdoc1 = db.parse(new FileInputStream(arg[0]));
    ... 

  • 기존의 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 구문을 아래에 입력하고 '확인' 버튼을 클릭
      (예 : xdoc.text, xdoc.documentElement.firstChild.nodeName, ...)
     구문 :    

원하는 노드 찾아가기

  • 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 파일 경로 입력 또는 '찾아보기'로 선택

    'LOAD'로 파일을 메모리에 로드 :
      또는
    미리 작성되어 있는 파일 사용하기    

    원하는 검색 조건을 입력하고 '검색' 버튼 클릭

    1) 엘리먼트 또는 속성 이름 검색 :
        
    2) '텍스트 내용' 또는 속성값 검색 : 
        
    3) 조건검색 {이름, 비교, '내용'/값}
      

    <div id="resDiv">검색 결과</div>

문서에 새로운 노드 추가하기

  • 1단계. 문서객체 내에 신규 노드 만들기
        ① [신규 생성] 엘리먼트노드 = 문서.createElement(“태그이름”)
        ② [신규 생성] 데이터노드 = 문서.createTextNode(“노드값”)
        ③ [데이터 붙이기] 엘리먼트노드.appendChild(데이터노드)
  • 2단계. 원하는 노드 밑에 붙이기
        a) [원하는 위치에] 부모노드.appendChild(신규노드)
                            또는  부모노드.insertBefore(신규노드, 기존노드)
        b) [새문서, 특수노드의 경우] 문서.appendChild(신규노드)
                                            또는  문서.insertBefore(신규노드, 기존노드)

                      

  • 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 attr0 = xroot.firstChild.getAttributeNode('InStock');
     
    alert('[getAttributeNode] : ' + attr0.xml+ '\n' + attr0.name + attr0.value);

     var xroot=xdoc.documentElement;          
     var attr = xroot.firstChild.getAttribute('InStock');
     
    alert('[getAttribute] :'+ attr + '\n' + attr.name + attr.value);

새로운 속성 추가하기

  • A. 속성 노드 만들어서 붙이기
        ① [신규생성] 속성노드 = 문서.createAttribute(“속성명”)
        ② [속성값 설정] 속성노드.nodeValue = “속성값”
        ③ [속성 추가] 해당노드.attributes.setNamedItem(속성노드)
                   [또는] 해당노드.setAttributeNode(속성노드)
  • B. 속성값 설정하기
          
    해당 노드.setAttribute(“속성명”, “속성값”)
  •             

속성의 수정/삭제 

  • 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>
      ...
      <xml  id="xdoc"> </xml>
      <xml  id="xsldoc"> </xsl>
      ...
    </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);

      
     
    alert(newdoc);
     result
    .innerHTML=newdoc;
      
     result.
    innerText=" ... "

    <div id="result"> ... </div>
크리에이티브 커먼즈 라이센스
Creative Commons License
TAG.