[Java] DOM과 SAX

SungminPark·2024년 1월 4일
0

자바 정리

목록 보기
8/10
post-thumbnail

파서가 필요한 이유


XML 문서는 단지 계층적 구조 형식의 문서이다.

XML 문서의 내용을 읽어 들여 처리하는 기능의 프로그램이 필요하며, 이 프로그램이 파서이다텍스트 형식인 XML 문서가 컴퓨터에 의해 처리되기 위해서는, 그 구조를 프로그램에 의해 처리 가능한 데이터 구조나 구조화된 정보 등으로 변환하는 것이 필요하다.

파서는 XML 응용 프로그램 개발 시, 세부적인 XML 문법으로부터 프로그램을 분리시켜 주는 역할을 하는데 동작하는 방식에 따라 DOM 과 SAX 파서가 있다.

DOM은 W3C가 표준으로 정한 파서이다.

파서는 XML 문서의 내용을 읽어 들이는 기능의 각 프로그래밍 언어 모듈(API)을 제공한다.

파서의 목적은 XML 문서의 내용을 검증하여 그 내용을 응용프로그램에게 전달하는 데 있다.

🎈 DOM (Document Object Model)


DOM은 XML문서를 나타내는 객체들의 인터페이스를 표준으로 정해놓은 것으로 DOM파서는 바로 XML문서로부터 DOM구조를 생성하는 역할을한다.
DOM은 XML 문서를 메모리에 트리 구조로 로드하여 데이터에 접근하는 방식이다.
전체 문서를 메모리에 로드하므로 작은 XML 파일에 적합하며, 데이터에 임의로 접근할 수 있는 장점이 있다.

DOM을 쓰는 이유


  • 문서의 일부를 두 번 이상 읽어야 할 때
  • 문서를 수정해야 할 때
  • 문서의 구조적인 처리가 필요할 때

=> DOM방식은 XML문서의 구조를 그대로 적용할 수 있으며 임의의 엘리면트나 속성에 바로 접근할 수 있고 값의 수정이 가능하다

DOM의 단점


  • 메모리 사용이 많다
    : 문서전체를 메모리에 올려두기 때문에 문서가 클 경우 메모리 사용량이 늘어날 수 있다.
  • 속도가 느리다
    : DOM 구조를 여러번 이용하는 경우엔 효과적 이지만, DOM구조를 한번만 읽어 처리하거나 다른 형식의 문서 구조를 처리하고자 하는 경우 비효율적이다.

🎈 SAX (Simple API for XML)


SAX 는 문자열을 앞에서 부터 차례로 읽어 가면서 요소, 속성이 인식될 때 마다 Event 를 발생시킨다.각각의 Event 발생에 대하여 핸들러를 구현하는 프로그래밍이다.
SAX는 이벤트 기반으로 XML을 파싱하는 방식이다. DOM과 달리 메모리를 적게 사용하며, 순차적으로 XML 문서를 읽어가면서 처리한다.

SAX를 쓰는 이유


SAX 의 장점은 속도와 단순함에 있으며, 모든 문서의 내용을 메모리에 올리지 않으므로 메모리를 적게 사용하게 된다.
XML 문서를 읽으면서 그 내용을 다른 Java 객체의 트리 구조로 변환하는 경우 또는 단지 XML 문서의 내용을 읽기만하려는 경우에는SAX 를 사용한다.

  • XML 문서를 순차적으로 일괄 처리하는 경우
  • 상대적으로 XML 문서 구조가 간단하고, 그 구조 자체가 주요 관심사가 아닌 경우
  • 메모리, 속도와 관련된 문제점을 우선적으로 고려해야 하는 경우

SAX의 단점


  • 문서 일부분에 대한 임의 접근이 불가능 하다.
  • 이벤트 및 작업 상태를 직접 보관해야 한다
  • SAX는 단순하게 어떤 요소를 읽었는지 등의 정보를 줄 뿐, 현재 이 요소가 어떤 요소의 일부인가 등의 문맥정보를 자동으로 유지해 주지 않는다

SAX는 한번에 문서를 훑어 내려가면서 읽기 때문에 성능은 높일 수 있지만, 내요 수정이 불가능 하다.

DOM과 SAX의 주요 차이점


DOM은 전체 문서를 메모리상에 올려놓고 처리하므로 원하는 요소를 바로 찾아가 추가 및 수정할 수 있는데 비해,
SAX는 문서를 처음에서 끝까지 순차적으로 처리하며 문서의 일부분만을 메모리에 올려 처리하므로 메모리를 적게 사용하는 반면 특정 요소를 수정하는 기능은 불가능 하다.

적용분야


DOM은 XML문서에 대한 구조적 접근이 필요한 경우, 문서 정보를 쉽게 파악하고자 할때 사용되며, SAX는 문서의 일부분만을 읽을 때 변환 시, 유효성 처리 시 사용한다.

🎈 DOM예제 코드


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class DOMParserExample {
    public static void main(String[] args) {
        try {
            // XML 파일 로딩
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse("example.xml");

            // 루트 엘리먼트 획득
            Element rootElement = document.getDocumentElement();

            // 자식 노드 목록 얻기
            NodeList nodeList = rootElement.getElementsByTagName("item");

            // 각 아이템 출력
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element item = (Element) nodeList.item(i);
                String value = item.getTextContent();
                System.out.println("Item: " + value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

예시 XML파일


<root>
    <item>Apple</item>
    <item>Orange</item>
    <item>Banana</item>
</root>

🎈 SAX예제 코드


import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;

public class SAXParserExample {
    public static void main(String[] args) {
        try {
            // XML 파일 로딩
            File xmlFile = new File("example.xml");

            // SAX 파서 생성
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            // 이벤트 핸들러 정의
            DefaultHandler handler = new DefaultHandler() {
                boolean itemFlag = false;

                @Override
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                    if (qName.equalsIgnoreCase("item")) {
                        itemFlag = true;
                    }
                }

                @Override
                public void characters(char[] ch, int start, int length) throws SAXException {
                    if (itemFlag) {
                        System.out.println("Item: " + new String(ch, start, length));
                        itemFlag = false;
                    }
                }
            };

            // 파싱 실행
            saxParser.parse(xmlFile, handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
profile
개발자 준비 중 입니다

0개의 댓글