소프트웨어/XML

XML 기본 내용

falconer 2007. 7. 10. 11:00


Dom이란 객체 덩어리이다.

웹 페이지와 관련된 잡업을 쉽게 할 수 있도록 유용한 기능의 많은 객체를

만들어서 그 객체의 이름을 DOM이라고 했습니다. 이 DOM은 자바스크립트

와 객체를 사용하는 vbscript에서도 사용할 수 있습니다.2007-07-09 17:38:47 월요일

DOM은 브라우저 안에 있습니다. 그래서 가끔 브라우저 내장 객체라고 부르는

사람도 있습니다.

간단히 말해서 DOM이란 웹 문서를 작성할 때 자유롭게 불러서 사용할 수

있는 객체 모델입니다.

DOM(Document Object Model)

  • W3C's definition

    "The Document Object Model is a platform- and language-neutral interface that will alㅋlow programs and scripts to dynamically access and update the content, structure and style of documents.

    • dynamic access and update
      • XML/HTML 문서의 접근 및 수정 - 내용/구조/스타일 검색 및 수정
    • interface
      • 응용 프로그램(스크립트 포함) 인터페이스 : API - 각종 메소드 및 속성을 정의
      • 플랫폼 및 언어 중립적 : Java, JavaScript, ASP, ...
  • DOM의 역할
    • 문서내 객체(element)를 조작하기 위한 인터페이스(API)
      • 구조의 탐색 및 조작 : 각 요소와 속성에 대한 검색/질의가 가능, 추가/수정/삭제가 가능
      • 컨텐츠의 조작 : 문서 요소에서 text 등 컨텐츠의 검색/추가/수정/삭제가 가능
    • 대상 문서 : XML1.0 또는 HTML4.0, 기타 웹문서
  • DOM 사양
    • DOM level 1 : 1998.10 W3C Recommendation
    • DOM level 2 : 2000.11 W3C Recommendation
    • DOM level 3 : 2001.8 W3C Working Draft

DOM and XML Parser

  • Parser
    • XML 문서를 읽고 해석 : well-formed, valid 검사
    • 응용프로그램 개발시 파서 사용 이유
      • 세부적인 XML 문법으로부터 프로그램 격리
      • 파서가 메모리에 DOM 트리를 생성 : XML 문서트리와 일치

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

    <parent>
        <child  id="123">text here</child>
     </parent>
     

  • 인터페이스(API)
    • 객체의 속성과 메소드를 사용하기 위한 사양
    • DOM 인터페이스 예
      - 문서.childNodes[0].nodeName
      - 문서.firstChild.firstCild.firstCild.nodeName
      - 문서.firstChild.firstCild.firstCild.nodeValue

DOM level 1 주요 API

  • DOM Core Interface (Object Hierachy)
  • 주요 객체/속성/메소드
    • p.330-335 : 설명생략 - 진행하면서 지속적으로 참조
    • 주요 객체에 대한 속성과 메소드 (괄호안은 W3C 표준이 아니라  MS에서 제공)

    객체(Object)

    속성(Properties)

    메소드(methods) 

    Document 객체

    doctype,
    documentElement, implementation,
    (async, readyState)

    createAttribute, createCDATASection, createComment, createEntityReference, createElement, ..., createTextNode, getElementByTagName,
    (load, loadXML, save)

    Node 객체

    nodeName, nodeType, nodeValue, childNodes, firstChild, lastChild, nextSibling, ..., (text, xml)

    hasChildNodes, cloneNode,
    appendChild, insertBefore,
    removeChild, replaceChild

    Element 객체

    tagName

    getAttribute, getAttributeNode,
    removeAttribute, ...,
    setAttribute, setAttributeNode

    Attribute 객체

    name, value


    CharacterData 객체

    data, length

    appendData, deleteData, insertData, replaceData, substringData

DOM 프로그래밍 시작 - Document 객체

  • 문서 객체 새로 만들기 : DOMDocument 객체 생성
    • Msxml.DOMDocument 객체 새로 만들기
    • 또는 HTML에서 <xml> 태그 이용

    JavaScript (JScript)

    <Script language="Javascript">
       
    var xdoc
       
    xdoc = new ActiveXObject("Msxml.DOMDocument");
        ...
    xdoc.load("ex08.xml");;
    </script>
    VBScript 의 경우 <Script language="VbScript">
      Dim xdoc
      Set xdoc = CreateObject("Msxml.DOMDocument")
      ...
    xdoc.load("ex08.xml");
    </Script>

    HTML에서 <xml>  태그 이용

    - MSXML 파서 설치안한 경우

    <HTML> <HEAD>
        <Script language="Javascript">
            xdoc.load("ex08.xml");    </script>
    </HEAD>
    <BODY>
        <xml id="xdoc"></xml>
    </BODY> </HTML>
  • 기존의 XML 문서 읽기
    • DOMDocument 객체 읽기 - async 속성, load 메소드, xml 속성
    MSXML 파서 설치한 경우   MSXML 파서 설치안한 경우  
    <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("ex07a.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 객체의 정보구하기

  • 속성 : nodeName, nodeType, nodeValue, attributes, text 속성
  • nodeType
    • 1 (element), 2 (attribute), 3 (text) , 4 (CDATA), 5 (Entity Reference)...  : [p.348] 
  •  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);
     

실습 프로그램

  • 파일 LOAD 및 DOM 명령 실행 (교재 s20-03.htm 과 s20-05.htm 혼합)

    XML 파일 경로를 직접 입력 또는  '찾아보기'로 선택, 'LOAD'로 파일을 메모리에 로드
    경로 :  =>

    사용하고자 하는 DOM 구문을 아래에 입력하고 '확인' 버튼을 클릭  (예 : xdoc.text, xdoc.documentElement.firstChild.nodeName, ...) 구문 :   

     <SCRIPT language="Javascript">
            var xdoc, rootNode;
            function
    FileLoad()
            {
                    xdoc = new ActiveXObject("Msxml2.DOMDocument");
                    xdoc.async = false;
                    xdoc.load(
    path.value);
                    if (xdoc.parseError.errorCode != 0)
                        alert("파일을 메모리로 로드하는데 실패하였습니다 : " + xdoc.parseError.reason);
     
                    rootNode = xdoc.documentElement;
                    alert("[파일로드 성공] 루트 엘리먼트 : " + rootNode.nodeName);
            }
            function Execute()
            {
                    var selectionString;
                    try {
                            selectionString = eval(syntax.value);
                    } catch(e) {
                            selectionString = null;
                    }
                    alert(selectionString);
            }
    </SCRIPT>  
     ...
    <BODY>
     ... 경로 : <input  type="file"  size="40"  id="
    path">
         <input  type="button"  value="LOAD"  onclick="
    FileLoad()">
     ... 구문 : <input  size="50"  id="
    syntax"  value="xdoc.">&nbsp;
         <input  type="button" onclick="
    Execute()" value=확인>
     ...
    </BODY>


//------------------------------------------------------------------------------






1. DOM이란?

DOM(Document Object Model)이란 용어는 한동안은 웹 브라우저에 적용되었다. 현대의 브라우저는 객체 모델을 통하여 브라우저의 서비스에 프로그램저그로 액세스할 수 있도록 한다. 대표적인 예가 HTML페이지내의 스크립트 언어이다. 윈도우, 문서, 그리고 히스토리와 같은 객체는 BOM(browser object model)의 한 부분으로 취급되어왔다. 그러나 웹 개발이 갑자기 폭발적으로 증가하고 마이크로소프트와 넷스케이프 사이의 경쟁으로 인하여 이 모델은 서로 다르게 구현되었고 동일한 코드를 적용하기가 어려워졌다. 웹에서 문서 구조를 액세스하고 조작하는 좀 더 표준적인 방법을 만들기 위해서 W3C는 현재의 W3C DOM이라는 스펙을 내놓았다. 이 스펙은 HTML문서에 대한 객체 모델과 XML문서에 대한 좀 더 일반화되 모델을 제공한다.

W3C DOM은 언어 중립적(language-neutral)이고 플랫폼 중립적(platform-neutral)인 정의이다. 즉, DOM을 구성하는 다른 객체에 대해 인터페이스는 정의하지만, 구현에 대해서는 어떤 스펙도 제공하지 않는다. DOM안에 있는 객체는 개발자가 문서로부터 데이터를 읽고, 탐색하고, 변경하고, 추가하며, 삭제할 수 있도록 한다. 또한 문서항해를 위한 표준적인 기능 정의를 제공하고, HTML문서와 XML문서의 내용과 구조를 조작할 수 있는 기능을 제공한다.

DOM은 어떤 플랫폼에서 어떤 프로그래밍 언어로도 구현할 수 있다. 예를 들어 DOM인터페이스를 데이터 액세스 함수들에 대한 랩퍼(wrapper)로 구현함으로써 데이터 저장소를 DOM을 사용하여 액세스할 수 있다.


2. DOM을 사용하는 이유

XML문서를 생성하고 액세스하기 위해서 DOM을 사용하면 다음과 같은 몇 가지 장점을 얻을 수 있다.

· DOM은 문법이 적절하고 well-formed 임을 보여준다.
· DOM은 문법으로부터 내용을 추출한다.
· DOM은 내부 문서 조작을 단순화한다.
· DOM은 전형적인 계층적 또는 관계형 데이터베이스 구조와 거의 유사하다.

이러한 내용에 대해 좀더 자세히 살펴보자.

(1) DOM은 문법이 적절하고 Well-formed임을 보장한다

DOM파서는 텍스트 파일을 노드 트리의 추상적 표현으로 변환하기 때문에, 당혀지지 않은 테그나 부적절하게 중첩된 태그와 같은 문제는 완벽하게 피할 수 있다. 게다가 DOM은 문서에서 부적절한 부모-자식 관계를 허용하지 않는다. 예를 들어 Attr객체는 다른 Attr객체의 부모가 될 수 없도록 만들 수 있다.

(2) DOM은 문법으로부터 내용을 추출한다

DOM에 의해 생성된 노드 트리는 XML 파일에서 발견할 수 있는 내용의 논리적이고 일관된 표현이다. 이것은 어떤 정보가 존재하는지, 그리고 XML 문법에 꼭 국한되지 않고도 어떻게 관계를 갖는지를 보여준다. 예를 들어, 노드에 의해 노출된 정보는 관계형 데이터베이스를 변경하거나 HTML페이지를 생성하기 위해 사용할 수 있다. 그리고 개발자는 XML언어의 세부 사항을 알 필요가 없다.

(3) DOM은 내부 문서 조작을 단순화한다

DOM을 사용하여 XML 파일을 수정하는 개발자는 손으로 같은 일을 하는 사람보다 좀더 쉽게 작업할 수 있다. 앞 예제에서 언급했던 것처럼, 문서의 중간에 요소를 추가하는 것 정도는 DOM을 사용하면 간단히 처리할 수 있다. 게다가 전역 처리는 몇 개의 명령을 혼합하여 수행할 수 있다. 만일 DOM을 사용하지 않는다면 파일을 직접 스캔하고 해당 태그들을 직접 제거해야 한다.

(4) DOM은 전형적인 계층적 또는 관계형 데이터베이스 구조와 거의 유사하다

DOM이 데이터 요소 사이의 관계를 표현하는 방법은 현대의 객체 지향형 데이터베이스와 관계형 데이터베이스에서 정보를 표현하는 방법과 매우 유사하다. 이는 데이터베이스와 DOM을 사용하는 XML 파일 사이의 정보 이동을 매우 쉽게 만든다.많은 데이터베이스는 눈송이 구조를 사용하여 계층적 정보를 표현한다. 이것은 차바퀴의 살과 같이 데이터베이스 안에 있는 정보가 중앙에 있는 '꼭대기 단계'테이블로부터 방사된다.

3. DOM 핵심 인터페이스에 대한 개관

이 절에서는 객체들과 문서 객체들을 가져오고 사용하기 위한 인터페이스에 대해 최소한의 정의를 내린다. DOM을 따르는 제품들에서는 이 절에서 명시된 기능(핵심 기능)을 이용하면, 소프트웨어 개발자들이나 웹 스크립트 작성자들이 분석된 HTML이나 XML의 내용을 가져와서 사용할 수 있다. 또한 DOM 핵심 API는 단지 DOM API 호출을 사용함으로서 문서 객체를 구축한다; 문서의 기본골격을 생성하고, 지속적으로 저장, 관리하는 것은 DOM API를 구현한 제품에서 수행해야 할 것이다.

(1) DOM 구조 모델

DOM은 문서를 노드 객체들의 계층구조로서 나타낸다. 각각의 노드 객체들은 특별한 인터페이스들을 제공한다. 문서의 구조에 있어서, 어떤 타입의 노드는 여러 가지 종류의 자식노드들을 가질 수 있고, 다른 노드는 하위에 아무것도 가지고 있지 않은 단말 노드들이 될 수 있다. 자식 노드로서 가질 수 있는 노드의 타입은 다음과 같다.

문서
문서조각
문서타입
엔터티참조
엘리먼트
속성
처리명령
주석
텍스트
CDATA섹션
엔터티
Notation(표기)

엘리먼트(maximum of one), 처리명령, 주석, 문서타입
엘리먼트, 처리명령, 주석, 텍스트, CDATA섹션, 엔터티참조
자식없음
엘리먼트, 처리명령, 주석, 텍스트, CDATA섹션, 엔터티참조
엘리먼트, 텍스트, 처리명령, CDATA섹션, 엔터티참조
텍스트, 엔터티참조
자식없음
자식없음
자식없음
자식없음
엘리먼트, 처리명령, 주석, 텍스트, CDATA섹션, 엔터티참조
자식없음

DOM은 NodeList 인터페이스를 명시한다. 이것은 노드의 자식, 또는 Element 인터페이스의 getElementsByTagName 메소드에 의해서 리턴되는 엘리먼트와 같이, 노드들의 정렬된 리스트들을 다루기 위해서 사용된다. 그리고 또한 이름 속성에 의해서 참조되는 노드들의 정렬되지 않은 집합을 다루기 위해서 NameNodeMap 인터페이스를 명시한다. 이것은 DOM에서 Element. NodeList나 NamedNodeMap의 속성들이 "살아있는" 것, 즉, 기본적인 문서 구조의 변화들이 모든 관련된 NodeList나 NameNodeMap에 반영된다는 것이다. 예를 들어 만약 DOM 사용자가 한 엘리먼트의 자식을 포함하고 있는 NodeList 객체를 얻고, 이어서 그 엘리먼트에 자식노드들을 추가한다면 (또는 자식노드를 삭제하거나, 수정한다면), 이러한 변화가 사용자 측면에서 다른 작용없이 자동적으로 NodeList에 반영되어야 한다. 더욱이 트리안의 노드에 대한 변화가 NodeList나 NameNodeMap안의 노드에 대한 모든 참조에서도 반영되어야 한다.

마지막으로, 텍스트, 주석, CDATA섹션의 인터페이스들은 CharacterData 인터페이스로부터 모두 상속받는다.

(2) 메모리 관리

이 스펙에서 정의된 대부분의 API들은 클래스라기 보다는 인터페이스이다. 이것은 실제로 인터페이스에 정확히 일치하는 클래스를 구현하는 것이 아니라 단지, 정의된 이름과 지정된 동작을 가진 메소드를 나타낼 수 있도록 실제로 구현하는 것이다. DOM API는 자신의 데이터 구조를 가지고 있던 애플리케이션들 위에, 또는 전혀 다른 클래스 구조를 가진 새로운 애플리케이션들 위에 얇은 겉포장으로 구현될 수 있다. 이것은 또한 일반적인 작성자(자바나 C++에을 사용하는)가 DOM 객체들을 생성하기 위해 사용될 수 없다는 것을 의미한다. 왜냐하면 이미 구성되어 있는 기본적인 객체들이 DOM 인터페이스와 전혀 관계가 없기 때문이다. 객체지향 디자인에서 이것에 대한 상투적인 해결책은 여러 인터페이스들을 구현한 객체의 인스턴스를 생성하는 factory 메소드를 정의하는 것이다. 어떤 인터페이스 "X"를 구현하는 객체들은 Document 인터페이스에서 "CreateX()"메소드에 의해서 생성된다; 이것은 모든 DOM 객체들이 지정된 문서의 내용에 존재하기 때문이다.

DOM 레벨 2 API는 DOMImplementation 또는 Document 객체를 생성하기 위한 표준 방식을 정의하지는 않는다; 실제 DOM을 구현할 때, 이러한 DOM 인터페이스를 동작시키는 어떤 방식을 제공해야만 한다. 그리고 나서 다른 모든 객체들은 Document의 Crate 메소드(또는 다른 편리한 메소드)로부터 만들어질 수 있다.

핵심 DOM API들은 일반적인 사용자의 스크립트 언어들이나, 대부분 전문 프로그래머들에 의해 사용되는 간단하지 않은 언어들까지 포함해서, 다양한 언어들과 호환되도록 디자인되어 있다. 그래서 DOM API들은 다양한 메모리 관리 방침을 사용해 작동할 필요가 있다. 메모리 관리가 사용자에게 전혀 드러나지 않는 언어의 플랫폼들에서부터, 사용하지 않는 메모리를 자동으로 다시 요구하는 자동 쓰레기 수집(automatic gabage collection)을 제공하지만 제작자에게 명시적으로 보여주는 언어(자바와 같은 언어)들 뿐만 아니라, 일반적으로 프로그래머가 명시적으로 객체에 메모리를 할당하고, 어디에서 사용되는지 추적하고 재사용을 위해 직접 해제하는 것을 요구하는 언어(특히 C/C++)들까지 포함하기 위해서이다. 이러한 플랫폼들 사이에 일관된 API를 보장하기 위해서 메모리 관리문제를 전혀 다루지 않고 대신 구현시에 수행할 수 있도록 하고 있다. DOM 워킹그룹(ECMA Script 와 자바를 위한)에 의해서 고안된 명시적인 언어 규칙중 어느 것도 메모리 관리를 위한 메소드를 요구하지 않는다. 그러나 다른 언어(특히 C나 C++)를 위한 DOM 규칙은 아마도 이러한 메모리 관리 지원을 요구할 것이다. 그러나 이것은 DOM 워킹 그룹이 아니라, 특정 언어로 DOM API를 적용하려는 사람들이 확장시켜야 할 것이다.

(3) 이름 관행 (Naming Convention)

속성이나 메소드의 이름들이 짧고, 정보량이 많고, 내부적으로 일관되고, 유사한 API의 사용자들에게 친숙한 것은 좋은 반면에, 이러한 이름들이 DOM 구현시 지원되는 옛날의 API들에서 사용되는 이름들과 충돌하지 않아야만 한다. 더구나 OMG IDL과 ECMAScript 둘다 이름의 충돌을 피하기 위한 능력에서 커다란 한계를 가지고 있다. 그래서 DOM 이름들은 모든 환경에서 유일하기 위해서 길고 아주 설명적인 경향이 있다.

또한, 워킹 그룹은 다른 API에서의 이름의 구별과 다를지라도, 여러 용어의 사용에 있어서 내부적인 일관성을 유지하려고 시도하고 있다. 예를 들어, 구조 모델을 바꾸는 메소드는 "remove"란 메소드 이름을 사용하고, 구조 모델 내부의 무언가를 제거하는 메소드를 "delete"란 메소드 이름으로 사용한다. "delete"되는 것은 리턴되지 않고, "remove"된 것은 성공하면 리턴되어질 것이다.

(4) API의 상속과 Flattened View

DOM 핵심 API들은 XML/HTML 문서에 대한 두 개의 약간 다른 부류의 인터페이스들을 나타낸다; 하나는 상속이란 계층을 가지는 "객체 지향"적인 접근을 나타내는 것이고, 다른 하나는 모든 조작들이 Node 인터페이스를 통해서 수행되도록 하는 "단순화된" 관점을 나타낸다. 이 Node 인터페이스는 COM 환경에서 호출하는 질의 인터페이스나 외형적인 형태(자바나 C와 같은 언어들에서처럼)를 요구하지 않는다. 이러한 두가지의 동작들은 자바와 COM에서 상당히 많은 비용이 들어가고 그래서 DOM은 성능이 중요한 요소로 작용하는 환경에서 사용되어 질 것이다. 그러므로 단지 Node 인터페이스를 사용함으로서 중요한 기능을 사용할 수 있게 하고 있다. 또, 많은 사용자들이 DOM에서 "모든 것을 노드"로 접근하는 것보다 계층적인 상속을 더 쉽다고 느끼기 때문에, 객체 지향 API를 선호하는 사람들을 위한 보다 높은 레벨의 인터페이스도 지원할 것이다.

실제로, 이것은 API에서 상당한 중복을 초래할 수 있다. 워킹 그룹은 "상속"의 접근을 API의 주요 관점으로 고려하고 있고 그리고 Node에서 전체 기능은 사용자들이 필요로 하는 "여분의" 기능으로 검토하고 있다. 그러나 그것은 객체지향 분석을 강요하는 다른 인터페이스들에서 메소드를 위한 요구를 무시하지는 않는다. (물론, 객체지향 분석이 노드 인터페이스와 같은 속성이나 메소드를 만들어 낼 때, 중복되었다는 것을 명시하지는 않는다.) 그래서, Node 인터페이스에서 일반적인 NodeName 속성이 있을지라도, 여전히 엘리먼트 인터페이스에서의 tagName 속성이 존재한다; 이러한 두가지 속성들은 DOM API가 만족해야하는 다른 구성요소에서 주어진 같은 값을 가지고 있지만, 워킹 그룹은 두가지 모두 지원할 가치가 있다고 여기고 있다

(5) DOMString 타입

상호교환을 위해서, DOM은 다음과 같이 DOMString 타입을 명시하고 있다.

Type Definition DOMString

이때의 DOMString은 연속적인 16비트 길이이다.

IDL Definition

typedef sequence<unsigned short> DOMString;

애플리케이션들은 UTF-16을 사용해서 DOMString을 인코딩 해야한다. UTF-16 인코딩은 광범위한 연구 실행 때문에 선택되어졌다. HTML과 XML을 위한 문서의 문자셋(그리고, 숫자참조를 위한 표기)은 UCS[ISO-10646]에 기반을 두고 있음을 유의해야 한다. 어떤 경우에 소스문서에 있어서 하나의 숫자 참조는 DOMString에서 2개의 16비트 유닛과 일치할 수 있다.

메모: DOM이 문자열 타입의 이름을 DOMString이라고 정의한다 할지라도, 바인딩시에 다른 이름들을 사용할 수 있다. 예를 들어 자바에서 DOMString은 인코딩으로서 UTF-16을 사용하기 때문에 String 타입으로 사용된다.

메모: 1998년 8월, OMG IDL 스펙은 wstring 타입을 포함하고 있다. 그러나 문자의 길이를 결정하는 인코딩 협상에 의존하고 있기 때문에 DOM API의 상호교환을 위한 기준을 제공하지 못하고 있다.

(6) DOM에서 문자열 비교

DOM은 문자열 일치를 내포하고 있는 많은 인터페이스들을 가지고 있다. HTML 프로세서들은 일반적으로 엘리먼트로서 표준 이름을 대문자(가끔, 소문자)로 가정한다. 반면에 XML은 명시적으로 대소문자를 구분한다. DOM의 목적에 있어서, 문자열 일치는 DOMString의 16비트 단위의 이진비교로 수행된다. 그래서 DOM 구조가 만들어지기 전에, 어떤 표준화가 해당 프로세서 안에서 정해질 것이라고 DOM은 가정한다.

메모: 이것은 무슨 표준화가 발생하는냐에 대한 논쟁을 야기한다. W3C 118N 워킹 그룹은 어떤 표준화가 DOM을 구현하는 애플리케이션을 위해 필요한지를 정의하고 있는 중이다.

(7) XML Namespaces

DOM 레벨 2는 namespace와 연관된 엘리먼트나 속성들을 생성하고 조작하기 위한 DOM 레벨 1의 몇가지 인터페이스들을 확대함으로서 XML Namespace들을 지원한다.

DOM에 관한한, XML namespace를 선언하기 위해 사용된 특별한 속성들은 다른 속성들과 같이 다루어질 수 있다. 그러나 노드들은 생성되어진대로 영구적으로 namespace URI들과 연결되어야 한다. 그 결과 DOM의 사용에 있어서, 문서내에서 노드를 이동하는 것은 어떤 경우라도 namespace prefix나 namespace URI의 변화를 가져오지는 않는다. 유사하게, namespace prefix와 namespace URI를 가진 노드의 생성이나, 노드의 namespace prefx를 변경하는 것은, 적절한 XML namespace를 선언하기 위한 특별한 속성들의 추가, 제거, 수정을 초래하지는 않는다. Namespace의 유효성을 강요하지는 않는다.; DOM의 구현에 책임이 있다. 특히 prefix들과 namespace URI들이 강요되지 않기 때문에, 일반적으로 결과 문서는 일관적이지 않다. 예를들어, 애플리케이션은 문서가 연속적일 때 사용중인 모든 namespace를 선언할수 있다.

namespace가 없는 문서에서, 엔터티참조 노드의 자식 리스트는 항상 관계된 엔터티와 같다. 이것은 엔터티가 연결되지 않은 namespace prefix를 포함한 문서에서는 진실이 아니다. 그러한 경우에 관계된 엔터티참조의 자손들은 엔터티 참조에 의존하고 있는 다른 namespace URI들과 연결되어 있다. 더욱이, DOM에서 노드들은 항상 같은 namespace URI들과 연결되기 때문에 엔터티 참조 노드를 이동하는 것은 serialize하지 않은 문서를 발생하게 한다.
이것은 또한 다음측면에서 사실이다. DOM 레벨 1 메소드 Document 인터페이스의 createEntityReference가 엔터티에 일치하는 엔터티 참조를 생성하기 위해 사용되어 질 때 리턴된 엔터티참조의 자손들이 연결되지 않기 때문이다. DOM 레벨 2는 namespace prefix를 해결하기 위한 어떠한 구조도 지원하지 않는다. 이런 모든 이유 때문에, 엔터티와 엔터티 참조의 사용은 피하거나 극도로 조심스럽게 사용되어 진다. DOM의 다음 레벨에서는 이것을 다루기 위한 몇 개의 부가적인 지원을 포함할 것이다.

Document 인터페이스의 createElementNS와 createAttributeNS와 같은 새로운 메소드들은 namespace에 정통한 애플리케이션에서 사용되어지도록 정의되어 있다. namespace를 사용하지 않는 단순한 애플리케이션은 createElement나 createAttribute같은 DOM 레벨 1 메소드들을 사용할수 있다. 이러한 방식으로 생성된 엘리먼트들이나 속성들은 namespace prefix, namespace URI, 그리고 local name을 가지고 있지는 않다.

메모 : namespace를 다루지 않을 때 DOM 레벨 1을 사용하는 것은 안전한 반면에, 동시에 새로운 것들을 사용하는 것은 피해야만 한다. namespace와 관계가 없는 DOM 레벨 1 메소드들은, nodename에 의해서만 속성 노드들을 식별해야 한다. 반대로, namespace와 관련된 DOM 레벨 2 메소드들은 namespaceURI와 localName에 의해서 속성노드들을 식별할 수 있다. 이러한 기본적인 차이 때문에, 두 부류의 메소드들을 혼합하는 것은 예측하지 못한 결과들을 가져오게 된다. 특히, setAttributeNS를 사용하는 것은 하나의 엘리먼트에 같은 nodeName을 가지고 있지만, 다른 namespaceURI를 가지고 있는 두 개 이상의 속성을 설정할 수 있다. 그러한 nodeName에서 getAttribute를 호출하는 것은 여러 속성들중의 어느 하나를 리턴할 수 있다. 그결과는 구현에 의존적이게 된다. 유사하게 setAttributeNode를 사용하는 것은 같은 prefix와 namespaceURI를 가지고 있지만 다른 nodeName을 가지고 있는 두 개 이상의 속성을 설정할 수 있다. 이러한 경우에 getAttributeNodeNS는 플랫폼에 의존해서, 어느 하나를 리턴할 것이다. 그러한 경우에 유일한 보장은 setAttribute와 setAttributeNS가 각각 getAttirbute와 getAttributeNS가 리턴한 노드에 영향을 주는 것이다.



//------------------------------------------------------------------------------






1. DOM의 여러가지 타입

DOM은 XML에서 뿐만 아니라 HTML안의 객체 모델에 대한 필요성을 말하고 있다. Well formed HTML문서 역시 XML문서이기 때문이다. XMLDOM은 CoreDOM으로 언급된다.

(1) DOM Level 1

core, HTML & XML 문서 모델에 관한 내용을 담고 있다.
navigation & manipulation

[특징]

1) Core DOM 기반으로 HTML 문서 핸들링을 위한 인터페이스

2) HTML에 맞는 인터페이스만 추가로 정의

3) HTML4.0에 정의 된 모든 태그에 대해 각각의 타입 등록

4) HTML 태그 각 고유의 추가적인 속성 및 기능 지님

(2) DOM Level 2

style sheet를 적용한 객체 모델 지원한다.
문서에 대한 style 정보를 manipulation하는 기능을 정의한다.

[특징]

1) 문서의 문맥과 구조 그리고 스타일을 동적으로 접근하고 갱신하기 위한 플랫폼, 중간 언어 인터페이스

2) XML, HTML, 추상적 뷰, 일반적 스타일 시트, CSS, 이벤트, 문서 구조와 객체 범위의 변화를 결정하기 위한 구체적인 인터페이스

3) DOM Level 1 Core을 기반으로 작성

4) DOM Level 1 Core Vs. DOM Level 2 Core
     DOM Level 2 specifications 은 CORBA 2.2 대신 CORBA 2.3.1 을 사용
     DOM Level 1 Core interfaces와 exceptions 변화
     Type의 변화

5) DOM Level 2 Views
     DOM Level 2 Core기반에서 작성
     문서를 표현하는 내용을 업데이트
     동적으로 접근하기 위한 스크립트나 프로그램을 위한 인터페이스를 정의

6) DOM Level 2 Events
     DOM Level 2 Core 와 DOM Level 2 Views 에서 프로그램
     일반적인 이벤트 시스템에 스크립트나 프로그램을 위한 인터페이스 정의

7) DOM Level 2 Style
     DOM Level 2 Core와 DOM Level 2 Views 기반 위에서 작성
     문서의 스타일이나 내용을 업데이트
     스크립트나 프로그램을 작성하는 인터페이스나 DOM Level 2 Style Sheets , CSS를 정의

(3) DOM Level 3

DOM Level 2 Core 에 기반을 두고 있다.
Namespace나 문서의 스타일, 내용, 구조에 동적 접근 및 갱신이 가능한 확장 인터페이스를 제공해 준다.

[특징]

1) DOM Level 2 Event Specification에 명시된 기능을 확장

2) DOM Level 2에 이미 정의된 modules을 새로운 인터페이스로 추가

3) DOM Level 2에 이미 정의된 interface들을 기본으로 설계

4) Core Requirements

     White space 처리
     XML 선언과 CDATASection 선언의 명확성 구분
     특정 클래스를 사용하기 위해 Java에서 DOM 로딩
     노드 식별
     Namespace의 검색과 수정
     예외사항 처리
     노드 정렬 처리
     다른 문서로의 노드 이동(Moving)

5) Events Requirements

     Level2 의 Events Spec에서 처리되지 않고 언급되지 않은 Event들을 처리
     EventListener grouping
     Key event set
          키보드 입력을 다루는 Key event들의 집합
     Input event set
          키보드 입력에 기반한 IME(Input Method Editor)를 다루는 Input event들의 집합
     Device independent event set

DOM Level 0의 스펙은 존재하지 않지만 타이틀은 마이크로소프트 인터넷익스플로러 3과 넷스케이프3에서 나타난 HTML DOM의 결합을 언급하고 있다.

2. 트리모델

XML은 계층언어이다. XML문서에 포함되어 있는 태그들은 부모자식관계를 가지고 있다. 때문에 자연스럽게 트리로 표현할 수 있다. DOM스펙에서는 XML내부문서의 구조가 트리여야만 된다고 언급하지는 않는다. 차라리 인터페이스의 집합이 직접적으로 트리모양의 개념적인 모델로 이끌고 있다.

즉 다시 말하자면 DOM인터 페이스가 XML문서를 트리로 표현한다는 것을 파서의 사용자에게 알려준다.

XML문서안의 앨리먼트 또는 애트리뷰트와 같은 각 구조는 트리안에서 노드로 표현되고, 이 트리 표현법은 객체지향원칙으로 디자인되어 있다. XML구조를 표현하는 노드들은 그들 각 고유의 프로퍼티와 메소드 집합을 가지고 있고 기본클래스로부터 기능을 공유하게 된다. 모든 노드에 있는 몇몇 기능은 트리를 검색하는데 필요한 메카니즘과 노드의 내용을 조작할 능력을 포함하고 있다.

(1) 기본 인터페이스

1) DOM Exception

DOM operations의 예외적인 상황에서 예외 처리

2) DOM Implementation

Operation를 수행하기 위한 많은 method 제공

3) DocumentFragment

"lightweight" or "minimal" Document object

4) Document

HTML 또는 XML 문서 표현
문서의 root는 tree를 개념적으로 표현

5) Node

DOM의 주된 datatype
document tree에서 단일 노드 표현

6) NodeList

Node들의 집합에서 node의 추출

7) NamedNodeMap

Name으로 접근할 수 있는 node들을 나타내는데 사용
NodeList로 부터 상속을 받지 못함

8) CharacterData

character data 의 method나 attributes의 집합을 가진 확장된 Node

9) Attr (Attribute)

Element object의 속성을 표현

10) Text

Element 나 Attr의 문맥적 내용을 표현

11) Comment

주석을 표현

(2) 확장 인터페이스

1) DocumentType

엔티티 정보, Notation 정보, DTD 문서형을 취급

2) Entity

DocumentType의 속성값으로 DOM 트리 구성에서 제외
EntityReference에 의해 DOM 트리에 삽입

3) EntityReference(엔티티 참조)

4) Notation(표기법 선언)

5) ProcessingInstruction(처리명령)

6) CDATASection(CDATA 섹션 처리)

(3) DOM 인터페이스의 개념적 구조


//------------------------------------------------------------------------------






1. 여러가지 다른 노드 타입

각 노드 타입은 Node라고 부르는 기본클래스로부터 파생되었다. 개발자는 고유의 노드를 생성하지는 않지만 다음에 나타나는 노드들 중 하나를 생성하여 XML문서의 한부분에 대한 적당한 행위를 수행할 수 있다. 이러한 노드들은 각각 nodeType 프로퍼티를 통하여 그들 자신을 식별할 수 있는데, 이는 숫자가 모든 노드에 배정되고 nodeType은 특별한 노드에 연결된 숫자를 반환하여 준다.

또한 노드는 이름과 값을 가지고 있다.

nodeType
nodeType에 따른 숫자
Element
1
Attribute
2
Text
3
CDATASection
4
EntityReferance
5
Entity
6
ProcessingInstruction
7
Comment
8
Document
9
DocumentType
10
DocumentFragment
11
Notation
12


(1) Document

Document 노드는 마스터 노드이다. 많은 노드들중에 오직 하나만이 XML문서를 위하여 존재할 수 있다. 이 노드는 맨위에 있는 부모노드이고 XML문서 전체를 표현한다. 즉, Document는 XML문서의 특정부분을 나타내는 것이 아니라는 것이다. 그리고 이 노드는 다른 노드를 생성하는 기능을 가지고 있다.

(2) NodeList

NodeList 노드는 자식 노드들을 유지하기 위하여 사용되는 노드이다. 현재 얼마나 많은 자식들이 있는지, 반복구조 기능을 이용할 수 있는 특징을 가지고 있는지를 부모노드에게 알려준다. 하지만 모든 노드가 NodeList 콜렉션을 가질 수 없다. 왜냐하면 NodeList는 개념적으로 주어진 자식노드들에게 접근하기 위한 도구일 뿐이기 때문이다. 즉, 자식노드를 그룹화 시키는데 사용할 뿐이다.

(3) NamedNodeMap

NodeList와 비슷하지만 그들의 이름을 사용하여 자식노드에 접근하는 부가 기능을 가지고 있다. 이 기능은 애트리뷰트에 접근하고자 할때 필요하다. 그 결과로 NamedNodeMap 노드는 애트리뷰트 노드를 유지하는데 사용된다는 얘기다.

(4) Element

Element 노드 타입은 XML문서에 있는 엘리먼트를 포함한다. 그리고 엘리먼트안에 선언된 애트리뷰트에 접근해서 관리하는 특별한 도구를 가지고 있다. Element노드는 Document노드의 자식인 맨위에 존재하는 엘리먼트를 제외하고는 모두 다른 엘리먼트의 자식들이다. 이때 맨위에 존재하는 Element를 documentElement라고 말하며, 바로 Root Element이다.

<root>
    <some/>
</root>


위의 예제에서 <root>는 Document노드의 자식이고, <some>은 root Element 노드의 자식이다.

(5) Text

Text 노드는 태그안에 포함된 엘리먼텍스트를 나타낸다. 다음의 XML문서는 name Element 노드의 자식인 Text 노드를 만든다. 이 Text 노드는 'Mydosu'라는 값을 포함하고 있다.

<root>
    <name>Mydosu</name>
</root>

(6) Attr(Attribute)

Attr 노드 타입은 엘리먼트 범위안에 선언된 애트리뷰트를 나타낸다. 다음 XML 예제를 자세히 보도록 하자.

<root myatt="value"/>

이 예제의 트리보델은 다음과 같다. 애트리뷰트에 관여하는 노드와 마지막의 text 노드도 눈여겨 보도록 하자.

(7) CDATASection

CDATASection 노드는 Text 노드와 비슷하지만 마크업을 포함 할 수 있다.

<root><![CDATA[<b>Kim</b>]]></root>

(8) DocumentType

DocumentType노드는 DTD의 작은 부분 집합이다. DTD의 전부를 보여 주지 못한다는 것이다. 단지 <!ENTITY>와 <!NOTATION>만을 나타낸다.

<!DOCTYPE root [
<!ELEMENT root (#PCDATA)>
]>
<root>TEXT</root>

(9) Entity

Entity 노드는 DTD에서 사용된 <!ENTITY> 태크표현방식을 제공해 준다. 이때 Entity노드의 부모노드는 DocumentType 노드이다. system id, public id, notation name과 같은 엔티티의 여러가지 프로퍼티가 Attr 노드로 모델화 되고 Entity 노드의 자식으로 자리잡는다.

(10) Notation

Notation 노드는 DTD에서 사용된 <!NOTATION> 태크표현방식을 제공해 준다. 이때 Notation 노드의 부모노드는 DocumentType 노드이다. system id, public id, notation name과 같은 엔티티의 여러가지 프로퍼티가 Attr 노드로 모델화 되고 Notation 노드의 자식으로 자리잡는다.

<!DOCTYPE root [
<!ELEMENT root (#PCDATA)>
<!ENTITY sample SYSTEM "http://ss.hh.com/sample.xml">
<!NOTATION gif SYSTEM "http://ss.hh.com/gif/gifviewer.exe">
]>
<root>TEXT</root>



(11) ProcessingInstruction

ProcessingInstruction 노드는 PI를 표현한다. Document 노드의 자식이다.

(12) Comment

Comment 노드는 <!-- -->를 표현한다. Comment 노드는 XML구조에 관한 주석을 XML문서 트리에 삽입한다.

(13) DocumentFragment

DocumentFragment 노드는 Document 노드의 일부분이다. 이 노드는 이동할 때 위치소유자가 사용된다. 이 노드는 Document 노드의 충분한 능력을 갖고 있지 않다. 왜냐하면 트리에 재입력되는 노드를 위한 임시기억장소이기 때문이다.

다음의 예제 XML을 이용하여 DOM tree 구조를 각자 그려 보도록 하라.

<?xml version="1.0" encoding="euc-kr">

<GOODSLIST>
<!-- Result from a query -->
   <good no="1012345">
      <name>빠삐코</name>
      <price>500원</price>
   </good>
   <good no="2022346">
      <name>맛동산</name>
      <price>600원</price>
   </good>
</GOODSLIST>



//------------------------------------------------------------------------------






1. 기본 사용법

이 강의에서 기본적으로 사용하는 방법에 대해서 말하겠다. 일단 간단한 예제를 사용하기 위한 브라우저와 자바스크립트를 이용할 것이니까 HTML을 바탕으로 하는 것이 좋겠다. HTML을 바탕으로 한다면 XML문서를 데이터섬으로 불러서 활용하면 되겠다.

기본형태를 한번보면 이해할 것이다.

<HTML>
<HEAD>
<TITLE> New Document </TITLE>
</HEAD>

<BODY>

<xml id="xml">
<root>
<element1/>
<element2/>
<element3/>
</root>
</xml>

<script language="javascript">

var rootNode=xml.documentElement;
var alsoRootNode=xml.childNodes.item(0);

var element1=xml.documentElement.childNodes.item(0);
var element2=rootNode.childNodes.item(1);
var element3=xml.childNodes.item(0).childNodes.item(2);

confirm(rootNode.nodeName);
confirm(xml.xml);
</script>

</BODY>
</HTML>


뭐...대충 이런식이다. 예전에 배운것처럼 일단 예제용 XML문서를 하나 만들어 두고 그 파일을 링크 시킨 다음 사용해도 된다.

일단 이번 강의의 목적은 표준 DOM을 익히는 것이다. Application 마다 고유한 파싱과 메소드들을 제공해 주는 것도 있지만 일단 표준을 알고 지나가는 것이 좋을 것이다.

2. 모든 것이 Node

일단 DOM Level 1에서 보았던 그림을 한번 더 보자

위의 그림은 클래스의 상속성을 나타내기도 한다. 그림에서 처럼 부모를 가지고 있는 모든 클래스는 부모가 가지고 있는 모든 프로퍼티와 메소드를 얻게 된다. 즉, Node에서 시작된다는 것이다. 하지만 Node는 다른 클래스를 파생시킬때만 사용되고 직접적으로 나타나지는 않는다.

그리고 NodeList와 NamedNodeMap노드는 예외다. 이것은 기본 클래스를 가지지 않는다.

3. Node

(1) 부모노드

Node의 부모노드는 없다.

(2) Node Propeties

1) nodeName

타 입
DOMstring
설 명
노드의 이름을 나타낸다. 이 프로퍼티가 사용되는 노드의 타입에 의거하여 결과 값이 변한다. 아래 표는 중요하게 사용되는 nodeName의 노드타입은 Element와 Attribute인것을 보여준다.

노드타입
nodeName 프로퍼티
Document
Element
Attribute
Text
CDATASection
Comment
Entity
Notation
EntityResference
PricessingInstruction
DocumentType
DocumentFragment

#document
element
attribute
#text
#cdata-section
#comment
entity name
notation name
name of entity resferenced
target(the first word following the <?)
document type name
#document-fragment


<HTML>

<BODY>

<script language=javascript for=window event="onload">
confirm(xml.documentElement.nodeName);
confirm(xml.documentElement.attributes.item(0).nodeName);
</script>
<xml id = "xml">
<엘레먼트이름 애트리뷰트이름 = "hello" />
</xml>
</BODY>
</HTML>


2) nodeValue

타 입
DOMstring
설 명
노드안에 포함된 데이터를 나타낸다. 이 프로퍼티가 사용되는 노드의 타입에 의존하여 결과 값이 변한다. 아래 표는 nodeValue의 행위를 보여준다.

노드타입
nodeName 프로퍼티
Document
Element
Attribute
Text
CDATASection
Comment
Entity
Notation
EntityResference
PricessingInstruction
DocumentType
DocumentFragment

null
null
attribute value
text
text
comment text
null
null
null
text(target안에 있는 노든 내용)
null
null


3) nodeType

타 입
unsigned short
설 명
노드타입을 나타내는 정수를 알려준다. 아래표는 노드타입에 따른 정수값이다.

nodeType
nodeType에 따른 숫자
Element
1
Attribute
2
Text
3
CDATASection
4
EntityReferance
5
Entity
6
ProcessingInstruction
7
Comment
8
Document
9
DocumentType
10
DocumentFragment
11
Notation
12

<HTML>
<BODY>

<script language=javascript for=window event="onload">
confirm(xml.documentElement.nodeName);
confirm(xml.documentElement.nodeType);
confirm(xml.documentElement.attributes.item(0).nodeValue);
confirm(xml.documentElement.attributes.item(0).nodeType);
confirm(xml.documentElement.attributes.item(1).nodeValue);
confirm(xml.documentElement.attributes.item(1).nodeType);
confirm(xml.documentElement.childNodes.item(0).nodeValue);
confirm(xml.documentElement.childNodes.item(0).nodeType);
</script>

<xml id = "xml">
<someElement someAttribute = "애트리뷰트값" nextAttribute="두번째애트리뷰트값">
엘리멘트 내용을 기술하세여!
</someElement>
</xml>

</BODY>
</HTML>

4) childNodes

타 입
nodeLiat
설 명
노드의 모든 자식노드를 보유한 nodeList 콜렉션이다. 노드가 자식을 가지지 않더라도 nodeList는 리턴된다. 단지 childNode의 length가 0으로 설정될 뿐이다.

5) attributes

타 입
namedNodeMap노드
설 명
노드의 모든 자식노드를 보유한 namedNodeMap 콜렉션이다. 애트리뷰트 프로퍼티가 엘레멘트, 엔티티, 노테이션이 아닌 모든 노드에 대해서는 0으로 설정해 놓는다. 애트리뷰트를 가지지 않더라도 namedNodeMap은 리턴된다.


6) parentNode

타 입
node
설 명
노드의 부모노드를 지시하는 포인터다. nodeList콜렉션은 노드 바로 위에 있지만 parentNode는 nodeList 콜렉션 위의 노드를 가리킨다.

<html>
<script language="javascript" for="window" event="onload">
confirm(xml.documentElement.nodeName);
confirm(xml.documentElement.childNodes.item(0).parentNode.nodeName);
</script>
<xml id="xml">
<element1>
<element2/>
</element1>
</xml>
</html>


7) firstChild

타 입
node
설 명
노드의 첫번째 자식노드를 나타낸다. 자식이 없으면면 null로 설정된다.
myNode.firstChild 와 myNode.childNoeds.item(0)은 서로 같다.

8) lastChild

타 입
node
설 명
노드의 마지막 자식노드를 나타낸다. 자식이 없으면 null로 설정된다.
myNode.lastChild 와 myNode.childNoeds.item( myNode.childNoeds.length-1)은 서로 같다.

<html>
<script language="javascript" for="window" event="onload">
var myNode = xml.documentElement;
confirm(myNode.lastChild.nodeName);
confirm(myNode.childNodes.item(myNode.childNodes.length-1).nodeName);
</script>
<xml id = "xml">
<root>
<element1/>
<element2/>
<element3/>
</root>
</xml>
</html>


9) previousSibling

타 입
node
설 명
한 노드가 부모노드를 가지고 있고 그 부모의 자식이 현재노드 왼쪽에 있는 노드를 나타낸다. 만약에 이 자식노드가 존재하지 않는다면 null로 설정된다.

10) nextSibling

타 입
node
설 명
한 노드가 부모노드를 가지고 있고 그 부모의 자식이 현재노드 오른쪽에 있는 노드를 나타낸다. 만약에 이 자식노드가 존재하지 않는다면 null로 설정된다.

11) ownerDocument

타 입
document
설 명
현재 노드가 자리잡고 있는 DOM 트리의 Document 노드를 나타낸다. 노드를 생성할 수 있는 노드는 Document 노드이기 때문에 Document 노드로 쉽게 접근할 수 있는 방법으로 유용하다.

<HTML>

<BODY>

<script language=javascript for=window event="onload">

var myNode=xml.documentElement ;

confirm(xml.documentElement.nodeName);
confirm(xml.documentElement.nodeType);
confirm(xml.documentElement.childNodes.item(0).nodeValue);
confirm(xml.documentElement.childNodes.item(0).parentNode.nodeName);
confirm(xml.documentElement.childNodes.item(1).nodeName);
confirm(xml.documentElement.childNodes.item(1).parentNode.nodeName);
confirm(xml.documentElement.firstChild.nodeName);
confirm(xml.documentElement.childNodes.item(0).nextSibling.nodeName);
confirm(xml.documentElement.lastChild.nodeName);
confirm(xml.documentElement.childNodes.item(myNode.childNodes.length-1).previousSibling.nodeName);
confirm(xml.documentElement.childNodes.item(0).ownerDocument.nodeName);
confirm(xml.documentElement.childNodes.item(myNode.childNodes.length-1).childNodes.item(0).nodeValue);
</script>

<xml id = "xml">
<rootElement >
이글은 childNode입니다.
<subElement1 />
<subElement2 />
<subElement3 />
<lastElement>
에구구!
</lastElement>
</rootElement>
</xml>

</BODY>
</HTML>


(2) Node Methods

이제 부터 가술할 내용들은 주로 노드의 자식들을 관리하고 조작하기 위한 메소드들이다. 노드가 모두 다른 타입의 노드이기 때문에 비록 상속받은 메소드가 의미가 없더라도 따라오는 메소드는 상속을 받게 된다. 하지만 자식을 가질 수 없는 노드에게 자식에 영향을 미치는 메소드를 사용하면 에러가 발생하니 유의하자.

1) insertBefor(newChild,refChild)

인자
newChild와 refChild는 Node이다.
반환값
Node
예외처리
DOMException
설명
기존의 자식노드인 refChild앞에 newChild노드를 삽입한다.
만약 refChild가 null로 설정되면 자식리스트의 맨마지막에 삽입된다. refChild존재하지 않거나 newChild가 주어진 부모에 허용될 수 없다면 에러난다.

2) replaceChild(newChild,oldChild)

인자
newChild와 oldChild는 Node이다.
반환값
Node
예외처리
DOMException
설명
oldChild가 제거되고 newChild노드를 삽입한다.

3) removeChild(oldChild)

인자
oldChild는 Node이다.
반환값
Node
예외처리
DOMException
설명
oldChild가 제거된다.
만약 oldChild가 없으면 에러가 난다.

4) appendChild(newChild)

인자
newChild는 Node이다.
반환값
Node
예외처리
DOMException
설명
newChild를 맨마지막에 삽입한다.
만약 newChild가 트리 어딘가에 위치하여 있다면 먼저 그위치에서 제거된후 자식의 현재리스트에 덧붙여 진다.

<html>
<script language="javascript" for="window" event="onload">
var elem1 = xml.documentElement.childNodes.item(0);
var elem2 = xml.documentElement.childNodes.item(1);
confirm(xml.xml);
elem1.appendChild( elem2.childNodes.item(0) );
confirm(xml.xml);
</script>
<xml id = "xml">
<rootElement>
<elem1>
<childElement1/>
</elem1>
<elem2>
<childElement2/>
</elem2>
</rootElement>
</xml>
</html>

5) hasChildNode()

인자
none
반환값
boolean
예외처리
none
설명
자식노드가 있다면 true, 없으면 false값을 리턴한다.

6) cloneNode(deep)

인자
deep는 논리값이다.
반환값
Node
예외처리
none
설명
deep이 true이면 child를 가지고 복사한다.만약 deep이 거짓이면 노드가 복사되지만 자식들은 무시된다. true이면 자식노드를 모두 포함해서 복사된다.


//------------------------------------------------------------------------------






1. Document

(1) 부모노드

Document Node 노드의 부모노드는 Node이다. Document 노드는 그 밑에 있는 여러가지 노드를 다루는 도구를 포함하고 있다. 특히 Document노드가 나중에 트리에 삽입될 수 있는 노드를 생성하는데 이용된다. 또한 기본 검색처리방법도 포함되어 있고 rootElemet 노드와 DocumentType 노드같이 트리에 있는 중요한 노드에 대한 포인터도 가지고 있다.

(2) Document Propeties

1) documentElement

타 입
Element node
설 명
문서 내의 가장 높은 레벨의 Element를 나타낸다.


<HTML>

<BODY>

<script language=javascript for=window event="onload">
confirm(xml.documentElement.nodeName);
confirm(xml.documentElement.attributes.item(0).nodeName);
</script>
<xml id = "xml">
<엘레먼트이름 애트리뷰트이름 = "hello" />
</xml>
</BODY>
</HTML>


키워드 xml이 Document Node이고 xml.documentElement는 rootElement를 나타내는 Element 노드이다.
XML문서 전체를 나타내고 싶을때는 xml.xml을 이용한다.

2) docType

타 입
documentType Node
설 명
문서안의 DocumentType노드를 나타낸다. DTD내용의 일부를 포함하고 있다.

3) implementation

타 입
DOMimplementation Node
설 명
문서안의 DOMimplementation 노드를 나타낸다. 버전확인을 위한 매커니즘을 제공해 준다.



(2) Document Methods

1) createElement(tagName)

인자
tagName은 string이다.
반환값
Element
예외처리
none
설명
tagName에 맞추어진 nodeName 프로퍼티를 가진 Element 노드를 생성하고 리턴한다.

2) createDocumentFragment()

인자
none
반환값
DocumentFragment
예외처리
none
설명
새로운 DocumentFragment 노드를 생성한다.

3)createTextNode(data)

인자
data는 string 값이다.
반환값
Text Node
예외처리
none
설명
string data 를 포함하는 새로운 textNode를 생성한다.

4) createComment(data)

인자
data는 string 값이다.
반환값
Comment
예외처리
none
설명
string data 를 포함하는 새로운 Comment Node를 생성한다.

5) createCDATASection(data)

인자
data는 string 값이다.
반환값
CDATASection
예외처리
none
설명
string data 를 포함하는 새로운 CDATASection를 생성한다.

6) createProcessingInstruction(target,data)

인자
target과 data는 string 값이다.
반환값
ProcessingInstruction
예외처리
none
설명
새로운 ProcessingInstruction를 생성하고 반환한다. 주어진 파라미터 target과 data에 PI 프로퍼티인 target과 data를 설정한다.

7) createAttriute(name)

인자
name은 string이다.
반환값
Attriute
예외처리
none
설명
새로운 Attribute 노드를 생성하고 리턴한다. 그리고 name에 nodeName프로퍼티를 설정한다. nodeValue프로퍼티는 공백으로 남겨 놓는다.

8) createEntityReference(name)

인자
name은 string이다.
반환값
EntityReference
예외처리
none
설명
새로운 EntityReference 노드를 생성하고 리턴한다. 그리고 name에 nodeName프로퍼티를 설정한다.

9) getElementsByTagName(tagName)

인자
tagName은 string이다.
반환값
nodeList
예외처리
none
설명
파라미터 이름인 name에 부합되는 프로퍼티 tagName(또는 nodeName)을 가지는 Element 노드 리스트를 리턴한다. 이 메소드는 Document 노드에 속하는 모든 트리를 검색한다. 만약이 이름이 "*"와 같다면 모든 Element 노드가 리턴된다.


2. 트리관리의 예

(1) Node 생성

<html>
<script language="javascript" for="window" event="onload">
//새로운 element 노드를 생성한다.
var newNode = xml.createElement("element2");
//원하는 위치에 삽입한다.
xml.documentElement.insertBefore(newNode, null);
confirm(xml.xml);
</script>
<xml id = "xml">
<rootElement>
<element1/>
</rootElement>
</xml>
</html>

위의 예제는 새로운 엘리먼트를 어떻게 생성하고 트리에 그것을 어떻게 입력할 것인지를 보여 주고 았다. 위의 예제는 그냥 마지막에 삽입하기 위해 insertBefore(newNode, null)처럼 'null'을 지정해 주었다.

'xml.xml' 은 처음의 xml은 XML문서의 ID인 xml, 즉 문서 전체이고, 뒤의 xml은 마이크로소프트의 확장 프로퍼티인데 오직 MSXML에서만 사용되는 것이다.

(2) Node 삭제

<html>
<script language="javascript" for="window" event="onload">
//삭제할 노드를 찾는다.
var nodeToDelete = xml.documentElement.childNodes.item(1);
//노드를 삭제한다.
xml.documentElement.removeChild(nodeToDelete);
confirm(xml.xml);
</script>
<xml id = "xml">
<rootElement>
<element1/>
<element2/>
</rootElement>
</xml>
</html>

(3) Node의 이동

<html>
<script language="javascript" for="window" event="onload">
//이동을 할 노드를 찾는다.
var nodeToMove = xml.documentElement.childNodes.item(1);
//노드를 이동한다.
xml.documentElement.childNodes.item(0).appendChild(nodeToMove);
confirm(xml.xml);
</script>
<xml id = "xml">
<rootElement>
<element1/>
<element2/>
</rootElement>
</xml>
</html>


Node 클래스에 있는 appendChild(...)는 element2를 이동시키는데 사용되었다. remonveChild(..)와 InsertChild..(...) 를 함께 사용하면 같은 결과를 얻을 수 있을 것이다.

//------------------------------------------------------------------------------






1. Element

(1) 부모노드

Element Node 노드의 부모노드는 Node이다. 이 Element에만 존재하는 대부분의 메소드들은 애트리뷰트를 관리하는 메소드들이다.

(2) Element Propeties

1) tagName

타 입
string
설 명
Element의 태그이름을 나타낸다. Element에 대한 nodeName과 같다.

(2) Element Methods

1) getAttribute(name)

인자
name은 string 값이다.
반환값
string
예외처리
none
설명
name으로 명명된 애트리뷰트의 내용을 포함하는 문자열을 리턴한다.

2) setAttribute(name, value)

인자
name, value 는 string 값이다.
반환값
none
예외처리
none
설명
name으로 명명된 애트리뷰트가 존재하지 않는다면 name으로 명명된 문자열로 애트리뷰트를 만들고 그 값에 value를 준다. 만약 이미 존재하고 있다면 이전의 값을 새로운 값으로 대체된다.

3) removeAttribute(name)

인자
name은 string 값이다.
반환값
none
예외처리
none
설명
name으로 명명된 애트리뷰트를 삭제한다.

4) getAttributeNode(name)

인자
name은 string 값이다.
반환값
Attribute Node
예외처리
none
설명
name으로 명명된 애트리뷰트 노드를 리턴한다. 존재하지 않는다면 null을 리턴한다.
getAttribute(name) = getAttributeNode(name).nodeValue

5) removeAttributeNode(oldAttr)

인자
oldAttr은 Attribute Node이다.
반환값
none
예외처리
none
설명
oldAttr으로 명명된 애트리뷰트 노드를 제거하고 oldAttr를 리턴한다.

6) setAttributeNode(newAttr)

인자
newAttr은 Attribute Node이다.
반환값
none
예외처리
none
설명
newAttr는 Element Node의 Attribute 리스트에 추가된다. Attribute 노드는 Document 노드를 사용하여 생성할 수 있다. 또한 다른 Element에서 삭제되었던 Attribute가 이 메소드에 의해 사용될 수 있다.

<html>
<script language="javascript" for="window" event="onload">

var attrNode = xml.documentElement.getAttributeNode("myAttr");
xml.documentElement.removeAttributeNode(attrNode);
xml.documentElement.childNodes.item(0).setAttributeNode(attrNode);
confirm(xml.xml);
</script>
<xml id = "xml">
<rootElement myAttr="안녕하세요">
<myElem/>
</rootElement>
</xml>
</html>


7) getElementsByTagName(name)

인자
name은 string 값이다.
반환값
nodeList
예외처리
none
설명
파라미터 이름이 name에 부합되는 tagName을 가지는 Element Node의 리스트를 리턴한다. 이 메소드는 그것이 호출 받았던 element의 모든 하위 트리를 검색한다. 만약에 name이 "*"와 같다면 모든 엘리먼트 노드가 리턴된다. Document 노드 클래스의 메소드와 같은 일을 수행한다. 다만 Document 노드에서는 문서전체가 검색대상이고 Element에서는 지정된 Element의 하위트리만을 대상으로 한다.

8) normalize()

인자
none
반환값
none
예외처리
none
설명
인접한 Text노드를 한 노드로 합친다. 만약 프로그래머가 Text노드를 이동시킬때 서로 인접해 있기 때문에 쉽사리 이동이 가능한 형식으로 DOM문서를 만들었을때 부모노드에서 normalize()를 호출하면 인접한 두개의 Text Node가 합쳐지는 DOM문서를 만들 수 있다.

2. Element Node의 사용 예

(1) 자식노드 방문하기

childNode 콜렉션과 for loop를 이용하여 쉽게 작성이 가능하다. 좋은 반복구조 기능은 DOM 스펙에 첨가 되어 있다. 참조해 보기를 바란다. 여기서는 프로그램에서 메소드를 직접 호출하여 사용했다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=ks_c_5601-1987" http-equiv=Content-Type>
<META content="MSHTML 5.00.2014.210" name=GENERATOR></HEAD>
<BODY onload=start()>
<SCRIPT language=javascript>

//엘리먼트 노드타입을 나타내기위해 전역변수(상수) 사용
var ELEMENT_NODE = 1;

function start() {
//탬색해야하는 자식들의 개수를 구한다.
var length = xml.documentElement.childNodes.length;

//개수만큼 반복
  for (index = 0; index < length; index++) {
    var childNode = xml.documentElement.childNodes.item(index);
// 자식이 엘리먼트인지 확인하여 참이면 태그이름출력
    if(childNode.nodeType == ELEMENT_NODE) {
      confirm(childNode.nodeName);
    }
  }
}

</SCRIPT>
<xml id=xml>
  <rootElement>
    <element1/>
    <element2/>
    <element3/>
  </rootElement>
</xml>
</BODY></HTML>


(2) Element의 내용보여주기

자식노드가 text 또는 CDATASection 노드라면 그 내용을 보연준다. 일단 모든 자식 노드를 방문하면서 Text Node 인지 CDATASection Node인지를 검사하여 참이면 내용을 보여주면 된다.

<html>
<body onload="start()">
<script language="javascript">

//nodeType 상수정의
var TEXT_NODE =3;
var CDATASECTION_NODE = 4;

//rootElement를 지정해 준다.
function start() {
   displayContents(xml.documentElement);
}

//모든 노드를 방문하면서 Text와 CDATASection의 내용을 보여준다.
function displayContents(node) {
   var length = node.childNodes.length;
   var index;
   var outputBuffer = ""; //출력하기 위한 버퍼

   for (index = 0; index < length; index++) {
      var childNode = node.childNodes.item(index);
      if (childNode.nodeType == TEXT_NODE) {
         outputBuffer += childNode.nodeValue;
      }
      if (childNode.nodeType == CDATASECTION_NODE) {
         outputBuffer += childNode.nodeValue;
      }
   }
   confirm(outputBuffer);
}

</script>
</body>
<xml id = "xml">
<rootElement>
지금 텍스트를 시작합니다...

<![CDATA[<B>굵은 글자체로 쓰겠습니다.</B>]]>

이제 텍스트를 끝냅니다...
</rootElement>
</xml>
</html>


(3) 트리에 있는 모든 노드 방문하기

자료구조내의 트리의 운행방법중 하나인 "깊이 우선 검색법 : 형제노드를 방문하기전에 자식노드를 먼저 방문하는 방법"을 선택하여 모든 노드를 방문하고자 한다. 이때 사용하는 방법은 재귀호출을 이용한다. 여기서는 프로그래밍 구조를 살펴보기 위하여 노드를 엘리먼트만을 처리했다. 애트리뷰트가 있어 그것도 탐색하고 싶다면 애트리뷰트가 았는지 확인하고 있으면 애트리뷰트 탐색하는 부분을 추가하면 가능할 것이다.

<html>
<body onload="start()">
<script language="javascript">

var ELEMENT_NODE = 1;

//루트엘리먼트로 함수 시작
function start() {
   visit(xml.documentElement);
}

//노드방문함수
function visit(node) {
   //엘리먼트인지 확인-맞으면 엘리먼트 출력
   if(node.nodeType == ELEMENT_NODE) {
      confirm(node.nodeName);
      // 이때 str += nodeNmae 같이 태그이름을 문자열로 만들 수도 있다.
   }
   //자식 노드의 개수를 가져온다.
   var length = node.childNodes.length;
   // 자식 노드가 있다면 자식 노드의 개수만큼 노드를 탐색한다.
   if (length > 0) {
      var index;

      for (index =0; index < length; index++) {
         // 노드 방문함수를 이용하여 재귀호출하여 계속 진행된다.
         visit( node.childNodes.item(index));
      }
   }
}

</script>
</body>
<xml id = "xml">
   <rootElement>
      <element1>
         <childElement1/>
      </element1>
      <element2/>
      <element3>
         <childElement2/>
      </element3>
   </rootElement>
</xml>
</html>


(4) Attribute의 관리방법

<html>
<body onload="start()">
<script language="javascript">

function start() {
var rootElement = xml.documentElement;

rootElement.setAttribute('myAttr', '반갑습니다.');
alert(rootElement.getAttribute('myAttr'));
}

</script>
</body>
<xml id = "xml">
<rootElement/>
</xml>
</html>


//------------------------------------------------------------------------------






1. Attribute

(1) 부모노드

부모노드는 Node이다. Element, Entity, Notation 내의 애트리뷰트를 관리한다. 프로퍼티와 메소드가 많지는 않지만 몆가지라도 알아두면 쓰임새가 있다. Attribute노드는 실제로 Attr로 정의된다.

(2) Attribute Propeties


1) name

타 입
string
설 명
Attribute 노드의 이름을 나타낸다. Node로 부터 상속박은 nodeName과 같다.

2) specified

타 입
Element 논리값
설 명
Attribute 가 파서에 의해 로드되기전에 XML문서에 기입된다면 true로 설정된다.

3) value

타 입
string
설 명
Attribute 노드의 값을 나타낸다. Node로 부터 상속박은 nodeValue과 같다.

2. NodeList

(1) 부모노드

부모노드는 없다. DOM 트리를 검색하는데 있어서 결정적인 역할을 하는 요소이다.

(2) NodeList Propeties


1) length

타 입
unsigned long integer
설 명
NodeList안에 있는 자식의 개수를 리턴한다.

(2) NodeList Methods

1) item(index)

인자
index는 unsigned long integer 값이다.
반환값
node
예외처리
none
설명
NodeList가 관리하는 자식들중에 index값에 해당하는 노드을 리턴한다.
첫번째 자식 : index = 0
마지막 자식 : index = length -1
IE5.0 이상에서는 somenode.childNodes(index)를 사용할 수 있다.

2. NamedNodeMap

(1) 부모노드

부모노드는 없다. 애트리뷰트 콜렉션을 유지하기 위해 사용된다.

(2) NamedNodeMap Propeties


1) length

타 입
unsigned long integer
설 명
NamedNodeMap안에 있는 자식의 개수를 리턴한다.

(2) NamedNodeMap Methods

1) item(index)

인자
index는 unsigned long integer 값이다.
반환값
node
예외처리
none
설명
NamedNodeMap가 관리하는 자식들중에 index값에 해당하는 노드을 리턴한다.
첫번째 자식 : index = 0
마지막 자식 : index = length -1

2) getNmaedItem(name)

인자
name은 string 값이다.
반환값
node
예외처리
none
설명

name과 같은 nodeName 프로퍼티를 가지는 노드를 리턴한다 . 만약 없으면 null을 리턴한다.


3) setNmaedItem(node)

인자
node는 Node이다.
반환값
node
예외처리
DOMException
설명
node와 함께 지정된 노드를 트리에 더하고 node를 리턴한다. 만약 같은 이름의 node가 존재한다면 node로 치환되고 옛날 노드는 리턴된다.
다음 3가지중에 한가지라도 걸리면 예외상황이 발생한다.
1) node가 다른문서 안에서 생성된 경우
2) NamedNodeMap이 read-only인경우
3) node가 현재 다른 앨리먼트내에 있는 애트리뷰트인 경우
단, IE5.0이상에서는 Document에서 createAttribute로 생성한 노드를 예외상황없이 다른 Document 노드의 트리에 입력할 수 있다.

4) removeNmaedItem(name)

인자
name은 string 값이다.
반환값
node
예외처리
DOMException
설명

name과 같은 nodeName을 가지는 노드를 삭제하고 노드를 리턴한다 . 만약 처음부터 노드가 없으면 null을 리턴하고 지정된 노드가 없다면 예외상황이 발생한다.
단, IE5.0이상에서는 노드가 없더라도 예외상황이 발생되지 않는다.


3. CharacterData

(1) 부모노드

부모노드는 Node 이다. Text, CDATASection, Comment 노드에 의해 사용되어 진다. 때문에 string을 다루기 위한 프로퍼티와 메소드가 제공된다.

(2) CharacterData Propeties

1) length

타 입
integer
설 명
text string의 글자 수를 리턴한다.

2) data

타 입
string
설 명
CharaterData로부터 상속받은 노드에 저장된 text를 리턴한다.
nodeValue와 같은 값을 리턴한다.

(2) CharacterData Methods

1) substringData(offset,count)

인자
offset,count는 unsigned long integer 값이다.
반환값
string
예외처리
DOMEception
설명
offset에서 시작하는 문자열로부터 count만큼의 문자를 리턴한다.
offset,count가 정당하지 않다면 에러를 낸다.
offset은 양의 정수값을 가진다. 또한 전체길이(length)를 초과할 수 없다.
offset을 0으로 설정하는 것과 count를 length로 설정한다는 것은 string 전체를 리턴한다.

2) appendData(appendString)

인자
appendString은 string 값이다.
반환값
node
예외처리
DOMEception
설명

기존의 텍스트에 appendString을 덧붙인다.
노드가 read-only면 에러가 난다.


3) insertData(offset, newString)

인자
offset은 unsigned long integer, newString은 string이다.
반환값
node
예외처리
DOMException
설명
offset에 위치한 기존의 텍스트에 newString을 삽입한다.
offset이 정당하지 않거나 read-only면 에러가 발생한다.

4) deleteData(offset,count)

인자
offset,count는 unsigned long integer 값이다.
반환값
none
예외처리
DOMException
설명

기존의 텍스트에서 offset에서 시작하는 텍스트 스트링으로부터 count만큼 문자를 제거한다.
offset이 정당하지 않거나 read-only면 에러가 발생한다.


4) replaceData(offset, count, data)

인자
offset,count는 unsigned long integer, data는 string이다.
반환값
none
예외처리
DOMException
설명

기존의 텍스트에서 offset에서 시작하는 텍스트 스트링으로부터 count만큼 문자를 data로 치환한다.
offset이 정당하지 않거나 read-only면 에러가 발생한다.


4. Text

(1) 부모노드

부모노드는 characterData이다.

(2) Text Methods


1) splitText(offset)

인자
offset은 long integer 이다.
반환값
none
예외처리
none
설명

호출된 텍스트를 두개의 텍스트로 만든다. 첫번째는 offset의 위치를 포함 텍스트이고, 두번째 텍스트는 offset 이후의 모든 텍스트이다.


5. CDATASection

(1) 부모노드

부모노드는 Text 이다. Text 노드와 비슷하게 행동하지만 단하나의 차이는 CDATA 부분이 그안에 저장될 수 있다.

6. DocumentType

(1) 부모노드

부모노드는 Node이다. DTD를 나타내는데 사용한다. 다만 Entity와 Notation만 나타낸다. 모든 프로퍼티가 read-only 이다.

(2) DocumentType Propeties

1) name

타 입
string
설 명
DOCTYPE 바로 다음에 아노는 이름을 나타내며 바로 root element의 이름이다.

2) entities

타 입
namedNodeMap
설 명
이 문서에 대한 Entiy 콜렉션을 나타낸다.
각 Entity 노드는 DTD에 있는 엔티티선언을 모델화한 것이다.

3) notations

타 입
namedNodeMap
설 명
이 문서에 대한 Notation 콜렉션을 나타낸다.
각 Notation노드는 DTD에 있는 notation 선언을 모델화한 것이다.

7. Entity

(1) 부모노드

부모노드는 Node이다. DTD에 선언된 entity 를 모델화한 것이다. DOM 트리에서는 entity 노드가 DocumentType 노드 아래에서만 사용된다.

(2) Entity Propeties

1) systemId

타 입
string
설 명
엔티티와 관련된 시스템식별자를 나타낸다. 없다면 null이다.

2) publicId

타 입
string
설 명
엔티티와 관련된 공개된 식별자를 나타낸다. 없다면 null이다.

3) notationName

타 입
string
설 명
파서되지 않은 엔티티에 대한 notation 이름을 나타낸다. 파서된 엔티티뿐이라면 null을 나타낸다.

8. Notation

(1) 부모노드

부모노드는 Node이다. DTD에 선언된 notation을 모델화한 것이다. DOM 트리에서는Notation 노드가 DocumentType 노드 아래에서만 사용된다.

(2) Notation Propeties

1) systemId

타 입
string
설 명
Notation과 관련된 시스템식별자를 나타낸다. 없다면 null이다.

2) publicId

타 입
string
설 명
Notation과 관련된 공개된 식별자를 나타낸다. 없다면 null이다.

9. EntityReference

(1) 부모노드

부모노드는 Node 이다. EntityReference 노드는 대응하는 Entity 노드를 가리키는데 사용된다. 이 노드 타입은 그 자신의 프로퍼티와 메소드의 어떤것도 확장시키 않는다. 때문에 단지 Node안에 선언된 메소드와 프로퍼티만 EntityReference와 함께 사용할 수 있다. EntityReference 아래에 있는 노드는 read-only 이다. EntityReference 노드는 하위트리 전체를 포함해서 다수의 노드를 포함하는데 사용되어질 수 있다.

10. ProcessingInstruction

(1) 부모노드

부모노드는 Node이다. ProcessingInstruction 노드는 XML문서내의 processingInstruction을 나타내는데 사용된다.

(2) ProcessingInstruction Propeties

1) target

타 입
string
설 명
<?target text?>의 형식으로 존재하는 PI의 표적을 나타낸다.

2) data

타 입
string
설 명
<?target text?>의 형식으로 존재하는 PI의 텍스트를 나타낸다.

11. Comment

(1) 부모노드

부모노드는 CharacterData 이다. Comment 노드는 XML문서안의 <!-- text -->와 같은 주석을 나타내는데 사용된다. 이 노드는 Text와 비슷하게 동작한다. 왜냐하면 주석내 텍스트을 사용할 수 있기 때문이다.

12. DocumentFragment

(1) 부모노드

부모노드는 Node 이다.

DocumentFragment 노드는 어떠한 XML문서를 나타내지 않는다. 대신에 노드를 이동시칼때 위치소유자(place holder)로서 사용된다. DocumentFragment 노드를 어떤 노드(Document나 Element)의 자식 리스트에 입력할때 오직 DocumentFragment의 자식들과 DocumentFragment 그 자신만이 입력된다. DocumentFragment는 트리안에 존재하는 Element를 합치는데 유용하게 사용된다. 일단 DocumentFragment에서 Element 콜렉션을 생성하면 자식들은 하위트리로 이동된다.

간단한 예를 한번 보도록 하자.

<html>
<body onload="start()">
<script language="javascript">
function start() {
// DocumentFragment 노드를 생성한다.
  var myDocFrag = xml.createDocumentFragment();

// 두개의 Element 노드를 생성한다.
  var element1 = xml.createElement("element1");
  var element2 = xml.createElement("element2");

// 생성된 두개의 Element 노드를 DocumentFragment 노드에 자식으로 삽입한다.
  myDocFrag.insertBefore(element1, null);
  myDocFrag.insertBefore(element2, null);

//실제 xml의 root엘리먼트에 DocumentFragment에서 생성된 트리를 삽입한다.
  xml.documentElement.insertBefore(myDocFrag, null);

  confirm(xml.xml);
}

</script>
</body>
<xml id = "xml">
  <rootElement/>
</xml>
</html>


기본 로직은 대충 이해될 것이다. 다만 유의해서 봐야 할 것은 결과를 살펴볼 때 DocumentFragment를 사용했다는 어떠한 흔적도 증거도 남아있지 않다는 것이다. 즉 서로 다른곳에 위치한 필요한 트리를 DocumentFragment의 하위트리에 모아 놓고 한꺼번에 삽입시킬 수 있다는 것이다.

13. DOMImplemetation

(1) 부모노드

부모노드는 없다. DOMImplemetation 클래스는 DOM의 어느 특정 인스턴스와는 독립적으로 세세한 구현을 하기 위해 사용된다.

(2) DOMImplemetation Methods

1) hasFeature(feature, version)

이 메소드는 마크업언어와 버전을 받아서 참 또는 거짓을 리턴한다. 특정 버전은 특정한 마크업언어에 의존하는 것이 있다. 때문에 버전을 확인하는 것이 중요할 때가 있을 것이다. 그때 사용하면 된다.

14. DOMString

(1) 부모노드

부모노드는 없다. DOMString의 단 하나의 요구조건은 UTF-16 인코딩을 사용한다는 것이다. 실제 많이 사용되지 않는다. 왜냐하면 애플리케이션의 string을 그대로 많이 사용하기 때문이다.

15. DOMException

(1) 부모노드

부모노드는 없다. 언어 의존적인 존재이기 때문에 Java나 .NET에서나 가능할 것이다.

//------------------------------------------------------------------------------






DOM (계속)

원하는 노드 찾아가기

  • Node 객체의 운행(Traversal) 관련 속성
    • 관련속성
    • hasChildNodes() 메소드
  • NodeList 객체 
    • 노드들의 리스트, 예: childNodes 객체
    • length 속성, item(번호) 메소드
      xdoc.load("ex08.xml");
     var xroot = xdoc.documentElement;
     if (xroot.hasChildNodes) {
         alert(xroot.childNodes.length);
         var curr = xroot.firstChild;  alert(
    curr.ownerDocument.nodeName + curr.xml);
         alert(curr.nodeName + curr.nodeTypeString + curr.nodeValue + curr.attributes.length);
     }
     else alert('No Child');  
      xdoc.load("ex08.xml");
     var xroot = xdoc.documentElement;
     var curr = xroot.firstChild.nextSibling;    alert(curr.xml);
     curr = curr.childNodes.item(2);    alert(curr.xml);
     curr = cur.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);
     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);

      xdoc.load("ex08.xml");
     var xroot = xdoc.documentElement;
     var node1 = xroot.selectSingleNode('//book[@InStock=0]');
     alert(node1.xml+'\n=> 재고가 없습니다.');
     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);

실습예제 : 도서 검색 (교재 s20-05.htm 응용)

    XML 파일 경로 입력 또는 '찾아보기'로 선택

    'LOAD'로 파일을 메모리에 로드 :
      또는
    기본 예제 파일 (서점 도서 목록) 이용하기 :

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

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

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

    1) ... :<INPUT type="text" name="cond0" size="25">&nbsp;
    <INPUT type=button value="검색" onclick="
            var resHTML='';
            var nlist = xmldoc.getElementsByTagName(cond0.value);
                   
            for (var i=0; i&lt;nlist.length; i++) resHTML += nlist(i).xml + '\n\n';
            if (resHTML)                    
                  resDiv.innerText = resHTML;
            else
                  resDiv.innerHTML = '<H3>No match found by this search</H3>';  
           ">

    2) ... : <INPUT  type="text" name=cond1 size="25">&nbsp;
    <INPUT type=button value="검색" onclick="
            var resHTML='';
            var xroot = xmldoc.documentElement;
            var nlist = xroot.selectNodes('//*[text()=' + cond1.value + ']');
            var alist = xroot.selectNodes('//@*[text()=' + cond1.value + ']');
                   
            for (var i=0; i&lt;nlist.length; i++)  resHTML += nlist(i).xml + '\n\n';
            for (var i=0; i&lt;alist.length; i++)  resHTML += alist(i).xml + '\n\n';
            if (resHTML)                    
                   resDiv.innerText = resHTML;
            else
                   resDiv.innerHTML = '<H3>No match found by this search</H3>' ;
            ">

    3) ... : <INPUT  type="text" name=con21 size="12">&nbsp; <select name="comp"><option value="=">=...</select><INPUT  type="text" name=con22 size="12">
    <INPUT type=button value="검색" onclick="
            var resHTML='';
            var xroot = xmldoc.documentElement;
            var nlist = xroot.selectNodes('//'+con21.value+'[text()'+comp.value+con22.value+']');
                   
            for (var i=0; i&lt;nlist.length; i++)  resHTML += nlist(i).xml + '\n\n';
            if (resHTML)                    
                   resDiv.innerText = resHTML;
            else
                   resDiv.innerHTML = '<H3>No match found by this search</H3>';
            ">

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

  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("노드추가");
     pi = xdoc.create
    ProcessingInstruction("xml-stylesheet",  "type='text/xsl' href='ex8.xsl'");  
     cd = xdoc.createCDATASection("<1>");  alert(cd.xml);
     alert(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);
         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>
     

//------------------------------------------------------------------------------