2014/04/26

[Java] SAXParser를 이용하여 XML데이터 로드

원격서버에서 제공하는 XML데이터를 URL객체로 접근하여 스트림으로 읽어서 SAXParser로 분류하는 작업을 했다. 생각보다 간단했다.

SAXParser를 이용하는 경우 내부적으로 이벤트가 발생하는데 각 이벤트에 대해 정의된 DefaultHandler 인터페이스를 구현한 클래스에서 각 노드에 대해 접근하여 발췌하도록 구성한다.

* 수정 : 2010.04.27
- characters 메서드 변경
* 수정 : 2010.05.07
- XmlHandler 코드를 정리해서 추가 첨부
- empty element의 경우 데이터 획득이 안 되면서 element자체도 획득이 안 되는 문제 개선.


ReadXml.java
package com.xml;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;

public class ReadXml {
    public List read(String strUrl) {
        XmlHandler dh = null;
        
        try {
            URL url = new URL(strUrl);
            URLConnection urlConn = url.openConnection();
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            BufferedInputStream bis = new BufferedInputStream(urlConn.getInputStream());
            
            dh = new XmlHandler();
            parser.parse(bis, dh);
        } catch(MalformedURLException e) {
            System.out.println("[ MalformedURLException : " + strUrl + " ]");
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            System.out.println("[ ParserConfigurationException ]");
            e.printStackTrace();
        } catch (SAXException e) {
            System.out.println("[ SAXException ]");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("[ IOException ]");
            e.printStackTrace();
        }
        
        return dh.getList();
    }
}

XmlHandler.java
package com.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class XmlHandler extends DefaultHandler {
    String strJobName = "";
    private List list = new ArrayList();
    private HashMap map = null;
    private String strEname = "";
    private StringBuffer strBuff = new StringBuffer();
    private boolean bIsColumn = false;
 
    public void startDocument( ) throws SAXException {
        System.out.println( "SAX Event: [" + strJobName + "] START DOCUMENT ##################################" );
    }
    
    public void endDocument( ) throws SAXException {
        System.out.println( "List Size is " + list.size() );
        System.out.println( "SAX Event: [" + strJobName + "] END DOCUMENT ####################################" );
    }
    
    @SuppressWarnings("unchecked")
    public void startElement(String uri, String localName, String eName, Attributes attr) throws SAXException {
        //  System.out.println("SAX Event: START Element localName: " + localName);
        //  System.out.println("SAX Event: START Element eName: " + eName);
        //발췌 대상 엘리먼트 구분(엘리먼트 prefix로 구분함)
        if( eName.equals("item") ) {
            map = new HashMap();
        } else if( eName.substring(0, 3).equals("ns3") && !eName.equals("ns3:data") ) {
            strEname = eName.substring(4);
            bIsColumn = true;
            //데이터 버퍼 초기화
            strBuff.setLength(0);
            //   System.out.println(" Check Element eName: " + eName.substring(4));
        } else {
            bIsColumn = false;
        }
    }
 
    @SuppressWarnings("unchecked")
    public void endElement(String uri, String localName, String eName) throws SAXException {
        if( eName.equals("item") ) {
            list.add(map);
            //   System.out.println("SAX Event: END Element eName: " + eName);
        } else {
            if(bIsColumn) {
                //     System.out.println(strEname + " : ["+ strBuff.toString().trim() + "]");
                map.put(strEname, strBuff.toString().trim());
            }
        }
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        //발췌 대상 엘리먼트의 값만 추출
        if(bIsColumn) {
        strBuff.append(ch, start, length);
        //      System.out.println(strEname + " is [" + map.get(strEname) + "]");
        //      System.out.println("Char Start : " + start + " Length : " + length);
        }
    }
 
    /**
    * 발췌한 대상 서비스 데이터 리턴
    * @return List
    */
    @SuppressWarnings("unchecked")
    public List getList() {
        return this.list;
    }
}

댓글 없음:

댓글 쓰기