DOMツリー構築を可変長引数で簡単に

名前空間実体参照、CDATAセクション、、、は考慮外

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(
    "<!--コメント-->" +
    "<要素 属性名='属性値'>" +
        "<子要素>テキスト</子要素>" +
    "</要素>"
)));