본문 바로가기

Java/문법 및 이해

[Java] SAX Parser

1. SAX Parser

Simple API for XML Parser의 약어로, 자바 API에서 제공한다.

DOM Parser와는 다르게 SAX Parser는 문서를 딱 한번만 읽는다.
다시말해, 한 번 읽는데 문서를 순회하면서 event가 발생하면 순차적으로 파싱을 하게 된다. 즉, XML 문서를 읽어들여서 어떤 태그를 만나면 그에 따라 이벤트를 생성한다.

하지만 딱 한번 순회하므로 다양한 형태로 처리할 수 없지만, 가볍고 파서가 간단하다는 장점이 있다.

 

2. SAX 구조 모델 : 이벤트 기반 인터페이스

XML 문서를 읽을 때 SAX 파서는 어떻게 이벤트를 발생하게 될까?

위 예시 처럼 특정 위치에서 이벤트를 발생시키는 메서드들이 존재한다.

 

(1) startElement() : 태그를 처음 만나면, 발생하는 이벤트

(2) endElement() : 닫힌 태그를 만나면 발생하는 이벤트

(3) characters() : 태그와 태그 사이의 text(내용)을 처리하기 위한 이벤트

 

 

3. SAX Parser 간단 예시

package IO.xml;

import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

// dom parser => xml 문서를 memory에 올려서 처리 => 위, 아래 또는 부모, 자식 이동이 자유롭다.
//           => 무겁다.
// sax parser => xml 문서를 시작에서 종료 순으로 1번  scan 하면서 처리하고 끝.
//       => 한번 순회하므로 되돌아갈 수 없다. 그리고 가볍다. tag 를 만나면 event 를 발생시켜서 특정 메서드를 호출해준다.

// xml => ArrayList<Emp>
public class EmpListSAXHandler extends DefaultHandler {

   List<Emp> empList = new ArrayList<>();

   // <emp> 태그를 만났을 때, 객체를 생성해야 한다.
   // startElemenet 때마다 객체를 만든다면 문제가 발생 -> private로 미리 생성.
   private Emp emp;
   private String data;

   @Override
   public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      // qName == emp 이면
      if ("emp".equals(qName)) {
         emp = new Emp();
      }
   }

   @Override
   public void endElement(String uri, String localName, String qName) throws SAXException {
      // qName 이 Emp, empId, empNm, salary
      // 닫는 태그를 만났을 때, 데이터를 저장해야함
      switch (qName) {
         case "empId" : emp.setEmpId(data); break;
         case "empNm" : emp.setEmpNm(data); break;
         case "salary" : emp.setSalary(Integer.parseInt(data)); break;
         case "emp" : empList.add(emp);
      }
   }

   @Override
   public void characters(char[] ch, int start, int length) throws SAXException {
      data = new String(ch, start, length);
   }
   
   // empList를 넘겨주기 위한 메서드
   public List<Emp> getEmpList() {
      return this.empList;
   }
}

앞서 설명한 3개의 메서드는 DefaultHandler의 메서드를 오버라이드하고 있다.

 

startElement() 부분을 보면,

"emp"에 해당하는 태그를 emp 라는 객체에 저장한다. 즉, xml 데이터를 원하는 데이터 부분에서 읽기 시작한 것이다.

 

endElement()는  닫는 태그를 만났을 때, 해당 데이터를 변수에 저장한다.

 

characters()는 태그와 태그 사이의 text를 처리하기 위한 메서드이다.

'Java > 문법 및 이해' 카테고리의 다른 글

[JAVA] intelliJ에서 JDBC와 MySQL 연동  (0) 2023.02.12
[JAVA] JDBC 란?  (0) 2023.02.11
[JAVA] 람다와 함수형 인터페이스  (0) 2023.01.27
[JAVA] Singleton 싱글톤 디자인 패턴  (0) 2023.01.22
[JAVA] 다형성 Polymorphism  (0) 2023.01.15