LexicalHandler Programming using SAX(Simple API for XML)


다음은 JAVA를 사용한 SAX 프로그래밍에 관한 내용입니다.

SAX 1.0의 네 가지 이벤트핸들러 외에 SAX 2.0에 들어오면서 DeclHandler와 LexicalHandler가 추가되었다.

1. LexicalHandler 소개
LexicalHandler는 XML 문서의 주요 구성 성분이 아닌 주석문이나 CDATA 섹션과 같은 렉시칼(Lexical)과 관련된 이벤트 핸들러이다. "lexical"이란 단어를 사전에서 찾아보면 "어휘"라는 뜻을 가지고 있다. 뜻처럼 문맥에 영향을 끼치지 않는 단어나 어휘의 개념으로 해석하면 되며 이와 관련된 이벤트 핸들러가 LexicalHandler이다.

LexicalHandler에는 7개의 이벤트메소드가 정의되어 있다.
  • void startDTD (String name, String publicld, String systemld)
  • void endDTD ()
  • void startEntiry (java.lang.String name)
  • void endEntity()
  • void startCDATA()
  • void endCDATA()
  • void comment(char[] ch, int start, int length)
startDTD() 메소드는 DTD 선언의 시작 시 발생하는 이벤트로써, name은 DTD의 식별자(XML 문서의 루트 엘리먼트 이름)를 나타내고, publicId와 systemId는 DTD가 존재하는 URI를 나타낸다.

endDTD() 메소드는 DTD 선언이 끝날 때 발생하는 이벤트이다.

startEntity() 메소드는 엔티티의 선언이나 엔티티 참조의 시작 시 발생하는 이벤트로써, name 인자는 엔티티의 이름을 나타낸다. 만약 엔티티의 선언이 외부 DTD 파일에 존재한다면 name 인자는 "[dtd]" 값을 반환하게 된다.

endEntity() 메소드는 엔티티가 사용 종료되었을 때 발생하는 이벤트 메소드이다.

startCDATA() CDATA Section이 시작될 때 발생하는 이벤트이다.

endCDATA() CDATA Section이 끝날 때 발생하는 이벤트이다.

startCDATA()와 endCDATA() 메소드는 CDATA Section의 시작과 끝만을 알려줄 뿐, 값을 얻을 수 없다는 것이 특징이다.

comment()이벤트 메소드는 XML 문서에서 주석문을 만났을 때 발생하는 이벤트로써, 주석문의 내용은 문자 배열로 제공된다.



2. LexicalHandler의 구현
LexicalHandler는 ContentHandler의 작성과 마찬가지로 LexicalHandler 내의 모든 이벤트 메서드를 구현하면 된다.

ContentHandler를 등록하기 위해서 XMLReader 객체의 setContentHandler() 메소드를 이용하였고, ErrorHandler를 등록하기 위해서 setErrorHandler() 메소드를 이용하였다. 이처럼 SAX 1.0에서 이벤트 핸들러를 등록하는 메소드를 제공하였지만, SAX 2.0에서 제공되는 핸들러는 별도의 등록 메소드를 제공하지 않는다.

따라서 SAX 2.0에서 제공되는 확장 핸들러를 등록하기 위해서는 XMLReader 객체의 setProperty() 메소드를 이용하면 된다. setProperty() 메소드는 XMLReader 객체의 속성을 설정하기 위한 메소드로써 원형은 다음과 같다.
     void setProperty (java.lang.String name, java.lang.Object value)

setProperty() 메소드의 name 인자는 속성 설정을 위한 속성 이름을 나타내고, value는 SAX 2.0의 확장 핸들러가 구현(implements)된 객체를 나타낸다. SAX 2.0의 혹장 핸들러를 등록하기 위한 속성 이름은 다음과 같다.
     LexicalHandler - http://xml.org/sax/properties/lexical-handler
     DeclHandler - http://xml.org/sax/properties/declaration-handler

LexicalHandler를 등록하기 위해서는 위의 URI를 사용해서 등록하면 된다.


다음은 LexicalHandler를 사용한 간단한 구현 예이다.

- SAXSample.dtd

<!ELEMENT booklist (book+)>
<!ELEMENT book  (name, page)>
<!ELEMENT name  (#PCDATA)>
<!ELEMENT page  (#PCDATA)>
<!ENTITY bookname "XML과 XML Web Services">

- SAXSample.xml
<?xml version="1.0" encoding="euc-kr" standalone="no"?>
<!DOCTYPE booklist SYSTEM "SAXSample.dtd">
<!-- 책 정보에 관한 XML -->
<booklist>
      <book>
            <name>
                  &bookname;
            </name>
            <page><![CDATA[ 648 ]]></page>
      </book>
</booklist>

import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.ext.*;
public class ExtLexicalHandler {
      public static void main(String[] args) {
            try {
                  String LEXICAL_URI = "http://xml.org/sax/properties/lexical-handler";
   
                  SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
                  SAXParser saxParser = saxParserFactory.newSAXParser();
                  XMLReader xmlReader = saxParser.getXMLReader();
   
                  ImplHandler handler = new ImplHandler();
                  xmlReader.setProperty(LEXICAL_URI, handler);
                  xmlReader.parse("SAXSample.xml");  
            } catch(Exception e) {
                  e.printStackTrace(System.err);
            }
      }
}
class ImplHandler implements LexicalHandler {
      public void startDTD(String name, String publicId, String systemId) {
            System.out.println("Start DTD");
            System.out.println(" Document Name : " + name);
            System.out.println(" Document Public URI : " + publicId);
            System.out.println(" Document System URI : " + systemId);
      }
      public void endDTD() {
            System.out.println("End DTD");
      }
      public void startEntity(String name) {
            System.out.println(name + " Entity Start");
      }
      public void endEntity(String name)  {
            System.out.println(name + " Entity End");
      }
      public void startCDATA() {
            System.out.println("Start CDATA Section");
      }
      public void endCDATA() {
            System.out.println("End CDATA Section");
      }
      public void comment(char[] ch, int start, int length) {
            String commentString = new String(ch, start, length);
            System.out.println("Comment : " + commentString);
      }
}

- Output
Start DTD
           Document Name : booklist
           Document Public URI : null
           Document System URI : SAXSample.dtd
[dtd] Entity Start
[dtd] Entity End
End DTD
Comment :  책 정보에 관한 XML
bookname Entity Start
bookname Entity End
Start CDATA Section
End CDATA Section


Reference : 소설같은 XML & XML Web Services




신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Proneer

댓글을 달아 주세요


티스토리 툴바