import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.google.common.collect.Lists;
public class XmlUtil {
public static class XmlElement {
private String name;
private String value;
private LinkedHashMap<String, XmlAttribute> attributeMap = new LinkedHashMap<>();
private LinkedHashMap<String, List<XmlElement>> elementMap = new LinkedHashMap<>();
private List<XmlElement> elementList = Lists.newArrayList();
public XmlElement(String name) {
this.setName(name);
}
public XmlElement(String name, String value) {
this.setName(name);
this.setValue(value);
}
public XmlAttribute attr(String key, String value) {
XmlAttribute e = new XmlAttribute(key, value);
attributeMap.put(e.getKey(), e);
return e;
}
public XmlElement append(XmlElement xmlElement) {
elementList.add(xmlElement);
String key = xmlElement.getName();
if (elementMap.containsKey(key)) {
elementMap.get(key).add(xmlElement);
} else {
elementMap.put(key, Lists.newArrayList(xmlElement));
}
return xmlElement;
}
public XmlElement append(String name, String value) {
XmlElement e = new XmlElement(name, value);
append(e);
return e;
}
public XmlElement append(String name) {
XmlElement e = new XmlElement(name);
append(e);
return e;
}
public void remove(String name) {
elementMap.remove(name);
for (int i = 0; i < elementList.size(); i++) {
XmlElement element = elementList.get(i);
if ("name".equals(element.getName())) {
elementList.remove(i);
i--;
}
}
}
public void clear() {
elementMap.clear();
elementList.clear();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<XmlElement> getElementList() {
return elementList;
}
public List<XmlAttribute> getAttributeList() {
return new ArrayList<XmlAttribute>(attributeMap.values());
}
public XmlElement getElement(String name) {
List<XmlElement> list = elementMap.get(name);
return list == null || list.size() == 0 ? null : list.get(0);
}
public List<XmlElement> getElementList(String name) {
return elementMap.get(name);
}
}
public static class XmlAttribute {
private String key;
private String value;
public XmlAttribute(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
public static String toString(XmlElement xmlElement) throws ParserConfigurationException, TransformerException {
return toString(toNode(xmlElement));
}
public static String toString(Node n) throws TransformerException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(n);
StreamResult result = new StreamResult(out);
transformer.transform(source, result);
String xml = new String(out.toByteArray(), StandardCharsets.UTF_8);
Document document = n.getOwnerDocument();
if (document != null) {
xml = xml.replaceFirst("<\\?xml[^>]+>", "");
}
return xml;
}
public static String toString(NodeList nodeList) throws TransformerException {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < nodeList.getLength(); i++) {
sb.append(toString(nodeList.item(i)));
}
return sb.toString();
}
public static Element toElement(Document document, XmlElement xmlElement) {
Element element = document.createElement(xmlElement.getName());
for (XmlAttribute attr : xmlElement.getAttributeList()) {
element.setAttribute(attr.getKey(), attr.getValue());
}
element.setTextContent(xmlElement.getValue());
for (XmlElement child : xmlElement.getElementList()) {
element.appendChild(toElement(document, child));
}
return element;
}
public static Node toNode(XmlElement xmlElement) throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
document.appendChild(toElement(document, xmlElement));
Element element = document.createElement(xmlElement.getName());
for (XmlAttribute attr : xmlElement.getAttributeList()) {
element.setAttribute(attr.getKey(), attr.getValue());
}
return document;
}
public static XmlElement parse(String xml) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource();
inputSource.setCharacterStream(new StringReader(xml));
Document document = documentBuilder.parse(inputSource);
Element documentElement = document.getDocumentElement();
return toXmlElement(documentElement);
}
public static XmlElement toXmlElement(Node node) {
XmlElement xmlElement = new XmlElement(node.getNodeName(), node.getNodeValue());
NamedNodeMap attributes = node.getAttributes();
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
Node item = attributes.item(i);
xmlElement.attr(item.getNodeName(), item.getNodeValue());
}
}
NodeList childNodes = node.getChildNodes();
if (childNodes != null) {
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
switch (item.getNodeType()) {
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
xmlElement.setValue(item.getNodeValue());
break;
case Node.ELEMENT_NODE:
xmlElement.append(toXmlElement(item));
break;
}
}
}
return xmlElement;
}
}
별도 라이브러리 없이 간단하게 xml 파싱 및 쓰기가 가능하도록 Util Class를 하나 만들어 보았습니다.
Source Code
사용예제
@Test
public void test() throws Exception {
XmlElement x1 = new XmlElement("x1-tag-name");
XmlElement header = new XmlElement("header-tag-name");
XmlElement body = new XmlElement("body-tag-name");
x1.append(header);
x1.append(body);
header.attr("xmlns", "http://goni9071.tistory.com");
header.append("Simple1", "value1");
header.append("Simple2", "value2");
body.append("body-el-1", "body-el-1-value1");
body.append("body-el-2", "body-el-1-value2");
String xmlString = XmlUtil.toString(x1);
System.out.println(xmlString);
XmlElement parse = XmlUtil.parse(xmlString);
System.out.println(XmlUtil.toString(parse));
}
|
결과
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<x1-tag-name>
<Simple1>value1</Simple1>
<Simple2>value2</Simple2>
</header-tag-name>
<body-tag-name>
<body-el-1>body-el-1-value1</body-el-1>
<body-el-2>body-el-1-value2</body-el-2>
</body-tag-name>
</x1-tag-name>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<x1-tag-name>
<Simple1>value1</Simple1>
<Simple2>value2</Simple2>
</header-tag-name>
<body-tag-name>
<body-el-1>body-el-1-value1</body-el-1>
<body-el-2>body-el-1-value2</body-el-2>
</body-tag-name>
</x1-tag-name>
|
Jaxb 처럼 Class를 미리 정의해서 사용하는 것도 가능합니다.
XmlElement를 상속받아서 처리하시면 됩니다.
이런느낌으로.~