티스토리 뷰

Studying/Web Application

XML Parser 정리

hongkyu 2012. 10. 10. 08:26

1.      DOM SAX 비교

DOM SAX에 대해서 기술하시오.

1)     DOM(Document Object Model) 방식

     DOM WEC에 의해 주관되는 표준 XML 처리 방법이다. DOM XML만을 위한 것이 아니라 XML과 같은 마크업 형식을 따르는 모든 문서를 처리하기 위한 표준 API이다. 그래서 DOM HTML뿐만 아니라 스타일시트를 위한 API도 함께 포함하고 있다.

     DOM XML 문서를 처리하기 위해 XML 문서를 읽고 메모리에 로딩한다. 메모리에 로딩된 XML은 트리 구조를 가지며, 트리 기반(Tree Based) API를 이용해서 XML 문서를 처리할 수 있다.

     DOM은 버전으로 구분되지 않고 Level에 의해 구분되는데, 현재 Level 3 일부가 권고안으로 확정된 상태이다.

 

2)     SAX(Sample API for XML) 방식

     DOM XML 문서를 메모리에 로딩하기 때문에 처리 속도가 느리고, XML 문서의 크기가 클 경우 많은 양의 메모리를 필요로 한다. 이런 단점을 극복하기 위해 만들어진 것이 바로 SAX이다. SAX XML-Dev Mailling List 회원들의 제안으로 만들어 졌고, 그 대표주자가 David Magginson이다.

     DOM XML 문서를 메모리에 로딩한 후 처리하는 방식을 사용하는 반면, SAX XML 문서를 읽어가면서 이벤트를 호출하여 처리하는 이벤트 기반(Event Based)의 처리 방식을 사용한다. XML 문서를 처리하기 위한 필요한 이벤트를 등록하면 SAX 파서가 XML 문서를 읽으면서 동시에 등록된 이벤트에 해당하는 부분을 만났을 때 이벤트가 호출되는 방식으로 동작한다.

     현재 SAX 2.0까지가 발표된 상태이며, 이는 http://www.saxproject.org 에서 확인할 수 있다.

 

3)     DOM 방식과 SAX 방식 비교

구분

DOM

SAX

파싱방법

Tree-Working기반

Event기반

처리방법

메모리에 로딩, Tree 자료구조화

순차적인 이벤트 발생 처리

장점

문서 구조 동적 변경 가능

복잡한 처리 연산 가능

문서 생성 및 편집 가능

XML 문서의 크기에 관계없이 파싱 가능

자신만의 데이터 구조 생성 가능

XML 문서의 일부만 처리 가능

단순하고 속도가 빠름

단점

메모리 요구량이 많음

처리 속도가 느림

문서의 구조에 대한 정보 파악이 어려움

문서 생성, 편집이 불가능

적용분야

구조적 접근이 필요한 경우

특정 부분으로 이동할 경우

문서 정보를 쉽게 파악하고자 하는 경우

문서 일부분만 읽는 경우

유효성 처리, 데이터 변환이 필요한 경우

동일 오류 처리가 필요한 경우

Element를 일부 추출하는 경우

구조변경

데이터 구조 변경 가능

데이터 구조 변경 불가

접근방식

Random Access 방식

Streaming 방식

 

2.      전제 조건

- code.xml 파일

 

<?xml version="1.0" encoding="UTF-8" ?>

<codes>

 

           <group id="locale">

                     <code id="ko_KR" value="ko_KR"/>

                     <code id="en_US" value="en_US"/>

           </group>

 

           <!-- MESSAGE -->

           <group id="messageType">

                     <code id="I"  value="정보성"/>

                     <code id="E"  value="에러성"/>

                     <code id="S"  value="성공성"/>

           </group>

 

           <group id="logLevel">

                     <code id="OFF"    value="OFF"/>

                     <code id="ALL"    value="ALL"/>

                     <code id="TRACE"  value="TRACE"/>

                     <code id="DEBUG"  value="DEBUG"/>

                     <code id="INFO"   value="INFO"/>

                     <code id="WARN"   value="WARN"/>

                     <code id="ERROR"  value="ERROR"/>

                     <code id="FATAL"  value="FATAL"/>

           </group>

 

           <!-- status -->

           <group id="status">

                     <code id="1"  value="스케줄"/>

                     <code id="2"  value="실행"/>

                     <code id="3"  value="완료"/>

                     <code id="4"  value="실패"/>

                     <code id="5"  value="삭제"/>

                     <code id="6"  value="시스템종료"/>

           </group>

 

</codes>

 

 

3.      VO(Value Object, Entity) 클래스

XML 파일에 대응되는 VO(Value Object, Entity) 클래스를 작성하시오.

- CodeVO 클래스

 

import java.util.Map;

 

public class CodeVO {

      

       private String groupId;

       private Map<String, String> codes;

      

       public String getGroupId() {

             return groupId;

       }

       public void setGroupId(String groupId) {

             this.groupId = groupId;

       }

       public Map<String, String> getCodes() {

             return codes;

       }

       public void setCodes(Map<String, String> codes) {

             this.codes = codes;

       }

}

 

 

4.      DOM parser

XML 파일을 DOM parser를 사용하여 위에서 작성한 VO로 변환하는 로직을 작성하시오.

- DomParser 클래스 (getCodeVos 함수를 호출로 변환)

 

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import org.apache.xerces.parsers.DOMParser;

import org.w3c.dom.Document;

import org.w3c.dom.NamedNodeMap;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

 

public class DomParser {

      

       public List<CodeVO> getCodeVos(String filePath) {

            

             DOMParser parser = new DOMParser();

             List<CodeVO> codeVos = new ArrayList<CodeVO>();

             String url = "file:" + new File(filePath).getAbsolutePath();

             Document document = null;

            

             try {

             parser.parse(url);

            

             document = parser.getDocument();

             

             // 최상위 노드(codes)

             NodeList nodes_0 = document.getChildNodes();

            

             // 1단계(group)

             NodeList nodes_1 = nodes_0.item(0).getChildNodes();

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

             Node node_1 = nodes_1.item(i);

             if(node_1.getNodeType()==Node.ELEMENT_NODE &&

node_1.getNodeName().equals("group")){

             CodeVO codeVo = new CodeVO();

            

             NamedNodeMap attr_1 = node_1.getAttributes();

             codeVo.setGroupId(attr_1.getNamedItem("id").getNodeValue());

            

             // 2단계(code)

             NodeList nodes_2 = node_1.getChildNodes();

             Map<String, String> codes = new HashMap<String, String>();

             for(int k=0; k<nodes_2.getLength(); k++){

             Node node_2 = nodes_2.item(k);

             if(node_2.getNodeType()==Node.ELEMENT_NODE &&

                           node_2.getNodeName().equals("code")){

              NamedNodeMap attr_2 = node_2.getAttributes();

             String codeId = attr_2.getNamedItem("id").getNodeValue();

             String codeValue = attr_2.getNamedItem("value").getNodeValue();

            

             if(codeId!=null && codeValue!=null){

                    codes.put(codeId, codeValue);

             }

             }

             }

             codeVo.setCodes(codes);

             codeVos.add(codeVo);

             }

             }

                   

             } catch (SAXException e) {

                    e.printStackTrace();

             } catch (IOException e) {

                    e.printStackTrace();

             }

            

             return codeVos;

       }     

}

 

 

5.      SAX parser

XML 파일을 SAX parser를 사용하여 위에서 작성한 VO로 변환하는 로직을 작성하시오.

- SaxParser 클래스 (getCodeVos 함수를 호출로 변환)

 

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import org.apache.xerces.parsers.SAXParser;

import org.xml.sax.Attributes;

import org.xml.sax.ContentHandler;

import org.xml.sax.Locator;

import org.xml.sax.SAXException;

 

public class SaxParser {

      

       public List<CodeVO> getCodeVos(String filePath) {

            

             SAXParser parser = new SAXParser();

             List<CodeVO> codeVos = new ArrayList<CodeVO>();

             String url = "file:" + new File(filePath).getAbsolutePath();

            

             try {

             CodeContentHandler codeContentHandler = new CodeContentHandler();

             parser.setContentHandler(codeContentHandler);

             parser.parse(url);

            

             codeVos = codeContentHandler.getCodeVos();

            

             } catch (SAXException e) {

                    e.printStackTrace();

             } catch (IOException e) {

                    e.printStackTrace();

             }

            

             return codeVos;

       }

      

       public class CodeContentHandler implements ContentHandler {

 

       List<CodeVO> codeVos = null;

       CodeVO codeVo = null;

       Map<String, String> codes = null;

      

       List<CodeVO> getCodeVos(){

             return codeVos;

       }

      

       @Override

       public void startDocument() throws SAXException {

             codeVos = new ArrayList<CodeVO>();

       }

      

       @Override

       public void endDocument() throws SAXException {

       }

       @Override

       public void startElement(String uri, String localName, String qName,

                    Attributes atts) throws SAXException {

             if(localName.equals("group")&&atts.getLength()==1) {

                   

                    if(codeVo==null){

                           codeVo = new CodeVO();

                    }

                    codeVo.setGroupId(atts.getValue("id"));

             }else if(localName.equals("code")&&atts.getLength()==2) {

                   

                    if(codes==null){

                           codes = new HashMap<String, String>();

                    }

                    codes.put(atts.getValue("id"), atts.getValue("value"));

             }

       }

      

       @Override

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

                    throws SAXException {

             if(localName.equals("group")&&codeVo!=null){

                    codeVo.setCodes(codes);

                    codes = null;

                   

                    codeVos.add(codeVo);

                    codeVo = null;

             }

       }

 

       @Override

       public void startPrefixMapping(String prefix, String uri)

                    throws SAXException {

       }

       @Override

       public void endPrefixMapping(String prefix) throws SAXException {

       }

       @Override

       public void characters(char[] ch, int start, int length)

                    throws SAXException {

       }

       @Override

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

                    throws SAXException {

       }

       @Override

       public void processingInstruction(String target, String data)

                    throws SAXException {

       }

       @Override

       public void setDocumentLocator(Locator locator) {

       }

       @Override

       public void skippedEntity(String name) throws SAXException {

       }

}

 

 

6.      XML 기록 (DOM 방식 사용)

변환된 객체를 DOM 방식으로 XML 파일에 기록하는 로직을 작성하시오.

- DomToXml 클래스 (writeXML 함수를 호출로 파일 저장)

 

import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStreamWriter;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

 

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.transform.OutputKeys;

import javax.xml.transform.Result;

import javax.xml.transform.Source;

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;

 

import org.w3c.dom.Document;

import org.w3c.dom.Element;

 

public class DomToXml {

 

       public boolean writeXML(List<CodeVO> codeVos, String filePath) {

            

             DocumentBuilderFactory dbf = null;

             DocumentBuilder documentBuilder = null;

             Document document = null;

                          

             try {

             dbf = DocumentBuilderFactory.newInstance();

             documentBuilder = dbf.newDocumentBuilder();

             document = documentBuilder.newDocument();

            

             // 최상위 노드(codes)

             Element element_0 = document.createElement("codes");

            

             // 1단계(group)

             for(int i=0; i<codeVos.size(); i++){

                    CodeVO codeVo = codeVos.get(i);

                   

                    Element element_1 = document.createElement("group");

                    element_1.setAttribute("id", codeVo.getGroupId());

                   

                    // 2단계(code)

                    Map<String, String> codes = codeVo.getCodes();

                    Set<String> keySet = codes.keySet();

                    Iterator<String> iterator = keySet.iterator();

                    while(iterator.hasNext()){

                           Element element_2 = document.createElement("code");

                           String codeId = iterator.next();

                           element_2.setAttribute("id", codeId);

                          element_2.setAttribute("value", codes.get(codeId));

                           element_1.appendChild(element_2);

                    }

                    element_0.appendChild(element_1);

             }

                    document.appendChild(element_0);

            

             // 파일생성

             Source source = new DOMSource(document);

             Result result = new StreamResult(new OutputStreamWriter(

new FileOutputStream(new File(filePath)), "utf-8"));

            

             TransformerFactory transformerFactory =

TransformerFactory.newInstance();

             transformerFactory.setAttribute("indent-number", new Integer(4));

            

             Transformer transformer = transformerFactory.newTransformer();

             transformer.setOutputProperty(OutputKeys.INDENT, "yes");

            

             transformer.transform(source, result);

            

             } catch (Exception e) {

                    e.printStackTrace();

                    return false;

             }

            

             return true;

       }

}

 

 

- DomToXml를 통해 생성된 XML 파일

 

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<codes>

    <group id="locale">

        <code id="ko_KR" value="ko_KR"/>

        <code id="en_US" value="en_US"/>

    </group>

    <group id="messageType">

        <code id="E" value="에러성"/>

        <code id="S" value="성공성"/>

        <code id="I" value="정보성"/>

    </group>

    <group id="logLevel">

        <code id="ERROR" value="ERROR"/>

        <code id="FATAL" value="FATAL"/>

        <code id="OFF" value="OFF"/>

        <code id="WARN" value="WARN"/>

        <code id="INFO" value="INFO"/>

        <code id="ALL" value="ALL"/>

        <code id="DEBUG" value="DEBUG"/>

        <code id="TRACE" value="TRACE"/>

    </group>

    <group id="status">

        <code id="3" value="완료"/>

        <code id="2" value="실행"/>

        <code id="1" value="스케줄"/>

        <code id="6" value="시스템종료"/>

        <code id="5" value="삭제"/>

        <code id="4" value="실패"/>

    </group>

</codes>

 

 

반응형

'Studying > Web Application' 카테고리의 다른 글

MappingJacksonJsonView Map 변환  (0) 2012.10.30
Reflection 정리  (0) 2012.10.10
DB Connection 정리  (0) 2012.10.10
Apache Commons Logging  (0) 2012.10.10
Log4j 정리  (0) 2012.10.10
댓글
«   2024/05   »
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 31
최근에 올라온 글
글 보관함
Total
Today
Yesterday