在Java中创建XML文件的最佳方法是什么?

时间:2014-02-25 18:49:41

标签: java xml xmlwriter

我们目前正在使用dom4j来创建XML文件。但是,我猜现在有更好的东西了。如果我们是Java 1.6或更高版本,那么在写出XML文件时使用的最好(运行时最快,使用简单)类。

我不需要构建DOM然后编写整个DOM。我只需要在将它们传递给类时写出元素/属性的东西。

谢谢 - 戴夫

4 个答案:

答案 0 :(得分:4)

我的2美分转到java-xmlbuilder。仅限于建筑。它比JAXP复杂得多。

答案 1 :(得分:4)

我猜你知道StAX和SAX框架 如果您没有考虑过它们,请提及它们。

http://docs.oracle.com/javase/tutorial/jaxp/stax/example.html#bnbgx

http://docs.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT5.html

答案 2 :(得分:4)

如果您只想编写一个XML文档,可以精确控制元素,属性和其他文档组件的创建,您可以使用StAX API中的XMLStreamWriter

答案 3 :(得分:0)

  

希望以下代码对您有帮助

package test.util.doc;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Map;
import java.util.function.Consumer;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
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.Node;
import org.w3c.dom.Text;


/** XML/HTML document writer class<br/>
 * Internally uses w3c DOM <br/>
 * @see Document
 * @author Dharmendrasinh Chudasama
 */
public class XMLWriter {

    /**
     * @param rootElementTagName
     * @param elementFillerConsume
     * @return instance of xml-writer
     * @author Dharmendrasinh Chudasama
     * @throws ParserConfigurationException
     */
    public static XMLWriter create(String rootElementTagName, Consumer<ElementWrapper> elementFillerConsume) throws ParserConfigurationException {
        return new XMLWriter(rootElementTagName, elementFillerConsume);
    }

    private Document doc;
    public XMLWriter(String rootElementTagName, Consumer<ElementWrapper> elementFillerConsume) throws ParserConfigurationException {
        doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
//      doc.setXmlStandalone(true);

        ElementWrapper wrapper = ElementWrapper.createChildWrapper(doc, doc, rootElementTagName);

        //fill
        elementFillerConsume.accept(wrapper);
    }

    public String toXMLString() throws TransformerException {
/*      StringBuilderWriter writer = new StringBuilderWriter();
        writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(System.lineSeparator());
        write(writer);
        return writer.toString().replace("/>", " />");*/
        //OR
/*      StringBuilderWriter writer = new StringBuilderWriter();
        write(writer);
        return writer.toString();*/
        //OR
        ByteArrayOutputStream out = new ByteArrayOutputStream(700);
        write(out);
        return out.toString();
    }

    public void write(File out) throws TransformerException {
        write(new StreamResult(out));
    }

    public void write(OutputStream out) throws TransformerException {
        write(new StreamResult(out));
    }

    public void write(Writer out) throws TransformerException {
        write(new StreamResult(out));
    }

    private void write(Result result) throws TransformerException {
        //export
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.METHOD,"xml");
        transformer.setOutputProperty(OutputKeys.VERSION, "1.0");
        transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");//in multi lines, def="no"
//      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");//remove<?xml ..?> tag, def="no"
//      transformer.setOutputProperty(OutputKeys.STANDALONE,"no");
//      transformer.setOutputProperty(OutputKeys.MEDIA_TYPE,"text/xml");
//      transformer.setOutputProperty("xalan:indent-amount", "0"); //def="0"
//      transformer.setOutputProperty("xalan:content-handler", "org.apache.xml.serializer.ToXMLStream");
//      transformer.setOutputProperty("xalan:entities", "org/apache/xml/serializer/XMLEntities");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");//prefix spaces before tags, def="0"

        transformer.transform(new DOMSource(doc), result);
    }


    /**
     * @author Dharmendrasinh Chudasama
     */
    public static class ElementWrapper {
        private Element element;

        private ElementWrapper(Element element) {
            this.element = element;
        }

        public Element getElement() {
            return element;
        }

        public Document getDoc() {
            return getElement().getOwnerDocument();
        }

        private static Element createChildElement(final Document doc, final Node parent, final String childTagName){
            Element child = doc.createElement(childTagName);
            parent.appendChild(child);
            return child;
        }

        private static ElementWrapper createChildWrapper(final Document doc, final Node parent, final String childTagName){
            Element child = createChildElement(doc, parent, childTagName);
            return new ElementWrapper(child);
        }

        /**create and append child tag to current element
         * @return created child tag
         */
        public Element createChildElement(String tagName){
            return createChildElement(getDoc(), getElement(), tagName);
        }

        public ElementWrapper createChildWrapper(final String childTagName){
            return createChildWrapper(getDoc(), getElement(), childTagName);
        }

        public void childText(String textContent){
            if(textContent != null && !textContent.isEmpty()){
                Text textNode = getDoc().createTextNode(textContent);
                getElement().appendChild(textNode);
            }
        }
/*      public ElementWrapper child(String tagName){
            return new ElementWrapper(getDoc(), createChild(tagName));
        }
*/
        /** append tag with string content */
        public void child(String tagName, String textContent){
            createChildWrapper(tagName).childText(textContent);
        }

        /**
         * @param parent
         * @param tagName
         * @return child element
         */
/*      public Element child(Element parent, String tagName){
            final Document doc = parent.getOwnerDocument();
            Element element = doc.createElement(tagName);
            parent.appendChild(element);
            return element;
        }*/

        public void child(String tagName, Consumer<ElementWrapper> elementConsumer){
            elementConsumer.accept(createChildWrapper(tagName));
        }

        /** @param dataMap {tagName, contentText}
         * @see #child(String, String)
         */
        public void child(Map<String,String> dataMap){
            dataMap.forEach((tagName,contentText)->child(tagName, contentText));
        }

        public void children(String[] childLoopTree, Consumer<ElementWrapper> lastChildConsumer){
            final Document doc = getDoc();
            Element element = getElement();
            for (String tagName : childLoopTree) {
                element = createChildElement(doc, element, tagName);
            }
            lastChildConsumer.accept(new ElementWrapper(element));
        }

        /** Add / replace attribute */
        public void attr(String attrName, String value){
            getElement().setAttribute(attrName, value);
        }

        public void attr(Map<String,String> dataMap){
            dataMap.forEach((attrName,value)->attr(attrName, value));
        }

    }



/*
    //example
    public static void main(String[] args) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        XMLWriter.create("html", html->{
            html.childs(new String[]{"head","title"}, title->title.childText("My TITLE"));
            html.child("body", body->{
                body.attr("bgcolor", "red");

                body.child("div", div->{
                    Map<String, String> userMap = new LinkedHashMap<String, String>();
                    userMap.put("roll-no", "1");
                    userMap.put("name", "Dharm");
                    div.child(userMap);
                });
                body.child("div", div->{
                    Map<String, String> userMap = new LinkedHashMap<String, String>();
                    userMap.put("roll-no", "2");
                    userMap.put("name", "Rajan");
                    div.child(userMap);
                });
            });
        }).write(out);

        System.out.println(out.toString());
    }
*/

}