달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2007. 2. 14. 17:49

05. XML 스트림 (SAX) 그거/Tech2007. 2. 14. 17:49

- SAX 란?
  . DOM에서 처리하기 어려운 연산을 지원하기 위한 목적으로 XML-DEV 메일링 리스트의 구성원들이 만든 XML 처리를 위한 API
  . SAX는 XML 파일을 정보를 전달하는 이벤트들의 스트림으로 다룬다.
  . 스트림의 순서에 따라 이벤트를 검사하여 순차적으로 처리.

  <votes totalVotes="5">
 <voter personid="1" status="primary">
  <vote>Sparkel</vote>
  <comments>It's about time we had this vote!</comments>
 </voter>
  </votes>

  DOM parser의 관점
    . votes element는 2개의 text element(줄바뀜)와 하나의 element(voter)
   <votes>#text
     <voter>..
  </voter>#text
   </votes>
 . voter element는 3개의 text element(줄바뀜)와 2개의 element(vote, comments)
  <voter>#text
    <vote>Sparkel</vote>#text
    <comments>It's about time we had this vote!</comments>#text
  </voter>

  SAX parser의 관점
    elemnt(votes) 시작
 #text 무시
 elemtn(voter) 시작
 #text 무시
 elemtn(vote) 시작
 문자(Sparkle)
 element(vote) 종료
 #text 무시
 element(comments) 시작
 문자(It's a bout time we had this vote!)
 element(comments) 종료
 #text 무시
 element(voter) 종료
 #text 무시
 element(votes) 종료

  SAX vs DOM
    다루려는 XML 문서의 유형에 따라 적용.
 SAX
  읽기 전용의 method를 제공하기 때문에 정보를 읽을 수 있으나 소스 문서에는 아무런 변화를 줄 수 없다.
  단방향 method를 제공하기 때문에 한 번 읽고 처리된 element에 재접근하려면 문서를 다시 파싱해야 한다.
  시간 순서에 따라 처리하기 때문에 사용이 확실치 않은 정보들로 메모리를 낭비할 필요가 없다.
  필요로 하는 정보를 찾은 후에는 바로 파싱의 과정을 종료할 수 있다.

- SAX parser의 생성
  . SAX parser의 구성
    Parser
 XMLReader
 ContentHandler, ErrorHandler

  . XMLReader의 생성
    XMLReader reader = XMLReaderFactory.createXMLReader();

  . ContentHandler
    10여개 정도의 event(startElement, endDocument...) 정의

  . ErrorHandler
    3개의 event(warning, error, fatalError) 정의

  . DefaultHandler
    이벤트마다 interface에 정의된 메소드들을 구현해야 하는 번거로움을 제거.

 public class DataProcessor extends DefaultHandler {
  public DataProcessor() {
   super();
  }
 }

 public class ErrorProcessor extends DefaultHandler {
  public ErrorProcessor() {
   super();
  }

  public void error(SAXParseException e) {
   System.out.println("Error : " + e.getMessage());
  }

  public void fatalError(SAXParseException e) {
   System.out.println("Fatal Error : " + e.getMessage());
  }

  public void warning(SAXParseException e) {
   System.out.println("Warning : " + e.getMessage());
  }
 }

 warning : 오류로 취급되지는 않지만 사용자에게는 전달할 필요가 있는 항목.
 error   : XML 1.0 권고안에서 정의한 오류들. 오류 발생시 파서는 더 이상 실행되지 않음.
 fatal error : 오류로 인해 파서의 계속적인 수행이 불가능하면 발생.

 DTDHandler     : 내부 DTD에서 정의되는 notation과 parsing 되지 않는 entity들에 대한 통지 수신
 DeclHandler    : DOCTYPE과 관련된 기타 event에 대한 통지 수신
 LexicalHandler : startDTD와 endCDATA 같은 이벤트들에 대한 통지 수신

  . Handler 설정
    XMLReader reader = XMLReaderFactory.createXMLReader(parserClass);
    reader.setContentHandler(new DataProcessor());
 reader.setErrorHandler(new ErrorProcessor());

  . 문서의 parsing
    InputSource file = new InputSource("votes.xml");
    reader.parse(file);

 InputStrea, Reader, String 모두 파서의 입력으로 이용 가능

- event의 처리

  . Document event
    public void startDocument() {}
 public void endDocument() {}

  . Element event
    public void startElement(String namespaceUri, String localName, String qualifiedName, Attributes attributes) {
  attributes.getLocalName(int i);
  attributes.getQName(int i);
  attributes.getValue(attributes.getQName(int i));
 }
    public void endElement(String namespaceUri, String localName, String qualifiedName) {}

  . Text event
    SAX에서 text contents는 element event가 아닌 characters event를 통해 전송된다.

 StringBuffer thisText = new StringBuffer();
 public void characters(char[] ch, int start, int length) {
  thisText.append(ch, start, length);
 }

 public void ignorableWhitespace(char[] ch, int start, int length) {}

  . startPrefixMapping(String prefix, String uri)
    namespace가 범주에 포함될 때 발생
  . endPrefixMapping(String prefix)
    namespace가 범주를 벗어날 때 발생
  . processingInstruction(String target, String data)
    parser가 처리 지시문에 접근했을 때 발생
  . skippedEntity(String name)
    parser과 외부 entity를 발견할 때 발생

- filter and chain

  . filter
    parser와 contents handler 사이에 위치
 데이터 처리 이전에 filter를 사용하여 application에 적합한 데이터로 변경

 parse -> filter -> content handler -> application

  . XMLFilter 생성
    public class DataFilter extends XMLFilterImpl {
  public DataFilter() {
  }

  public DataFilter(XMLReader parent) {
   super(parent);
  }
 }

 XMLFilterImpl은 DefaultHandler 클래스의 method 뿐만 아니라 XMLReader의 모든 method들도 구현한다.
 XMLFilterImpl은 DefaultHandler, XMLReader 두 class 모두의 역할을 수행

  . Stream에 filter의 삽입
    XMLFilter filter = new DataFilter();
 filter.setParent(reader);
 filter.setContentHandler(new DataProcessor());
 filter.setErrorHandler(new ErrorProcessor());
 filter.parse(new InputSource("votes.xml"));

  . Data의 filtering
 method를 overide 해서 사용한다.


'그거 > Tech' 카테고리의 다른 글

07.DTD(Document Type Definition)  (0) 2007.02.15
06. XML 문서에 대한 유효성 검증  (0) 2007.02.15
04. DOM의 활용(고급편)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
02. XML 문서와 application의 설계  (0) 2007.02.14
:
Posted by 뽀기