DOMツリー構築を可変長引数で簡単に
public class DOM { private static ThreadLocal<Document> threadLocal = new ThreadLocal<Document>(); public DOM() throws ParserConfigurationException { threadLocal.set(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); } public Document create(Node... nodes) { Document document = threadLocal.get(); for (Node node : nodes) { document.appendChild(node); } threadLocal.remove(); //呼び元のfinallyでremoveしたほうが例外時も安心 return document; } public static Element e(String elemName, Node... nodes) { Element element = threadLocal.get().createElement(elemName); for (Node node : nodes) { if (node instanceof Attr) { element.setAttributeNode((Attr) node); } else { element.appendChild(node); } } return element; } public static Attr a(String attrName, String attrVal) { Attr attr = threadLocal.get().createAttribute(attrName); attr.setValue(attrVal); return attr; } public static Text t(String text) { return threadLocal.get().createTextNode(text); } public static Comment c(String comment) { return threadLocal.get().createComment(comment); } }
staticメソッドをstatic importしておいて、こんな感じで使う
//構築 Document document = new DOM().create( c("コメント"), e("要素", a("属性名", "属性値"), e("子要素", t("テキスト") ) ) ); //表示 Transformer tran = TransformerFactory.newInstance().newTransformer(); tran.setOutputProperty("indent", "yes"); tran.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); tran.transform(new DOMSource(document), new StreamResult(new OutputStreamWriter(System.out)));
表示のコードは見なかったことにして出力結果
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!--コメント--> <要素 属性名="属性値"> <子要素>テキスト</子要素> </要素>
中でループが使えないし、Builderパターンのほうが無難かな?
このくらいならXML埋め込みでも十分だったり
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new InputSource(new StringReader( "<!--コメント-->" + "<要素 属性名='属性値'>" + "<子要素>テキスト</子要素>" + "</要素>" )));