JAVA 자료구조 java XML Parser 정리

2019.10.05 12:12

졸리운_곰 조회 수:175


 

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) {

            

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

             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>

 

 

 [출처] https://hongkyu.tistory.com/79

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
310 GEF Programmer Guide 번역 졸리운_곰 2019.11.25 227
309 Learn Eclipse GMF in 15 minutes file 졸리운_곰 2019.11.20 224
308 RCP 에디터 정리 졸리운_곰 2019.11.20 333
307 다른 그림과 관련하여 GEF 편집기 레이아웃에서 그림의 위치 제한 조건을 동적으로 계산 Dynamically calculating the position constraints for a figure in a GEF editor layout in relation to another figure file 졸리운_곰 2019.11.20 277
306 추상(abstract) 클래스가 필요한 기본적인 이유 졸리운_곰 2019.10.30 247
305 Java Byte Array to InputStream 졸리운_곰 2019.10.24 176
304 [JAXB] JAXB Annotation 설명~ Part. 2 졸리운_곰 2019.10.24 305
303 [JAXB] JAXB Annotation 설명~ Part. 1 졸리운_곰 2019.10.24 136
302 JAXB (3) - marshal, unmarshal에 대해 알아보자. file 졸리운_곰 2019.10.24 142
301 JAXB (2) - XML Schema를 Java Interfaces & Classes로 Binding Compile 하기 file 졸리운_곰 2019.10.24 144
300 JAXB (1) - JAXB 란? file 졸리운_곰 2019.10.24 188
299 XStream으로 자바 객체를 XML로 직렬화하기 file 졸리운_곰 2019.10.15 249
298 [번역] XStream 배우기 : 2분만에 배우는 XStream 졸리운_곰 2019.10.15 232
297 RCP 등에서 .mf 파일로 다른 프로젝트 익스포트 포함시 라이브러리(메소드)를 찾지 못할 때, Eclipse RCP - cant resolve importing libraries in final build file 졸리운_곰 2019.10.15 410
» java XML Parser 정리 졸리운_곰 2019.10.05 175
295 ESE2006-EclipseModelingSymposium15_GMF.pdf file 졸리운_곰 2019.09.21 302
294 GMF_Creation_Review.pdf file 졸리운_곰 2019.09.21 366
293 Eclipse EMF and GMF Tutorial file 졸리운_곰 2019.09.21 222
292 GMF Tutorial/ko file 졸리운_곰 2019.09.20 347
291 Model Driven Architecture approach to domain of graphical editors file 졸리운_곰 2019.09.20 268
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED