Parsing

codakcodak·2023년 7월 27일
0

Java

목록 보기
17/17
post-thumbnail

XML

  • 태그를 사용하며 확장 가능한 마크업 언어

  • 정확한 문법을 지켜야 동작

  • 구조적이며 큰 용량이 필요

SAXParser

  • 문서를 읽으면서 태그의 시작,종료 등 이벤트 기반으로 처리하는 방식
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.ssafy.k_xml_ui.parse.dto.BoxOffice;

public class BoxOfficeSaxParser extends DefaultHandler implements BoxOfficeParser {
	//DefaultHandler 반복적인 기능을 수행-->stateless sigleton 구현
    private static BoxOfficeSaxParser parser=new BoxOfficeSaxParser();
    private BoxOfficeSaxParser(){
    }
    public static BoxOfficeSaxParser getParser() {
    	return parser;
    }
    
    
    // 파싱된 내용을 저장할 List
    private List<BoxOffice> list = new ArrayList<>();
    // 현재 파싱하고 있는 대상 객체
    private BoxOffice current;
    // 방금 읽은 텍스트 내용
    private String content;

    @Override
    public List<BoxOffice> getBoxOffice(InputStream resource) {
        // TODO: SAXParser를 구성하고 boxoffice.xml을 파싱하시오.	
    	try {
    		SAXParserFactory factory=SAXParserFactory.newInstance();//SAXParser 객체를 생성하기 위한 객체
			SAXParser parser=factory.newSAXParser();//Parser객체를 생성하기 위한 객체
			parser.parse(resource, this);//한번에 읽으면서 수행하기 때문에 반환형이 없다.(반환형이 없기에 현재 객체에 데이터를 저장하려면 현재 객체를 가리키는 this를 줘야한다.)
			System.out.println("문서처리완료");
		} catch (ParserConfigurationException pe) {
			pe.printStackTrace();
		}catch(SAXException se) {
			se.printStackTrace();
    	}catch (IOException e) {
			e.printStackTrace();
		}
  
    	
        // END
        return list;
    }
    @Override//파싱 시작시 수행할 메서드
    public void startDocument() throws SAXException{
    	System.out.println("문서 읽기 시작");
    }
    @Override//파싱 끝에 수행할 메서드
    public void endDocument() throws SAXException{
    	System.out.println("문서 읽기 종료");
    }

    @Override//요소 시작점에 수행할 메서드
    public void startElement(String uri, String localName,
            String qName, Attributes attributes){
    	if(qName.equals("dailyBoxOffice")) {
    		current=new BoxOffice();
    	}
    }
//    
    @Override
    public void characters(char[] ch,int start,int length) throws SAXException{
    	this.content=new String(ch,start,length);
    }
    
    @Override//요소 끝점에 수행할 메서드
    public void endElement(String uri,String localName,String qName) throws SAXException{
    	if(qName.equals("dailyBoxOffice")) {
    		list.add(current);
    		current=null;
    	}else if(qName.equals("rank")) {
    		current.setRank(Integer.parseInt(content));
    	}else if(qName.equals("movieNm")) {
    		current.setMovieNm(this.content);
    	}else if(qName.equals("openDt")) {
    		current.setOpenDt(current.toDate(this.content));
    	}else if(qName.equals("audiAcc")) {
    		current.setAudiAcc(Integer.parseInt(content));
    	}
    	System.out.println("문서 읽기 종료");
    }
}

DOMParser

  • 문서를 다 읽고 난 후 문서 구조 전체를 자료구조에 저장하여 탐색하는 방식
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.ssafy.k_xml_ui.parse.dto.BoxOffice;

public class BoxOfficeDomParser implements BoxOfficeParser {

    private static BoxOfficeDomParser parser = new BoxOfficeDomParser();

    public static BoxOfficeDomParser getParser() {
        return parser;
    }

    private BoxOfficeDomParser() {
        System.out.println("DOM parser");
    }

    private List<BoxOffice> list = new ArrayList<>();

    @Override
    public List<BoxOffice> getBoxOffice(InputStream resource) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 문서 로딩 완료 --> 원하는 요소들 골라내기
            Document doc = builder.parse(resource);
            // 최 상위 element
            Element root = doc.getDocumentElement();
            parse(root);
        } catch (IOException | ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }
        return list;
    }

    private void parse(Element root) {
        NodeList list=root.getElementsByTagName("dailyBoxOffice");
        for(int i=0;i<list.getLength();i++) {
        	Node node=list.item(i);
        	this.list.add(getBoxOffice(node));
        }
    }

    private static BoxOffice getBoxOffice(Node node) {
        BoxOffice boxOffice = new BoxOffice();
        NodeList list=node.getChildNodes();
        for(int i=0;i<list.getLength();i++) {
        	Node child=list.item(i);
        	String name=child.getNodeName();
        	if(name.equals("rank")) {
        		boxOffice.setRank(Integer.parseInt(child.getTextContent()));
        	}else if(name.equals("movieNm")) {
        		boxOffice.setMovieNm(child.getTextContent());
        	}else if(name.equals("openDt")) {
        		boxOffice.setOpenDt(boxOffice.toDate(child.getTextContent()));
        	}else if(name.equals("audiAcc")) {
        		boxOffice.setAudiAcc(Integer.parseInt(child.getTextContent()));
        	}
        }
        return boxOffice;
    }
}

JSON

Javascript Object Notation(자바스크립트 객체 표현법)으로 간결한 문법,단순한 텍스트,적은 용량으로 대부분의 언어,플랫폼에서 사용가능한 데이터 교환 형식

json의 mapper표현법

{	
  	//Map<String,Map<String,Object>> result=mapper.readValue(resource,Map.class);
  	"boxOfficeResult":{
      "boxofficeType":"일별 박스 오피스",
      "showRange":"20120101~20120101",
      "dailyBoxOfficeList":[//(List)result.get("boxOfficeResult").get("dailyBoxOfficeList");
        {
          "rank":1,
          "movieNm":"미션임파서블",
          "openDt":"2011-12-15",
          "audiAcc":"12345"
        },
        ...
        ...
      ]
    }
}

코드

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ssafy.k_xml_ui.parse.dto.BoxOffice;

public class BoxOfficeJsonParser implements BoxOfficeParser {

    private static BoxOfficeJsonParser parser = new BoxOfficeJsonParser();

    public static BoxOfficeJsonParser getParser() {
        return parser;
    }

    private BoxOfficeJsonParser() {
        System.out.println("json");
    }

    private List<BoxOffice> list = new ArrayList<>();

    @Override
    public List<BoxOffice> getBoxOffice(InputStream resource) {
        ObjectMapper mapper = new ObjectMapper();//jackson라이브러리로서 클래스의 현식에 맞게 json의 필드들읍 대입하여 객체화시켜준다.

        // 날짜 변경과 관련된 룰 지정
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));//날짜형식을 새로 주입함
        try {
			Map<String,Map<String,Object>> result=mapper.readValue(resource,Map.class);
			List<Map<String,Object>> list=(List)result.get("boxOfficeResult").get("dailyBoxOfficeList");
			for(Map<String,Object> info:list) {
				BoxOffice boxOffice=mapper.convertValue(info, BoxOffice.class);
				this.list.add(boxOffice);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
       
        return list;
    }
}
profile
숲을 보는 코더

0개의 댓글