[Java] XML를 다루는 방법(XMLStreamWriter, XMLStreamReader, XmlFactory 사용법)
안녕하세요. 명월입니다.
이 글은 Java에서 XML를 다루는 방법(XMLStreamWriter, XMLStreamReader, XmlFactory 사용법)에 대한 글입니다.
프로그램를 만들때, 환경 설정 파일을 다루는 경우가 많이 있습니다. 환경 설정 파일의 구조로는 json 구조라던가 xml, ini, csv등등의 많은 파일 구조가 있습니다.
그 중 xml 형식의 파일 구조로 데이터를 취득하는 경우가 있습니다.
xml이란 인터넷을 찾아보면 eXtensible Markup Language의 약자로 확장성이 있는 마크업 언어라고 정의 되어있습니다.
이 확장성 마크업이라는 뜻은 동적으로 정의 가능한 데이터 포멧이라는 뜻입니다.
ini의 경우는 세션과 key가 있는데 key=value의 형식으로 데이터를 취득하는 방법입니다. 그 이상의 데이터를 설정하기가 쉽지 않습니다.
csv의 경우는 콤마나 탭의 구분으로 테이블 형식으로 데이터를 취득하는 방법으로 컬럼의 갯수만큼 레코드의 데이터가 정해지고 1행과 2행의 데이터의 구조는 같아 질 수 밖에 없습니다.
json은 ini와 csv보다는 조금 확장성이 용이하지만 json도 역시는 기본 key=value의 한계가 있습니다.
xml의 경우는 태그의 열고 닫음으로 데이터의 값을 표현할 수 있고 각 테그에 속성(attribute)를 동적으로 설정하므로써 데이터를 정말 자유스럽게 설정할 수 있는 장접이 있습니다.
xml를 취득하는 방법에는 여러가지가 있지만 여기서는 그중 XMLStream를 이용해서 간단하게 xml를 생성, 취득하는 방법을 소개하겠습니다.
import java.io.FileWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
public class Example {
// 실행 함수
public static void main(String[] args) {
// xml factory 취득
XMLOutputFactory factory = XMLOutputFactory.newFactory();
// 파일 stream 취득 (자동 close)
try (FileWriter writer = new FileWriter("d:\\work\\test.xml")) {
// xmlwriter 생성
XMLStreamWriter xmlwriter = factory.createXMLStreamWriter(writer);
// <?xml version="1.0" ?> 작성
xmlwriter.writeStartDocument();
// <document> 작성
xmlwriter.writeStartElement("document");
// <data> 작성
xmlwriter.writeStartElement("data");
// <data name="value"> 작성
xmlwriter.writeAttribute("name", "value");
// <data>Hello world</data> 작성
xmlwriter.writeCharacters("Hello world");
// </data> 작성
xmlwriter.writeEndElement();
// </document> 작성
xmlwriter.writeEndElement();
// xml 작성 종료
xmlwriter.writeEndDocument();
// 갱신 (파일에 쓰기)
xmlwriter.flush();
// xmlwriter 닫기
xmlwriter.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
XMLOutputFactory의 경우는 java의 표준 클래스이기 때문에 따로 오픈 소스 라이브러리를 참조할 필요가 없습니다.
xml은 함수의 호출 순서대로 생성되며 태그의 열고 닫힘과 속성과 값이 설정됩니다.
참조 - http://docs.oracle.com/javase/7/docs/api/javax/xml/stream/XMLStreamWriter.html
이번에는 xml를 읽는 방법에 대한 소스입니다.
import java.io.FileReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
public class Example {
// 실행 함수
public static void main(String[] args) {
// xml factory 취득
XMLInputFactory factory = XMLInputFactory.newInstance();
// 파일 stream 취득 (자동 close)
try (FileReader reader = new FileReader("d:\\work\\test.xml")) {
// xmlreader 생성
XMLStreamReader xmlreader = factory.createXMLStreamReader(reader);
// iterator 패턴으로 태그를 반복적으로 취득
while (xmlreader.hasNext()) {
// text에서의 태그 행 번호와 열 번호
System.out.print("EVENT:[" + xmlreader.getLocation().getLineNumber() + "][" + xmlreader.getLocation().getColumnNumber() + "]");
// 콘솔 출력 시작
System.out.print(" [");
// 태그의 타입 별로 출력 방법을 구분한다.
switch (xmlreader.getEventType()) {
// xml 시작 태그
case XMLStreamReader.START_DOCUMENT: {
// 태그 열기 출력
System.out.print("<?xml");
// 버젼 출력
System.out.print(" version='" + xmlreader.getVersion() + "'");
// 인코딩 타입 출력
System.out.print(" encoding='" + xmlreader.getCharacterEncodingScheme() + "'");
// standalone 타입 출력
if (xmlreader.isStandalone()) {
// 콘솔 출력
System.out.print(" standalone='yes'");
} else {
// 콘솔 출력
System.out.print(" standalone='no'");
}
// 태그 닫기 출력
System.out.print("?>");
}
break;
// 일반 시작 태그
case XMLStreamReader.START_ELEMENT: {
// 일반 시작 태그 출력
System.out.print("<");
// 태그 이름을 가지고 있을 경우
if (xmlreader.hasName()) {
// 접두어 취득
String prefix = xmlreader.getPrefix();
// uri 취득
String uri = xmlreader.getNamespaceURI();
// 태그 이름 취득
String localName = xmlreader.getLocalName();
// uri가 있으면
if (uri != null && !"".equals(uri)) {
// 콘솔 출력
System.out.print("[" + uri + "]");
}
// 접두어가 있으면
if (prefix != null && !"".equals(prefix)) {
// 콘솔 출력
System.out.print(prefix + ":");
}
// 태그 이름이 있으면
if (localName != null) {
// 콘솔 출력
System.out.print(localName);
}
}
// 네임 스페이스 갯수만큼 반복
for (int i = 0; i < xmlreader.getNamespaceCount(); i++) {
// 네임 스페이스 접두어 취득
String prefix = xmlreader.getNamespacePrefix(i);
// uri 취득
String uri = xmlreader.getNamespaceURI(i);
// 콘솔 출력
System.out.print(" ");
// 접두어가 없으면
if (prefix == null) {
// uri만 출력
System.out.print("xmlns='" + uri + "'");
} else {
// 출력
System.out.print("xmlns:" + prefix + "='" + uri + "'");
}
}
// 태그의 속성 갯수만큼 반복
for (int i = 0; i < xmlreader.getAttributeCount(); i++) {
// 접두어 취득
String prefix = xmlreader.getAttributePrefix(i);
// 네임 스페이스 취득
String namespace = xmlreader.getAttributeNamespace(i);
// 속성 이름 취득
String localName = xmlreader.getAttributeLocalName(i);
// 값 취득
String value = xmlreader.getAttributeValue(i);
// 콘솔 출력
System.out.print(" ");
// 네임 스페이스가 있으면
if (namespace != null && !"".equals(namespace)) {
// 콘솔 출력
System.out.print("[" + namespace + "]");
}
// 접두어가 있으면
if (prefix != null && !"".equals(prefix)) {
// 콘솔 출력
System.out.print(prefix + ":");
}
// 속성 이름이 있으면
if (localName != null) {
// 콘솔 출력
System.out.print(localName);
}
// 값 출력
System.out.print("='" + value + "'");
}
// 일반 시작 태그 출력
System.out.print(">");
}
break;
// 일반 닫기 태그
case XMLStreamReader.END_ELEMENT: {
// 일반 닫기 태그 출력
System.out.print("</");
// 태그 이름을 가지고 있을 경우
if (xmlreader.hasName()) {
// 접두어 취득
String prefix = xmlreader.getPrefix();
// uri 취득
String uri = xmlreader.getNamespaceURI();
// 태그 이름 취득
String localName = xmlreader.getLocalName();
// url가 있으면
if (uri != null && !"".equals(uri)) {
// 콘솔 출력
System.out.print("[" + uri + "]");
}
// 접두어가 있으면
if (prefix != null && !"".equals(prefix)) {
// 콘솔 출력
System.out.print(prefix + ":");
}
// 태그 이름이 있으면
if (localName != null) {
// 콘솔 출력
System.out.print(localName);
}
}
// 일반 닫기 태그 출력
System.out.print(">");
}
break;
// 태그 공백일 경우, 문자일 경우
case XMLStreamReader.SPACE:
case XMLStreamReader.CHARACTERS: {
// 문자의 시작 index
int start = xmlreader.getTextStart();
// 문자의 갯수
int length = xmlreader.getTextLength();
// 콘솔 출력
System.out.print(new String(xmlreader.getTextCharacters(), start, length));
}
break;
// 명령 태그
case XMLStreamReader.PROCESSING_INSTRUCTION: {
// 명령 태그 시작 출력
System.out.print("<?");
// 문자가 존재하면
if (xmlreader.hasText()) {
// 콘솔 출력
System.out.print(xmlreader.getText());
}
// 명령 태그 닫기 출력
System.out.print("?>");
}
break;
// CDATA 태그 (문자 데이터)
case XMLStreamReader.CDATA: {
// CDATA 열기 출력
System.out.print("<![CDATA[");
// 문자의 시작 index
int start = xmlreader.getTextStart();
// 문자의 갯수
int length = xmlreader.getTextLength();
// 콘솔 출력
System.out.print(new String(xmlreader.getTextCharacters(), start, length));
// CDATA 닫기 출력
System.out.print("]]>");
}
break;
// 주석 출력
case XMLStreamReader.COMMENT: {
// 주석 열기 출력
System.out.print("<!--");
// 문자가 존재하면
if (xmlreader.hasText()) {
// 콘솔 출력
System.out.print(xmlreader.getText());
}
// 주석 닫기 출력
System.out.print("-->");
}
break;
// 엔티티 참조
case XMLStreamReader.ENTITY_REFERENCE: {
// 콘솔 출력
System.out.print(xmlreader.getLocalName() + "=");
// 문자가 존재하면
if (xmlreader.hasText()) {
// 콘솔 출력
System.out.print("[" + xmlreader.getText() + "]");
}
}
break;
}
// 콘솔 출력 닫기
System.out.println("]");
// iterator 패턴의 다음 데이터
xmlreader.next();
}
// xmlreader 닫기
xmlreader.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
위 소스를 보면 xmlreader는 각 테그의 타입 별로 반복 패턴으로 표현됩니다.
참조 - http://docs.oracle.com/javase/7/docs/api/javax/xml/stream/XMLStreamReader.html
여기까지 Java에서 XML를 다루는 방법(XMLStreamWriter, XMLStreamReader, XmlFactory 사용법)에 대한 글이었습니다.
궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.
'Development note > Java' 카테고리의 다른 글
[Java] 63. Spring boot에서 cron 스케줄러와 Component 어노테이션 (0) | 2022.03.16 |
---|---|
[Java] JWT(Json Web Token)을 발행, 확인하는 방법 (0) | 2022.03.14 |
[Java] Redis 데이터베이스를 접속해서 사용하는 방법(Jedis 라이브러리) (0) | 2022.02.16 |
[Java] WebSocket에서 채팅 이력을 로딩하는 방법 (0) | 2021.06.15 |
[Java] Eclipse에서 Junit을 사용하는 방법 (0) | 2020.06.10 |
[Java] Cassandra(nosql)를 사용하는 방법 (0) | 2020.06.08 |
[Java] Selenium을 사용하는 방법 (2) | 2020.06.04 |
[Java] Websocket을 이용해서 유저(사이트 운영자)가 다른 유저와 채팅하는 방법 (0) | 2020.05.06 |