반응형

문서객체모델(Document Object Model, DOM)은 HTML과 XML 문서에 대한 프로그래밍 인터페이스
문서에 대한 구조적 정보를 제공하고 문서 구조나 외양 및 내용을 프로그램에서 접근할수 있는 방법 제공

DOM 노드의 유형
1. Node.ELEMENT_NODE는 엘리먼트 노드 유형에 대한 상수
2. Node.ATTRIBUTE_NODE는 애트리뷰트 노드 유형에 대한 상수
3. Node.TEXT_NODE는 텍스트 노드 유형에 대한 상수
4. Node.DOCUMENT_NODE는 문서 노드 유형에 대한 상수

다른 노드 유형들도 많이 있지만 주로 이 네가지 유형을 다루기 때문에 예시 하지 않는다.

nodeType 속성
DOM 노드 유형에 대해 상수로 정의 되어 있으므로 모든 노드에서 사용할수 있는 nodeType 속성을
사용하여 위 상수와 비교 함으로서 노드 타입을 알수 있다.


Internet Explorer는 자바스크립트에서 Node 상수를 사용할때 에러를 보고 한다.
Internet Explorer 7.0부터 이러한 문제를 정정했다 하지만 보편적으로 사용하는 6.0에서는 정상작동 하지 않는다.
따라서 Node 사용을 피해야 할것이다. 그냥 이런 것이 있다고만 알아 두도록 하자.

DOM, XML
반응형
출처: http://kr.blog.yahoo.com/kwon37xi/folder/3381246.html

  • DOM은 XML을 생성하고 변경할 수 있다.

XML DOM 트리의 생성과 변경

  • 새로운 XML을 생성하기 위해서는 org.w3c.dom.DOMImplementation을 구현한 클래스를 사용해야한다.
  • Xerces의 DOMImplementation구현 : org.apache.xerces.dom.DOMImplementationImpl
  • 생성 예

    DOMImplementation domImpl = new DOMImplementationImpl();
    Document doc = domImpl.createDocument(null, "rootElement", null);
    
  • Document 객체 생성시 파서의 Document 구현 클래스를 사용하면 DocType 이 생성되지 않는다. DOMImplementation 을 사용해서 새로운 XML DOM 트리를 생성해야 한다.
  • DOMImplementation.createDocument(1,2,3);
    • 첫번째 인자 : 문서의 루트 요소를 위한 네임스페이스
    • 두번째 인자 : 루토 요소
    • 세번째 인자 : DocType 클래스의 인스턴스.
  • DocType이 필요할 경우 DOMImplementation.createDocType() 사용.
  • 변경 예

    Element root = doc.getDocumentEelment();
    root.setAttribute("id", id); // id 속성의 추가
    
    Element nameElement = doc.createElement("name");
    Text nameText = doc.createTextNode("내용");
    nameElement.appendChild(nameText); //name 요소에 텍스트 값 추가
    root.appendChild(nameElement); // rootElement 요소에 name 요소 추가
    
  • 모든 노드의 생성은 Document 객체의 create* 메소드를 통해서 이뤄진다.
  • "appendChild()"는 자식 노드를 추가한다.

네임스페이스

  • DOM Level 2는 네임스페이스를 지원한다.
  • 네임스페이스를 위해 Node 인터페이스는 "getPrefix()"와 "getNamespaceURI()" 메소드를 제공한다.
  • Document.createElementNS() 네임스페이스를 지원하는 요소 추가.
  • 네임스페이스를 인식하는 각 메소드의 첫번째 인자는 "네임스페이스 URI"이고, 두번째 인자는 요소와 속성등의 QName이다. QName은 "ora:copyright" 와 같은 형태를 띈다.
  • "ora:copyright" 요소에서 getPrefix() : "ora" 리턴
  • 네임스페이스에 속하지 않는 요소에서 getPrefix() : null 리턴
  • 네임스페이스를 지정했을 때는 루트 요소에 xmlns 속성을 지정해야 한다.

DOM Level 2 - 순회(Traverse)

  • DOM 트리를 순회하는 기능을 제공한다.
  • "org.w3c.dom.traversal.DocumentTraversal" 인터페이스를 이용한다.
  • 일반적인 파서의 Document 구현 클래스는 DocumentTraversal 도 함께 구현한다.
  • NodeIterator

    NodeList descriptionElements =
    	root.getElementsByTagNameNS(docNS, "description");
    Element description = (Element)descriptionElements.item(0);
    
    // NodeIterator를 구한다.
    NodeIterator i = ((DocumentTraversal)doc)
    	.createNodeIterator(description, NodeFilter.SHOW_ALL,
    	new FormattingNodeFilter(), true);
    
    Node n;
    
    while ((n = i.nextNode()) != null) {
    	System.out.println("Search phrase found: '" + n.getNod eVal  ue() + "'");
    }
    
  • createNodeIterator(1, 2, 3, 4)
    • 첫번째 인자 : 순회할 노드 요소
    • 두번째 인자 : 상수 필터
      1. NodeFilter.SHOW_ALL : 모든 노드를 포함하여 순회
      2. NodeFilter.SHOW_ELEMENT : 요소만 순회
      3. NodeFilter.SHOW_TEXT : 텍스트 노드만 순회
    • 세번째 인자 : NodeFilter 구현 객체
    • 네번째 인자 : 엔티티 참조의 실제값을 분석할 것인가?
    • 두번째와 세번째 인자가 함께 나올 경우 두번째 인자 필터를 우선적용하고 그 결과를 다시 세번째 인자로 필터링한다.
  • NodeFilter
    • public short acceptNode(Node n); 을 이용해서 순회할 노드인지 여부를 결정한다.
      • 리턴값 NodeFilter.FILTER_SKIP : 필터로 들어온 노드는 건너 뛰고 그 자식노드를 계속 탐색
      • 리턴값 NodeFilter.FILTER_REJECT : 필터로 들어온 노드와 그 자식 모두 건너 뜀
      • 리턴값 NodeFilter.FILTER_ACCEPT : 필터로 들어온 노드 사용
    • 노드 필터 예

      class FormattingNodeFilter implements NodeFilter {
      	public short acceptNode(Node n) {
      		if (n.getNodeType() == Node.TEXT_NODE) {
      			Node parent = n.getParentNode();
      
      			if ((parent.getNodeName().equalsIgnoreCase("b")) ||
      				(parent.getNodeName().equalsIgnoreCase("i"))) {
      				return FILTER_ACCEPT;
      			}
      		}
      
      		return FILTER_SKIP;
      	}
      }
      
  • TreeWalker
    트리 뷰를 얻는다. 필터를 이용해 특정한 요소 등만 가진 트리를 생성해낸다.

범위(Range)

알 수 없는 DOM 구조에 새로운 컨텐트를 추가하거나 또는 컨텐트를 삭제, 복사, 추출해야 할 경우에 범위 모듈을 사용한다.

Wrong document Exception

잘못된 문서 예외(Wrong document Exception)은 서로 다른 문서의 노드들을 함께 사용하려 할 때 발생한다.

다른 문서의 노드를 현재 문서에 append하려면 importNode를 사용한다.
Element otherDocElement = otherDoc.getDocumentElement();
Element thisDocElement = thisDoc.getDocumentElement();

// 대상 문서에 노드 임포트
Element readyToUseElement =
    (Element)thisDoc.importNode(otherDocElement);

// 아무문제없이 노드 추가
thisDocElement.appendChild(readyToUseElement);



DOM, XML
반응형
출처: http://kr.blog.yahoo.com/kwon37xi/folder/3381246.html
DOM(Document Object Model)은 모든 프로그래밍 언어와 개발 도구에서 사용하는 문서의 컨텐트 모델을 표현하기 위해 설계되었다. 각 언어별로 바인딩이 존재한다.
이 점은 장점이 될 수도 있지만, JAVA 고유의 편리한 기능을 사용할 수 없어, 단점으로 작용하기도 한다. JAVA 고유의 기능을 사용한 JDOM이 DOM보다 훨씬 편리하다.
  • DOM은 모든 면에서 트리 모델이다.
  • DOM은 XML문서 전체를 메모리에 저장하여 표현한다.
  • 각 트리는 org.w3c.dom.Node 인턴페이스를 기반으로 한다. 요소, 속성, 텍스트, PI, 주석 등 모든 것이 Node로 표현된다.
  • 요소의 텍스트도 하나의 트리로 간주된다. 그러므로 Element 노드의 텍스트를 구할 때 "getText()"와 같은 방식으로 구할 수 없고, 요소의 Text 자식 노드들을 구한뒤, 거기서 값을 가져와야한다.

SAX의 장/단점

  • SAX는 순차적이라 XML문서의 요소를 무작위로 접근할 수 없다.
  • 형제 요소를 처리하기 어렵다.
  • 메모리를 훨씬 적게 사용한다.

XML 파싱 : Xerces 기준

  • DOM에서는 문서를 완전히 분석하여 트리 구조가 생성되어야 XML 문서의 데이터를 사용할 수 있다.
  • DOM에서 문서를 분석한 결과는 org.dom.w3c.dom.Document 객체로 표현된다.
  • 다음과 같이 XML 문서를 파싱한다.

    import org.apache.xerces.parsers.DOMParser; // 파서 import
    import org.w3c.dom.*; // DOM 인터페에스 import
    ...
    
    DOMParser parser = new DOMParser();
    
    // Document 객체인 DOM 트리 구성
    parser.parse("document.xml");
    Document doc = parser.getDocument(); // DOM Document 객체 얻기
    

  • import org.apache.xerces.parsers.DOMParser
    • void parse(org.xml.sax.InputSource inputSource)
    • void parse(java.lang.String systemId)

Node

  • DOM의 장점중의 하나는 XML을 표현하는(Document 객체를 포함한) 모든 DOM 객체가 DOM의 Node인터페이스를 상속한다는 점이다.
  • Node.getNodeType() : 현재 노드의 타입(요소, 속성, PI 등등..)을 가리킨다.
  • Document.getDocumentElement() : 최상위 요소(Root Element) 노드
  • Node.getNodeName() : 노드의 이름. Text 노드(요소의 값)의 경우 이 노드 이름은 의미가 없다.
  • Node.getNodeValue() : 노드의 값. Element 노드의 경우 이 값은 의미가 없으며 자식 노드를 구해 그 중 Text노드의 값을 가져와야만 한다.
  • Node.getChildNodes() : NodeList 인스턴스 반환. 자식 노드 목록.
  • NamedNodeMap Node.getAttributes() : Element 노드의 경우에만 유효. 속성 목록을 반환한다.
  • NodeList.item(int) : 자식 Node들을 순서대로 반환받는다.

DOCTYPE, PI 등의 처리

최상위 엘리먼트보다 상위에 오는 DOCTYPE과 PI(처리 지시어; Processing Instruction)등을 처리하려면 Document 노드 단에서 자식 노드들을 얻어야만 한다.

NodeList 사용시 주의점!

이것은 Java와 XML 책에는 없는 내용이다. 내 경험상의 주의점이다.

다음과 같은 XML이 있을 때
<root>
  <child1>hello</child1>
  <child2>hi~</chil2>
</root>
위 XML을 파싱하여 "root" 엘리먼트 Node 객체에서 getChildNodes()를 했을 경우에 주의할 점이 있다.
이 상황에서 "child1" 노드 객체를 가져올 때
DOMParser parser = new DOMParser();

parser.parse("test.xml");

Document doc = parser.getDocument();

Element root = doc.getDocumentElement();

NodeList children = root.getChildNodes(); // root 의 자식 노드 얻기 -- !! 요주의 부분!!

Node child1Node = children.item(0); // child1 요소 얻기 

Node textNode = child1Node.getChildNodes().item(0); // child1의 텍스트 얻기

System.out.println("child1 : " + textNode.getNodeValue());
위와 같이 하면 제대로 값을 가져올 수 있을까?

답은 "가져올 수도 있고 못 가져올 수도 있으나, 십중팔구는 NullPointerException이 발생한다는 것이다."
NullPointerException이 발생한다면 그것은 textNode가 null이기 때문이다.
위와 같이 NodeList.item(int) 메소드를 사용할 경우에 root 요소와 child1 요소 사이의 공백이 Text 노드로서 읽힐 수도 있다. 이 경우 NodeList.item(0)가 리턴하는 노드는 child1 요소가 아니라 root요소의 Text 노드가 되는 것이다.
만약 root 요소와 child1요소 사이에 아무런 공백도 없거나 DTD 등으로 공백을 무시하도록 했다면 안 그럴 수도 있다.

그러므로 child1 요소를 명백하게 가져오려고 할 경우에는 root.getChildNodes()를 사용해서는 안된다. root 노드를 Element 객체로 캐스팅하고 Element.getElementsByTagName(String)으로 명백하게 가져와야 한다.
Element root = doc.getDocumentElement();

// 이 부분이 바뀌었다!!
NodeList children = root.getElementsByTagName("child1"); // root 의 자식 노드 얻기

Node child1Node = children.item(0); // child1 요소 얻기

Node textNode = child1Node.getChildNodes().item(0); // child1의 텍스트 얻기

System.out.println("child1 : " + textNode.getNodeValue());

위와 같이 하면 children 객체에는 요소 이름이 "child1"인 요소만 남게 된다.

반응형

본 문서는 http://cafe.naver.com/specialj.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=1336 을 참조 

DOM 문서 객체 모델 [-, document object model]
본문
브라우저를 통한 확장성 생성 언어(XML) 문서의 상호 연동을 위한 객체 기반의 문서 모델. 플랫폼과 언어 면에서 중립적인 인터페이스로서 프로그램과 스크립트에 의한 문서의 내용˙구조˙종류의 동적인 접근과 변경이 가능하며, 스크립트나 프로그램 언어에 웹 페이지를 연결해 준다. 웹 페이지를 조작˙생성하기 위해 사용되는 속성, 방법 및 이벤트가 객체를 구성하는데, 이러한 객체들은 대부분의 웹 브라우저에서 스크립트 언어를 통해 접근할 수 있다.

 

 

 

JDOM [Java Document Object Model]
본문
자바에 최적화확장성 생성 언어(XML) 데이터 가공을 위해 만든 개방 소스 라이브러리. 자바 기반의 개발 도구로, 좀 더 직관적인 방법으로 XML을 조작할 수 있는 개방 소스 응용 프로그램 인터페이스(API)이며, SAX(Simple API for XML)와 문서 객체 모델(DOM)과도 상호 연동되고, SAX와 DOM의 장점만을 골라 만든 클래스인터페이스를 제공한다. JDOM은 W3C DOM과 유사하지만 DOM을 기반으로 설계되거나 DOM을 모델로 하지 않은 대안적인 문서 객체 모델로, 차이점은 DOM은 언어 중립적으로 설계되었고, 초기에 HTML 페이지의 자바 스크립트 가공에 주로 이용되었던 반면, JDOM은 자바 전용으로 설계되어 메소드 오버로딩(method overloading), 컬렉션(collection), 리플렉션(reflection), 친숙한 프로그램밍 환경 등 자바의 기본 기능들을 활용한다는 데 있다.

 

SAX

[simple API for XML, simple application program interface for Extensible Markup Language]

본문
확장성 생성 언어(XML)로 된 웹 파일을 해석할 수 있게 해 주는 응용 프로그램 인터페이스(API). XML을 해석하기 위해 문서 객체 모델(DOM) 대신 사용할 수 있는 대안으로 DOM보다 간단하고 대량의 파일용으로 적절하나 데이터 내용 운용면에서는 능력이 떨어진다. 또한 이벤트형 인터페이스이벤트를 제어하고 상황을 처리하여 XML 파서(parser)와 함께 사용된다.

 

JAX [Java API for XML]
본문
확장성 생성 언어(XML) 데이터 처리를 위한 자바 응용 프로그램 인터페이스. XML 파서(paser)를 얻기 위한 표준 인터페이스 JAXP(Java API for XML Procession), 메세징 프로토콜의 기초를 제공하는 JAXM(Java API for XML Messaging), 단순 객체 접근 프로토콜(SOAP) 스팩(제품 명세)에 따른 메시지를 만들고 소비하도록 하는 SAAJ(SOAP with Attachments API for Java), XML을 기반으로 한 자바 원격 프로시져 호출 응용 프로그램 인터페이스(API)인 JAX/RPC(Java API for XML-based RPC), XML 레지스터가 저장한 퍼블리싱된 웹 서비스 정보를 액세스하는 방법을 제공하는 JAXR(Java API for XML Registries)로 구성된다.

 

자바 XML팩 [Java XML Pack]
본문
선 마이크로시스템스사가 2001년 12월에 발표한 자바 언어(환경)를 확장성 생성 언어(XML)나 웹 서비스에 대응시키는 응용 프로그램 인터페이스(API)를 정리한 패키지. 자바 개발자에게 프로그램의 XML 대응이나 웹 서비스의 구축에 필요한 기술 제공을 목적으로 한다. JAXP(Java API for XML Processing), JAXM(Java API for XML Messaging), JAXB(Java API for XML Data Binding) 등 몇 개의 XML 관련 패키지를 통합한 것이다. 향후 자바 XML 팩에는 문서 처리, 데이터 처리 등 다른 XML 기술도 수록될 예정이다.

 

 

 

그외에 웹로직으로 알려진 BEA Systems의 스택스(StAX: Streaming API for Java)가 있다.


+ Recent posts