239 lines
8.0 KiB
Markdown
239 lines
8.0 KiB
Markdown
# **XML StAX Parser 쉽게 배우기**
|
|
|
|
## **1. StAX Parser란?**
|
|
StAX (Streaming API for XML) Parser는 XML 문서를 읽고 쓰는 **스트리밍 방식의 API**이다.
|
|
DOM이 **전체 XML을 메모리에 로드**하고, SAX가 **이벤트 기반으로 읽기만 가능**한 것과 다르게,
|
|
StAX는 **"Pull 방식"** 으로 데이터를 직접 가져올 수 있어 **더 유연하게 읽고 쓸 수 있음**.
|
|
|
|
✔ **장점:**
|
|
- **필요한 데이터만 직접 가져올 수 있음 (Pull 방식)**
|
|
- **SAX보다 코드가 더 직관적**
|
|
- **읽기(Parsing)뿐만 아니라 XML 파일 쓰기(XMLStreamWriter)도 지원**
|
|
|
|
✔ **단점:**
|
|
- **트리 구조 접근 불가 (DOM처럼 노드를 조작할 수 없음)**
|
|
- **SAX보다 약간 무겁지만 여전히 DOM보다는 가벼움**
|
|
|
|
**➡ 적절한 사용 사례:**
|
|
- **대용량 XML 파일에서 특정 데이터만 가져올 때**
|
|
- **XML을 읽을 뿐만 아니라, 새로운 XML을 생성해야 할 때**
|
|
|
|
---
|
|
|
|
## **2. 주요 메서드 정리**
|
|
|
|
### **📌 XMLStreamReader (읽기)**
|
|
| 메서드 | 설명 |
|
|
|-----|---|
|
|
| `XMLInputFactory.newInstance()` | `XMLStreamReader` 객체를 생성하는 팩토리 메서드 |
|
|
| `XMLStreamReader.next()` | 다음 XML 요소로 이동 |
|
|
| `XMLStreamReader.hasNext()` | 다음 요소가 있는지 확인 |
|
|
| `XMLStreamReader.getEventType()` | 현재 XML 이벤트 유형 반환 |
|
|
| `XMLStreamReader.getLocalName()` | 현재 태그의 이름 반환 |
|
|
| `XMLStreamReader.getAttributeValue(int index)` | 특정 인덱스의 속성 값 반환 |
|
|
| `XMLStreamReader.getText()` | 현재 태그의 텍스트 값 반환 |
|
|
| `XMLStreamReader.close()` | XML 리더 닫기 |
|
|
|
|
---
|
|
|
|
### **📌 XMLStreamWriter (쓰기)**
|
|
| 메서드 | 설명 |
|
|
|-----|---|
|
|
| `XMLOutputFactory.newInstance()` | `XMLStreamWriter` 객체를 생성하는 팩토리 메서드 |
|
|
| `XMLStreamWriter.writeStartDocument()` | XML 문서 시작 선언 |
|
|
| `XMLStreamWriter.writeStartElement(String name)` | XML 태그 시작 |
|
|
| `XMLStreamWriter.writeAttribute(String name, String value)` | 태그에 속성 추가 |
|
|
| `XMLStreamWriter.writeCharacters(String text)` | 태그 안에 텍스트 추가 |
|
|
| `XMLStreamWriter.writeEndElement()` | 현재 태그 종료 |
|
|
| `XMLStreamWriter.writeEndDocument()` | XML 문서 종료 |
|
|
| `XMLStreamWriter.close()` | XML 작성기 닫기 |
|
|
|
|
---
|
|
|
|
## **3. XML 문서 예제**
|
|
|
|
아래 XML 파일을 **StAX Parser를 사용하여 읽고 출력**해 보자.
|
|
|
|
```xml
|
|
<books>
|
|
<book id="1">
|
|
<title>자바 프로그래밍</title>
|
|
<author>홍길동</author>
|
|
<price>30000</price>
|
|
</book>
|
|
<book id="2">
|
|
<title>데이터베이스 개론</title>
|
|
<author>이몽룡</author>
|
|
<price>25000</price>
|
|
</book>
|
|
</books>
|
|
```
|
|
|
|
---
|
|
|
|
## **4. StAX Parser로 XML 읽기 (Pull 방식)**
|
|
|
|
### **✔ XMLStreamReader를 사용하여 XML 데이터 출력하기**
|
|
아래 코드는 `StAXParser`를 사용하여 XML 파일을 읽고, 책 정보를 출력하는 예제이다.
|
|
|
|
```java
|
|
import javax.xml.stream.*;
|
|
import java.io.FileInputStream;
|
|
|
|
public class StAXParserExample {
|
|
public static void main(String[] args) {
|
|
try {
|
|
// 1. XMLStreamReader 생성
|
|
XMLInputFactory factory = XMLInputFactory.newInstance();
|
|
XMLStreamReader reader = factory.createXMLStreamReader(new FileInputStream("books.xml"));
|
|
|
|
// 2. XML 데이터 읽기
|
|
String currentElement = "";
|
|
while (reader.hasNext()) {
|
|
int event = reader.next();
|
|
|
|
// 요소의 시작
|
|
if (event == XMLStreamReader.START_ELEMENT) {
|
|
currentElement = reader.getLocalName();
|
|
|
|
// <book> 태그의 id 속성 읽기
|
|
if (currentElement.equals("book")) {
|
|
System.out.println("\n책 ID: " + reader.getAttributeValue(0));
|
|
}
|
|
}
|
|
// 요소 안의 텍스트 읽기
|
|
else if (event == XMLStreamReader.CHARACTERS) {
|
|
String text = reader.getText().trim();
|
|
if (!text.isEmpty()) {
|
|
switch (currentElement) {
|
|
case "title":
|
|
System.out.println("제목: " + text);
|
|
break;
|
|
case "author":
|
|
System.out.println("저자: " + text);
|
|
break;
|
|
case "price":
|
|
System.out.println("가격: " + text);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
reader.close();
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**🔹 실행 결과**
|
|
```
|
|
책 ID: 1
|
|
제목: 자바 프로그래밍
|
|
저자: 홍길동
|
|
가격: 30000
|
|
|
|
책 ID: 2
|
|
제목: 데이터베이스 개론
|
|
저자: 이몽룡
|
|
가격: 25000
|
|
```
|
|
|
|
✅ `reader.next()`를 이용해 **한 단계씩 이동하며 직접 데이터를 가져옴**
|
|
✅ `reader.getLocalName()`을 이용해 현재 태그 이름 확인
|
|
✅ `reader.getText()`로 태그 안의 텍스트 값 가져오기
|
|
|
|
---
|
|
|
|
## **5. StAX Parser로 XML 쓰기 (쓰기 예제)**
|
|
|
|
XML 데이터를 **파일로 저장하는 경우** `XMLStreamWriter`를 사용한다.
|
|
|
|
### **✔ XMLStreamWriter를 사용하여 XML 파일 생성**
|
|
```java
|
|
import javax.xml.stream.*;
|
|
import java.io.FileOutputStream;
|
|
|
|
public class StAXWriterExample {
|
|
public static void main(String[] args) {
|
|
try {
|
|
// 1. XMLStreamWriter 생성
|
|
XMLOutputFactory factory = XMLOutputFactory.newInstance();
|
|
XMLStreamWriter writer = factory.createXMLStreamWriter(new FileOutputStream("new_books.xml"), "UTF-8");
|
|
|
|
// 2. XML 문서 작성
|
|
writer.writeStartDocument("UTF-8", "1.0");
|
|
writer.writeStartElement("books");
|
|
|
|
// 첫 번째 책
|
|
writer.writeStartElement("book");
|
|
writer.writeAttribute("id", "1");
|
|
|
|
writer.writeStartElement("title");
|
|
writer.writeCharacters("자바 프로그래밍");
|
|
writer.writeEndElement();
|
|
|
|
writer.writeStartElement("author");
|
|
writer.writeCharacters("홍길동");
|
|
writer.writeEndElement();
|
|
|
|
writer.writeStartElement("price");
|
|
writer.writeCharacters("30000");
|
|
writer.writeEndElement();
|
|
|
|
writer.writeEndElement(); // book 종료
|
|
|
|
// XML 종료
|
|
writer.writeEndElement(); // books 종료
|
|
writer.writeEndDocument();
|
|
writer.close();
|
|
|
|
System.out.println("XML 파일 생성 완료!");
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**🔹 생성된 XML 파일 (new_books.xml)**
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<books>
|
|
<book id="1">
|
|
<title>자바 프로그래밍</title>
|
|
<author>홍길동</author>
|
|
<price>30000</price>
|
|
</book>
|
|
</books>
|
|
```
|
|
|
|
✅ `writeStartElement()`를 이용해 태그 생성
|
|
✅ `writeCharacters()`로 태그 안의 텍스트 추가
|
|
✅ `writeAttribute()`를 이용해 속성 추가
|
|
|
|
---
|
|
|
|
## **6. StAX vs SAX vs DOM 비교**
|
|
|
|
| 특징 | StAX Parser | SAX Parser | DOM Parser |
|
|
|---|-----|-----|-----|
|
|
| **메모리 사용량** | 적음 | 적음 | 많음 |
|
|
| **속도** | 빠름 | 빠름 | 느림 |
|
|
| **데이터 접근 방식** | Pull 방식 | Push 방식 | 트리 기반 |
|
|
| **읽기** | ✅ | ✅ | ✅ |
|
|
| **쓰기** | ✅ | ❌ | ✅ |
|
|
| **수정** | ❌ | ❌ | ✅ |
|
|
|
|
---
|
|
|
|
## **7. 정리**
|
|
✔ **StAX Parser는 Pull 방식으로 XML을 읽고 쓸 수 있는 API**
|
|
✔ **필요한 데이터만 직접 가져올 수 있어 SAX보다 유연함**
|
|
✔ **쓰기 기능(XMLStreamWriter)을 지원하므로 XML 생성에도 적합**
|
|
✔ **대용량 XML을 다룰 때 효율적인 선택**
|
|
|
|
✅ **읽기 & 쓰기가 필요한 경우 StAX Parser를 사용하자!** |