<?xml version="1.0" encodong = "UTF-8"?>
" "
또는 ' '
로 묶어서 표현한다. xml 태그는 자유롭게 생성하기 때문에 최초 작성자의 의도대로 작서되는지 확인할 필요
문서의 구조와 적절한 요소,, 속성들의 개수, 순서들이 잘 지켜졌는가?
DTD 또는 Schema를 이용해서 문서의 규칙 작성
DTD, Schema를 잘 따는 문서를 "valid 하다" 라고 함
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
//import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
public class BoxOffice {
private Integer rank; // 등수
private String movieNm; // 영화제목
private Date openDt; // 개봉일
private Integer audiAcc;// 누적 관객 수
public Integer getRank() {
return rank;
}
public void setRank(Integer rank) {
this.rank = rank;
}
public String getMovieNm() {
return movieNm;
}
public void setMovieNm(String movieNm) {
this.movieNm = movieNm;
}
public Date getOpenDt() {
return openDt;
}
public void setOpenDt(Date openDt) {
this.openDt = openDt;
}
public Integer getAudiAcc() {
return audiAcc;
}
public void setAudiAcc(Integer audiAcc) {
this.audiAcc = audiAcc;
}
public Date toDate(String date) {
Date dateObj = null;
// TODO: 문자열 형태의 날짜를 Date로 변환해서 반환하시오.
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
dateObj = format.parse(date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
dateObj = new Date();
}
// END
return dateObj;
}
@Override
public String toString() {
return "[rank=" + rank + ", movieNm=" + movieNm + ", openDt=" + openDt + ", audiAcc="
+ audiAcc + "]";
}
}
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.day9.a_parse.dto.BoxOffice;
public class BoxOfficeSaxParser extends DefaultHandler implements BoxOfficeParser {
// TODO: singleton 형태로 작성해보자.
private static BoxOfficeSaxParser parser = new BoxOfficeSaxParser();
private BoxOfficeSaxParser() {
this.list = new ArrayList<>();
}
public static BoxOfficeSaxParser getParser() {
return parser;
}
// END
// 파싱된 내용을 저장할 List
private List<BoxOffice> list ;
// 현재 파싱하고 있는 대상 객체
private BoxOffice current;
// 방금 읽은 텍스트 내용
private String content;
@Override
public List<BoxOffice> getBoxOffice(InputStream resource) {
list = new ArrayList<>();
// TODO: SAXParser를 구성하고 boxoffice.xml을 파싱하시오.
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser;
try {
parser = factory.newSAXParser();
parser.parse(resource, this);
} catch (SAXException |ParserConfigurationException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// END
return list;
}
// TODO: 필요한 매서드를 재정의 하여 boxOffice.xml을 파싱하시오.
@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 locaName, String qName, Attributes attributes)throws SAXException {
if(qName.equals("dailyBoxOffice")) {
current = new BoxOffice();
}
}
@Override
public void endElement(String uri, String locaName, String qName) {
if(qName.equals("rank")) {
current.setRank(Integer.parseInt(content));
} else if(qName.equals("movieNm")) {
current.setMovieNm(content);
} else if (qName.equals("openDt")) {
current.setOpenDt(current.toDate(content));
} else if(qName.equals("audiAcc")) {
current.setAudiAcc(Integer.parseInt(content));
} else if(qName.equals("dailyBoxOffice")) {
list.add(this.current);
this.current = null;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException{
this.content = String.valueOf(ch, start, length);
}
// END
}
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.day9.a_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;
@Override
public List<BoxOffice> getBoxOffice(InputStream resource) {
list = new ArrayList<>();
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) {
// TODO: root에서 dailyBoxOffice를 추출한 후 BoxOffice를 생성해 list에 저장하시오.
NodeList list = root.getElementsByTagName("dailyBoxOffice");
for(int i= 0;i < list.getLength();i++) {
Node child = list.item(i); //boxoffice 정보
BoxOffice bo = getBoxOffice(child);
this.list.add(bo);
}
// END
}
private static BoxOffice getBoxOffice(Node node) {
BoxOffice boxOffice = new BoxOffice();
// TODO: node 정보를 이용해서 BoxOffice를 구성하고 반환하시오.
NodeList subNodes = node.getChildNodes();
for(int i = 0;i < subNodes.getLength();i++) {
Node sub = subNodes.item(i);
if(sub.getNodeName().equals("rank")) {
boxOffice.setRank(Integer.parseInt(sub.getTextContent()));
} else if(sub.getNodeName().equals("MovieNm")) {
boxOffice.setMovieNm(sub.getTextContent());
} else if (sub.getNodeName().equals("audiAcc")) {
boxOffice.setAudiAcc(Integer.parseInt(sub.getTextContent()));
}
}
// END
return boxOffice;
}
}