XML 파일을 읽거나 써야 할 일이 종종 생기는데, 그 때마다 해당 내용을 검색하거나 베껴 쓰는게 번거롭더군요. 정리해서 하나의 클래스로 만들면 좋겠다는 생각이 들었습니다.
/**
*
*/
package com.cafe24.twilightsh.xml;
import java.io.File;
import java.io.PrintStream;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
* XML 도우미.
* "https://docs.google.com/document/d/1LWta4cJnwHjsHi0Ypry5OJPup9RTYixMJWXQC9voShk/"
* ,
* "https://docs.google.com/document/d/1c61ht_OoHWaLuLB3JAMhJ8qHaW-80Xfmdxqx6s5gUEQ/"
* 참조.
*
* @author chan1
*
*/
public class XmlHelper {
/**
* DocumentBuilder. XML 문자열이나 파일을 parse, Document로 변환한다.
*/
private DocumentBuilder docBuilder;
/**
* 생성자.
*/
public XmlHelper() {
try {
docBuilder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException("DocumentBuilder 준비 실패.", e);
}
}
/**
* 웹 XML --> Document.
* 문자열을 Document로 변환하는 기능에 대해서는
* "xpath 를 이용, java 에서 xml 문서 쉽게 파싱하기"(http://stove99.tistory.com/106)
* 참조.
*
* @param xml
* 웹 XML (예: "http://www.example.com/test.xml")
* @return Document
*/
public final Document read(final String xml) {
try {
Document document = docBuilder.parse(xml);
return document;
} catch (Exception e) {
throw new RuntimeException("String-->Document 변환 실패.", e);
}
}
/**
* String --> Document.
* 단, {@link StringReader}는 반드시 자원 해제를 해줘야 하는 까다로운 점이 있으므로, 대신
* {@link #toDocument(String)}를 사용하는 것을 추천.
* 문자열을 Document로 변환하는 기능에 대해서는
* "xpath 를 이용, java 에서 xml 문서 쉽게 파싱하기"(http://stove99.tistory.com/106)
* 참조.
*
* @param xml
* XML 문자열
* @return Document
*/
public final Document read(final StringReader xml) {
// StringReader reader = null;
try {
// reader = new StringReader(xml.toString());
// InputSource is = new InputSource(reader);
InputSource is = new InputSource(xml);
Document document = docBuilder.parse(is);
return document;
} catch (Exception e) {
throw new RuntimeException("String-->Document 변환 실패.", e);
}
}
/**
* File --> Document.
* 문자열을 Document로 변환하는 기능에 대해서는
* "xpath 를 이용, java 에서 xml 문서 쉽게 파싱하기"(http://stove99.tistory.com/106)
* 참조.
*
* @param xml
* XML 문자열
* @return Document
*/
public final Document read(final File xml) {
Document document = null;
try {
// InputSource is = new InputSource(new FileReader(xml));
// document = docBuilder.parse(is);
document = docBuilder.parse(xml);
} catch (Exception e) {
throw new RuntimeException("File-->Document 변환 실패.", e);
}
return document;
}
/**
* Document를 {@link Result}에 출력한다.
* StreamResult에 들어가는 출력 객체가 무엇이 들어가는냐에 따라서 String/File/Console 등으로 출력처를 바꿀
* 수 있다. 즉, StringWriter면 String으로, FileOutputStream이면 파일로, System.out이면 콘솔에
* 출력 가능하다.
*
* @param document
* XML
* @param output
* String/File/Console
*/
public final void write(final Document document, final Result output) {
try {
// XSL 변환기.
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// OMIT_XML_DECLARATION을 "yes"로 선언하면, 가 없어짐
// transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
// "yes");
// 문자열로 변환.
Source xmlSource = new DOMSource(document);
transformer.transform(xmlSource, output);
} catch (Exception e) {
throw new RuntimeException("Document 쓰기 실패.", e);
}
}
/**
* Document --> String.
* 단, {@link StringWriter}는 반드시 자원 해제를 해줘야 하는 까다로운 점이 있으므로, 대신
* {@link #toString(Document)}를 사용하는 것을 추천.
* Document를 문자열로 변환하는 기능에 대해서는 (http://trypsr.tistory.com/45)
* 참조.
*
* @param document
* Document
* @param writer
* StringWriter
*/
public final void write(final Document document, final StringWriter writer) {
this.write(document, new StreamResult(writer));
}
/**
* Document --> File. Document를 주어진 파일에 쓴다.
*
* @param document
* XML
* @param writer
* File
*/
public final void write(final Document document, final File writer) {
this.write(document, new StreamResult(writer));
}
/**
* Document --> Console. Document를 콘솔에 쓴다.
* System.out을 입력하면 콘솔에 출력되는 것을 볼 수 있다.
*
* @param document
* XML
* @param writer
* System.out
*/
public final void write(final Document document, final PrintStream writer) {
this.write(document, new StreamResult(writer));
}
/**
* Document --> String.
*
* @param document
* XML
* @return XML 문자열
*/
public final String toString(final Document document) {
StringWriter writer = null;
try {
writer = new StringWriter();
this.write(document, writer);
return writer.toString();
} catch (Exception e) {
throw new RuntimeException("Document --> String 변환 실패.", e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (Exception e) {
// close 실패해도 딱히 할 게 없음.
}
}
}
}
/**
* String-->Document.
*
* @param xml
* XML 문자열
* @return Document
*/
public final Document toDocument(final String xml) {
StringReader reader = null;
try {
reader = new StringReader(xml.toString());
return this.read(reader);
} catch (Exception e) {
throw new RuntimeException("String-->Document 변환 실패.", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e) {
// close 실패해도 딱히 할 게 없음.
}
}
}
}
}
도우미 클래스의 코드입니다.
실제적으로 가장 많이 쓰게 될 기능은 String ↔ Document이라고 생각되는데 둘 다 자원해제 등 여러모로 번거로운 부분이 있어서, 해당 기능만 toString/toDocyment 메서드로 따로 뽑아서 더 단순하게 쓸 수 있게 했습니다..
XmlHelper.java
XmlHelperTest.java
XML읽기/쓰기 도우미 클래스와 그 테스트 클래스 파일을 첨부합니다.