반응형
XML은 w3c에서 개발된 마크업 언어로, 여러 종류의 데이터를 기술하는 데 사용할 수 있다.
예시 - 주식 정보를 나타내는 XML
<?xml version="1.0" encoding="UTF-8"?>
<stocks>
<stock>
<symbol>Citibank</symbol>
<price>100</price>
<quantity>1000</quantity>
</stock>
<stock>
<symbol>Axis bank</symbol>
<price>90</price>
<quantity>2000</quantity>
</stock>
</stocks>
이러한 XML 문서를 파싱하는 방법에는 대표적으로 DOM과 SAX가 존재한다. 이 글에서는 두 방식의 차이와 각 방식의 자바 코드 예시를 제공한다.
DOM
· XML을 트리 형태의 데이터로 만든 후, 해당 데이터를 가공하는 방식으로 파싱을 진행한다.
· XML 문서를 메모리에 모두 로드한 후 파싱한다.
- 단점: 메모리를 많이 사용한다.
- 장점: 구현과 구조변경이 쉽다.
코드 예시
파싱할 xml 파일은 위의 stock 정보를 갖는 xml로 한다.
import java.io.File;
import java.nio.file.Paths;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DOMParserExam {
public static void main(String[] args){
try {
// 파일 경로
File stocks = new File(Paths.get("").toAbsolutePath()+"/src/main/java/숙제20211207/Stocks.xml");
// 파일 읽기
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(stocks);
doc.getDocumentElement().normalize();
System.out.println("파일출력");
// 읽어들인 파일 불러오기
NodeList nodes = doc.getElementsByTagName("stock");
for (int k = 0; k < nodes.getLength(); k++) {
Node node = nodes.item(k);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
System.out.println("Stock Symbol: " + getValue("symbol", element));
System.out.println("Stock Price: " + getValue("price", element));
System.out.println("Stock Quantity: " + getValue("quantity", element));
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static String getValue(String tag, Element element) {
NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
Node node = (Node) nodes.item(0);
return node.getNodeValue();
}
}
SAX
· XML 문서를 라인단위로 체크하면서 파싱하는 방법이다.
· 이러한 이유로 XML 데이터를 모두 메모리에 올려 놓지 않고 파싱을 진행한다.
- 장점: 메모리를 사용하는 공간이 DOM에 비하여 작다.
- 단점: 구현과 구조 변경이 어렵다.
· 핸들러를 따로 구현하여 발생한 이벤트를 변수에 저장 활용하는 방식을 사용한다.
코드 예시
파싱할 xml 파일은 위의 stock 정보를 갖는 xml로 한다.
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ToString
@Getter
@Setter
public class Stock {
private String symbol;
private int price;
private int quantity;
}
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
public class StocksSaxHandler extends DefaultHandler {
//파싱한 Stock객체를 넣을 리스트
private List<Stock> stockList;
//파싱한 Stock 객체
private Stock stock;
//character 메소드에서 저장할 문자열 변수
private String str;
public StocksSaxHandler() {
stockList = new ArrayList<>();
}
public void startElement(String uri, String localName, String name, Attributes att) {
//시작 태그를 만났을 때 발생하는 이벤트
if(name.equals("stock")) {
stock = new Stock();
stockList.add(stock);
}
}
public void endElement(String uri, String localName, String name) {
//끝 태그를 만났을 때,
if(name.equals("symbol")) {
stock.setSymbol(str);
}else if(name.equals("price")) {
stock.setPrice(Integer.parseInt(str));
}else if(name.equals("quantity")) {
stock.setQuantity(Integer.parseInt(str));
}
}
public void characters(char[] ch, int start, int length) {
//태그와 태그 사이의 내용을 처리
str = new String(ch,start,length);
}
public List<Stock> getStockList(){
return stockList;
}
public void setStockList(List<Stock> stockList) {
this.stockList=stockList;
}
}
import java.io.File;
import java.nio.file.Paths;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SAXParserExam {
public static void main(String[] args) {
File stocks = new File(Paths.get("").toAbsolutePath()+"/src/main/java/숙제20211207/Stocks.xml");
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
StocksSaxHandler handler = new StocksSaxHandler();
parser.parse(stocks, handler);
List<Stock> list = handler.getStockList();
for(Stock stock:list) {
System.out.println(stock);
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
출처
반응형
'자바' 카테고리의 다른 글
자바의 변성 - 공변/무공변/반공변, 사용지점 변성과 선언 지점 변성 (0) | 2022.02.08 |
---|---|
[JAVA] 자바에서 파일, 디렉터리 변경 사항을 감지하는 방법 - WatchService (0) | 2021.12.13 |
[Java] 자바8의 새로운 날짜 관련 클래스들 - java.time 패키지 (LocalDate, LocalTime, LocalDateTime, ZonedDateTime) (0) | 2021.12.13 |
[Java] 런타임에 자바 코드를 조작하는 방법: 리플렉션(Reflection) (0) | 2021.12.10 |
[Java] JDK가 제공하는 기본 개발 도구 (javac, java, javadoc, jps, jmap) (0) | 2021.12.06 |
댓글