본문 바로가기

Programming/Java

XML parser using Java SAX library (Java SAX 이용하여 XML Parser 만들기)

자바에서 XML 파일을 파싱하는 Parser 를 만들기 위해서, 사용할 수 있는 라이브러리들은

다양하다. 그중에서 유명한 것이, DOM 과 SAX 이다.


DOM Parser 는 xml text 의 string들과 stream 들을 parsing 할 때 사용되는 것으로서,

XML 을 parsing 하면서, 트리구조를 만들고 이 트리구조 전체를 메모리 상에 로드 시킨다.


장점은: 사용법이 간단하고, 트리구조 전체를 볼 수 있다는 것.

단점은: 메모리를 많이 먹고, 조금 느리다는 점 이 있다.


더 자세한 정보를 얻고 싶으면 아래의 링크로 가서 살펴보면 도움이 된다.

http://www.w3schools.com/DOM/dom_intro.asp


SAX Parser 는 Simple API for XML Parser 의 약어로, Java API 에서 제공한다.

기본적으로 SAX Parser는 노드들이 들어올때마다 event 가 발생하면서 순차적으로 parsing 을

하게 된다. 그래서 어떤 노드에 무작위 적으로 접근을 하기 위해서는 이 node들을 사용자가 트리구조로 생성한뒤, 메모리에 올려서 사용하여야 한다.


장점은: 순차적으로 파싱을 하기 때문에 속도가 빠르고 메모리를 적게 먹는다.

단점은: 특정 노드를 무작위적으로 접근하는 random access 를 할 수 없다.


본인은 여기서 SAX Parser를 사용하기로 생각을 했다.


기본적으로 SAX Parser를 사용하기 위해서는 아래의 라이브러리들이 필요하다.


import javax.xml.parsers.*;

import org.xml.sax.*;

import org.xml.sax.helpers.*;


그다음 파서가 될 클래스는 DefaultHandler 라는 클래스를 상속 받아야 한다.


다음에는 startElement(...), characters(...), endElement(...) 메소드들의 행동을 구현해야 하고,

SAXParser 의 parse() 메소드를 호출 할 때, 해야 할 일들을 구현해야 한다.


아래의 코드는 SAX Parser를 이용한 간단한 xml file을 파싱하는 예제이다.


import javax.xml.parsers.*;

import org.xml.sax.*;

import org.xml.sax.helpers.*;


import java.io.*;

import java.lang.StringBuffer;


public class SimpleSAXParser extends DefaultHandler {


    private SAXParserFactory parserFact;

    private SAXParser parser;

    private Attributes tagAttributes;


    private String fileName; // xml file name to be parsed

    private String startTagName;

    private String endTagName;

    private String tagData;

    private String [] attrQNames; // attribute's names

    private String [] attrValues; // attribute's values


    private StringBuffer buffer = new StringBuffer();


    public SimpleSAXParser(String fileName)

    {

        super();

        try

        {

            parserFact = SAXParserFactory.newInstance();

            parser = parserFact.newSAXParser();

        }catch(Exception e){}


        this.fileName = fileName;

    }

    // 이 메소드는 태그가 시작될때 이것을 읽으면서 발생하는 이벤트 핸들링 메소드이다.

    // 예: <tag>data</tag> 여기서, 왼쪽에 있는 <tag> 가 읽히면서 발생하는 이벤트

    public void startElement(String uri, String lName, String ele, Attributes attributes)throws SAXException

    {

        startTagName = ele;

        tagAttributes = attributes;


        attrQNames = new String[tagAttributes.getLength()];

        attrValues = new String[tagAttributes.getLength()];


        for(int i = 0; i < tagAttributes.getLength(); i++)

        {

            attrQNames[i] = tagAttributes.getQName(i).trim();

            attrValues[i] = tagAttributes.getValue(i).trim();

        }

        // 여기서 버퍼를 비워줘야, 이전에 버퍼에서 읽었던 것들을 깨끗하게 할 수 있다.

        buffer.setLength(0); // 버퍼 비우기

    }


    // 이 메소드는 태그의 내용을 읽으면서 발생하는 이벤트 핸들링 메소드이다.

    // 예: <tag>data</tag> 여기서, 가운데 있는 data 가 읽히면서 발생하는 이벤트

    public void characters(char[] ch, int start, int len) throws SAXException{

        buffer.append(ch, start, len); // 버퍼에 data 를 집어 넣기.

    }


    // 이 메소드는 태그가 끝날때 이것을 읽으면서 발생하는 이벤트 핸들링 메소드이다.

    // 예: <tag>data</tag> 여기서, 오른쪽에 있는 <tag> 가 읽히면서 발생하는 이벤트

    public void endElement(String uri, String localName, String qName)

    {

        endTagName = qName;

        tagData = buffer.toString().trim(); // end tag 가 오면 버퍼에 있는 내용을 사용

    }


    public void parse(){ // SAXParser 의 parse() method를 호출하여 fileName 이라는 xml 을 파싱

        try {

            parser.parse(fileName, this);

        } catch (SAXException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }


    public static void main(String [] args){

        if(args.length < 1){

            System.out.println("usage: java InputParser xml_file_name");

            System.exit(0);

        }

        SimpleSAXParser parser = new SimpleSAXParser(args[0]);

        try{

            parser.parse();

            System.out.println("parsing success.");

        } catch(Exception e){

            System.out.println("parsing error.");

            e.printStackTrace();

            System.exit(0);

        }


    }

}