본문 바로가기

Robotics/Software Tech.

XML 파서의 종류, DOM과 SAX


DOM 과 SAX?
파서에는 2가지 종류가 있다.
현재 W3C에서는 DOM(Document Object Model)이란 스펙을 제안(Recommendation) 한 상태로 파서가 트리 기반으로 작동할 때 제공 돼야 할 트리으 인터페이스를 규정하고있고, W3C의 표준은 아니나 이벤트 기반의 파서와 작업할 수 있는 업계 표준으로 SAX(Simple API for XML) 라는 표준이 제안 된 상태다.

 

1) DOM
2) SAX
네임 스페이스(Namespace)의 지원 여부도 파서를 선택하는데 좋은 기준이 될 수 있다. XML 네임스페이스의 존재는 XML로 규정된 문서를 통합할 수 있는 기본 메커니즘을 제공 한다는데 의의가 있다. 네임 스페이스는 애플리케이션에서 처리할 수도 있지만 원칙적으로는 파서의 몫이다. 향후 XML 문서는 수많은 도메인에 의해 규정된 XML 애플리케이션을 포함하게 될 것이기 때문에 XML 애플리케이션에서  네임스페이스 처리는 매우 중요한 위치를 차지하게 될 것이다.
트리기반 API,DOM

DOM은 XML 문서를 DOM 트리라는 개념으로 접근할 수 있게 해준다. DOM은 인터페이스와 인터페이스의 계층구조를 기술한 것일 뿐이지 어떻게 만들라는 구현 방법을 규정한 것은 아니다.따라서 DOM을 지원하는 파서는 실제로 트리로 구현하든, 또 다른 구조를 사용하든지 간에 DOM의 인터페이스를 지원 하기만 하면 되는 것이다.

노드: DOM의 핵심 인터페이스

노드(Node)는 DOM 트리의 노드를 추상화한 인터페이스로 XML 문서의 문법적 요소를 노드로 다룰 수 있게 해준다. 노드에서 상속받아 실제 DOM 트리를 구성하는 노는 <표 2>와 같다. 각각의 노드 인터페이스에 그려있는 그림은 DOM 트리의 이해를 돕기위해  노드 간의 계층 구조를 시각적으로 보여주기 위한 심볼들이고 밑줄로 처리된 부분은 XML 문서상의 일치하는 문법 요소를 나타낸다.

<표2> DOM 트리의 노드

노드 내용 노드 내용

Document

DOM 트리의 최상위(root) 노드로 대상 XML문서 ProcessingInstruction

<?pi I am Instruction ?>

DocumentFragment

정확한 구조의 XML 문서일부 Comment

주석
<!- 난 주석-->
DocumentType

DTD Text

텍스트
<!DOCTYPE root
[
<!--선언리스트-->
]
>
<root>
난 텍스트!
</root>
EntityReference

엔티티 참조 CDATASection

CdataSection
$Entity; <root>
<![CDATA[난 cdata section[[>
</root>
Element

태그 Entity

일반 엔티티 선언부를 파싱한 결과
<root>
난 엘리먼트
</root>
Attr

태그의 속성값 Notation

Notation 선언부
<root tel='011 00'>
</root>
^ Top
DOM 트리 노드 인터페이스의 계층 구조

각각의 노드는 계층 구조를 가지고 있는데 자식 노드로 가질수 있는 노드가 모두 같은 것은 아니다. 노드간의 계층 구조는 XML 스펙에 정의 되어 있으며, 간단히 정리하면 <표 3>과 같다.각각의 그림에서 일반선은 자식 노드로서의 관계이고 화살표는 속성값으로의 관계를 말한다.

<표 3> DOM 트리 노드 인터페이스의 계층구조

노드 계층구조 설명
Document Document가 자식노드로 가질수 있는 태그는 문서의 최상의 태그를 말하며, XML 문서라면 반드시 하나가 존재해야 한다.
DocumentFragment DocumentFragment는 DOM 트리의 실제 노드가 될 수는 없고 임시로 만들었다가 DOM 트리에 자식 노드로 붙게 되면 바로 다음 레벨의 노드들의 순차적으로 붙게된다.
DocuentType DocumentType은 DOM 트리의 구성 노드가 아니라 Document의 속성값이다. 또한 자식 노드를 갖지 않으며 Entity와 Notation을 속성값으로 가지고 있다.
EntityReference Entity 참조
Element Element는 Attr을 속성값으로 갖는다.
Attr Attr은 태그의 속성값을 나타내는 것으로 Element의 속성값으로 실제 DOM 트리를 구성하지 않는다.
Entity Entity는 DocumentType의 속성값으로 DOM 트리 구성에는 빠지지만 EntityReference에 의해 DOM트리에 삽입한다.
ProcessionInstruction,
Comment, Text,
CDATASection,
Notation
자식 노드를 갖지 않는 노드들이며 Notation은 DocumentType의 속성값으로 DOM 트리에서 직접 참여하지 않는다.

 

^ Top
DOM 트리노드의 생성 및 관리

노드관리

DOM 트리의 노드를 관리하고 모든 노드의 기본 속성을 제공하는 인터페이스는 Node 인터페이스 이다. <리스트 1>은 IDL로 기술된 Node 인터페이스를 정리한 것으로 모든 DOM 트리 노드는 이 Node 인터페이스에서 상속을 받는다. 일단 Node 인터페이스에서 주목할 것은 nodeName, nodeValue, attributes로 실제 각각의 DOM 트리노드에서 어떤 값을 갖는가를 알아야 한다. attributes의 값은 Element 노드인 경우에만 유효한다는 점에 주목하자.(<표 4>)

NodeList와 NamedNodeMap 인터페이스는 배열처럼 인덱스로 달려있는 노드를 다룬다는 점에서는 같으나 NodeList는 순서가 있고 NamedNodeMap은 순서가 없다는 차이가 있다. 또한 NamedNodeMap은 이름으로 노드를 직접 다루게 해준다. 그래서 자식 노드를 나타내는 chideNodes는 XML문서에서 순서가 매우 중요하기 때문에 NodeList타입이고, 태그의 속성값을 나타내는 attributes는 순서에 상관없기 때문에 NamedNodeMap 타입으로 선언되었다.그 밖에 노드를 복제하는 cloneNode함수는 deep가 true면 자식 노드 전체를 포함해서 복제하고 반대면 자신만 복제한다.

<표 4> Node 인터페이스와 각각의 노드와의 관계

Node NodeName NodeValue Attributes
Element 태그이름 null 태그에 정의된 리스트
Attr 속성이름 속성값 null
Text #text 노드의 내용 null
CDATASection #cdata-section 노드의 내용 null
EntityReference 참조된 엔티티의 이름 null null
Entity 선언된 엔티티의 이름 null null
ProcessingInstruction PI 이름 PI 이름을 제외한 전체 내용 null
Comment #comment 주석내용 null
Document #document null null
DocumentType DTD 이름 null null
DocumentFragment #document-fragment null null
Notation Notation 선언이름 null null

노드 생성

파싱을 하면 DOM 트리가 구축되지만 필요에 따라 DOM 트리에 새로운 노드를 추가하고 싶거나 처음부터 새로 DOM 트리를 구축하고 싶은 경우는 필요한 노드를 생성할 필요가 있다. 이런 노드 생성을 지원하는 함수들은 DOM 트리의 최상위 노드인 Document에서 제공된다.Entity와 Notation 그리고 DocumentType 노드를 제외한 모든 생성 함수를 제공한다. 즉 DTD에 관련된 노드는 생성할 수 없는데 현재의 DOM 스펙에서는 DTD에 관련된 모델링이 고려되어 있지 않기 때문이기도 하고 현실적으로 DTD의 내용을 바꾸었을 때 트리에 어떤 형태로든지 영향을 줄 수 밖에는 없다는 문제가 있기 때문이다.

^ top
이벤트 기반 API. SAX
이벤트 기반의 인터페이스란 무엇인가?

XML(또는 SGML) API에는 두 가지 주요한 형식이 있다. 하나는 DOM과 같은 트리기반이고 다른 하나는 SAX와 같은 이벤트 기반의 API이다. 트리 기반의 API는 XML 문서를 파싱해 내부 트리 구조를 만들며, 애플리케이션은 그 트리를 탐색, 조작하는 식으로 작업을 수행한다. 반면 이벤트 기반의 API는 파싱 이벤트를 애플리케이션의 콜백(CallBack)을 통해 직접적으로 알릴 뿐, 내부 트리는 만들지 않는다.

그런데 DOM이 있는데도 불구하고 다른 방식의 인터페이스가 필요했던 이유는 트리기반의 API 애플리케이션은 전반적인  영역에서 유용하긴 하지만 굳이 트리가 필요 없는 경우도 있다. 문서가 매우 큰 경우, 불필요한 트리를 구축한 다는 것은 상당한 리소스 낭비일 수 있다. 게다가 어떤 애플리케이션은 DOM이 구축하는 트리와는 전혀 다른 고유의 트리나 테이블을 구축 할 필요가 있을 수 있다. 이 경우 DOM이 생성하는 트리는 전혀 쓸모가 없는 것이다.
   즉 트리 기반보다는 이벤트 기반의 API가 더 간단하고 저수준을 XML 문서에 접근할 수 있다는 얘기다. 또한 시스템 메모리보다 훨씬 큰 문서를 파싱하는 것이 가능하고 콜백 핸들러를 사용해 고유한 데이터 구조를  생성해 낼 수 있다.

<?xml = version='1.0'>
<doc>
<para> Hello World! </para>
</doc>
위와 같은 문서의 구조를 이벤트 기반의 인터페이스는 선형적으로 분석해 다음과 같이 결과를 내려고 한다.
start document
Start element : doc
Start element : para
Characters : Hello, world!
End element : para
End element : doc
End document 

[출처] DOM 과 SAX?|작성자 도신