这是我第一次写博客,所以可能写得不太好,请大家见谅!!
之前在网上看到了很多java生成xml字符串和创建xml本地文件的文章,但是感觉不太完整和解释不太详细(可能是我没有找到。。。)!
所以我自己总结了一下知识,希望对大家有用,也方便自己查阅!!
这篇博客的思路:
1. 关键代码步骤
2. 代码设计思路
3. 运行的结果图片
4. 完整代码
5. 代码的使用 | 测试


关键代码块
Dom步骤
1. 创建DocumentBuilderFactory工厂对象: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance():
2. 通过工厂对象,创建DocumentBuilder制作对象:DocumentBuilder builder = factory.newDocumentBuilder();
3. 通过制作对象,创建一个Document对象:Document document = builder.newDocument();
4. 创建节点:Element root = document.createElement(“节点名称”);
5. 添加节点:Element.appendChild(节点);
6. 节点添加属性:Element.setAttribute(“属性名”,”属性值“);
7. 节点间的内容:Element.setTextContent(“标签间内容”);
转换xml步骤
1. 创建TransformerFactory工厂对象:TransformerFactory transFactory = TransformerFactory.newInstance();
2. 通过工厂对象, 创建Transformer对象:Transformer transformer = transFactory.newTransformer();
3. 创建DOMSource对象:DOMSource domSource = new DOMSource(document);
4. 创建字节流:ByteArrayOutputStream bos = new ByteArrayOutputStream();
5. Transformer的transform()方法将DOM树转换成XML:Transformer对象.transform(DOMSource对象, new StreamResult(bos));

以上为关键代码,如果大家已经有了自己的思路和想法的话,可以不用再往下看了!!


下面为我自己的代码设计思路(可能不一定很好,所以大家也可用自己的设计)
代码设计思路:
1. 创建类XmlFormat:为xml的格式类,一个XmlFormat代表一个层级
(包含:根节点,层级节点,属性节点,设置节点的内容方法)
2. 创建类XmlHandler:用于生成xml字符串 和 生成xml文件
(包含:XmlFormat的集合,创建dom树的方法,生成xml字符串的方法,生成xml文件的方法,重载两个接口方法)


运行的结果图片:

这是第一种格式的xml图(生成的xml并没有换行,我是手动换的,方便图片制作)

java 生成xml中文乱码 java生成xml字符串_图片


这是第二种格式的xml图(生成的xml并没有换行,我是手动换的,方便图片制作)

java 生成xml中文乱码 java生成xml字符串_图片_02


这是本地生成的xml

java 生成xml中文乱码 java生成xml字符串_java 生成xml中文乱码_03

java 生成xml中文乱码 java生成xml字符串_java 生成xml中文乱码_04


完整代码
XmlFormat类:xml的格式类

import java.util.HashMap;

public class XmlFormat {

    //根节点名称
    private String rootName;
    //层级节点 名称/值 (值可为空。当值为空时,代表节点下带有属性节点。 当值不等于空时,代表该节点直接包含内容,没有属性节点)
    private HashMap<String, Object> multiplyNames;
    //属性节点 名称/值
    private HashMap<String, Object> propertyNames;

    /**构造函数
     * 参数: 根节点名称
     * */
    public XmlFormat(String rootName){
        this.rootName = rootName;
        this.multiplyNames = new HashMap<String, Object>();
        this.propertyNames = new HashMap<String, Object>();
    }

    /**(重载)用于xml层级节点键/值(没有属性节点)
     * 参数: 层级节点名称, 层级节点的值
     * */
    public void setElement(String multiplyName, String multiplyValue) {
        this.multiplyNames.put(multiplyName, multiplyValue);
    }

    /**(重载)用于xml层级节点,属性节点
     * 参数: 层级节点名称, 属性节点键/值
     * */
    public void setElement(String multiplyName, HashMap<String, Object> propertyNames) {
        this.multiplyNames.put(multiplyName, null);
        this.propertyNames = propertyNames;
    }

    /**
     * getter / setter
     * */
    ......
}

XmlHandler类:用于生成xml字符串 和 生成xml文件

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;

public class XmlHandler {

    //整个xml的节点数据(把设置的每个层级XmlFormat都添加到这个集合中)
    public List<XmlFormat> documentElements = new ArrayList<XmlFormat>();

    /** 生成Dom树
     *  返回Document(整个Dom Tree)
     * */
    private Document createDom(){
        DocumentBuilderFactory factory = null;
        DocumentBuilder builder = null;
        Document document = null;
        try {
            factory = DocumentBuilderFactory.newInstance();  //创建DocumentBuilderFactory工厂对象
            builder = factory.newDocumentBuilder();          //通过工厂对象, 创建DocumentBuilder制作对象
            document = builder.newDocument();                //通过制作对象, 创建一个Document对象,该对象代表一个XML文件
            document.setXmlStandalone(true);                 //设置XMLstandalone, true为没有dtd和schema作为该XML的说明文档

            //创建根节点
            Element root = document.createElement(documentElements.get(0).getRootName());
            document.appendChild(root);     

            //循环创建整个DOM树
            for(int i = 0; i < documentElements.size(); i++){   
                XmlFormat format = documentElements.get(i);   //获取xml的一个完整层级
                //循环创建层级节点
                for(Entry<String, Object> entryMultiply : format.getMultiplyNames().entrySet()){
                    if(entryMultiply.getValue() != null && !entryMultiply.getValue().toString().equalsIgnoreCase("")){ // 层级节点键/值(没有属性节点)
                        Element multiplyNode = document.createElement(entryMultiply.getKey());      // 创建一个层级节点
                        multiplyNode.setTextContent(entryMultiply.getValue().toString());           // 设置该层级节点的值
                        root.appendChild(multiplyNode);
                    } else {                                                                        // 层级节点键(带有属性节点)
                        Element multiplyNode = document.createElement(entryMultiply.getKey());      // 创建一个层级节点
                        root.appendChild(multiplyNode);
                        //循环创建属性节点
                        for(Entry<String, Object> entryProperty : format.getPropertyNames().entrySet()){
                            Element propertyNode = document.createElement(entryProperty.getKey());  // 创建一个属性节点
                            propertyNode.setTextContent(entryProperty.getValue().toString());       // 设置该属性节点的值
                            multiplyNode.appendChild(propertyNode);
                        }
                        root.appendChild(multiplyNode);         //设置层级节点到根节点
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } 
        return document;
    }


    /** 生成xml字符串
     *  参数: Document树对象
     *  返回String: 整个xml字符串
     * */
    private String createXmlToString(Document document){
        String xmlString = null;
        try {
            // 创建TransformerFactory工厂对象
            TransformerFactory transFactory = TransformerFactory.newInstance();     
            // 通过工厂对象, 创建Transformer对象
            Transformer transformer = transFactory.newTransformer();                
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
            //使Xml自动换行, 并自动缩进
            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "");           
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");  //中间的参数网址固定写法(这里还没搞懂)
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");                          //是否设置缩进(indent: yes|no)
            // 创建DOMSource对象并将Document加载到其中
            DOMSource domSource = new DOMSource(document); 
            ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
            // 使用Transformer的transform()方法将DOM树转换成XML
            transformer.transform(domSource, new StreamResult(bos));
            xmlString = bos.toString();  
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return xmlString;
    }


    /** 生成xml文件
     *  参数: url存放文件路径, Document树对象
     *  返回String: 反馈信息
     * */
    private String createXmlToFile(String url, Document document){
        String message = null;
        try{
            // 创建TransformerFactory对象
            TransformerFactory transFactory = TransformerFactory.newInstance();
            // 创建Transformer对象
            Transformer transformer = transFactory.newTransformer();
            //使Xml自动换行, 并自动缩进
            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");  //中间的参数网址固定写法(这里还没搞懂)
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");                          //是否设置缩进(indent: yes|no)
            // 建DOMSource对象并将Document加载到其中
            DOMSource domSource = new DOMSource(document); 
            //生成xml文件
            File file = new File(url); 
            if (!file.exists()) {       //判断文件是否存在
                file.createNewFile();   //不存在生存文件
            }
            FileOutputStream out = new FileOutputStream(file);     //文件输出流            
            StreamResult xmlResult = new StreamResult(out);        //设置输入源   
            // 使用Transformer的transform()方法将DOM树转换成XML(参数:DOMSource, 输入源)
            transformer.transform(domSource, xmlResult);
            message = "生成本地XML成功!";
        }catch(Exception e){
            e.printStackTrace();
            message = "生成本地XML失败!";
        }
        return message;
    }

    /** 接口方法(重载)
     *  创建Xml字符串
     *  返回String: xml字符串
     * */
    public String createXml(){
        String xmlString = null;
        if(documentElements != null && documentElements.size() > 0){    //判断是否存在xml格式和内容
            Document document = createDom();                //调用 生成Dom树 的方法
            xmlString = createXmlToString(document);        //调用 生成xml字符串 的方法
        }
        return xmlString;
    }

    /** 接口方法(重载)
     *  创建Xml本地文件(参数: 路径)
     *  返回String: 成功/失败消息
     * */
    public String createXml(String url){
        String xmlMessage = null;
        if(documentElements != null && documentElements.size() > 0){    //判断是否存在xml格式和内容
            Document document = createDom();                //调用 生成Dom树 的方法
            xmlMessage =  createXmlToFile(url, document);   //调用 生成xml文件 的方法
        }
        return xmlMessage;
    }
}

代码的使用 | 测试

//方法使用1(该方法为第一张结果截图,每个层级节点下,带有属性节点)
    public static void main(String[] args) {
        //创建数据(这里大家可以从数据库读出)
        String rootName = "rootXml";                    //根节点名称

        String multiplyOne = "multiply";                //层级节点名称
        HashMap<String, Object> propertyOnes = new HashMap<String, Object>();   //属性节点集合
        propertyOnes.put("name", "chuck");
        propertyOnes.put("age", 20);

        String multiplyTwo = "multiply2";               //层级节点名称
        HashMap<String, Object> propertyTwos = new HashMap<String, Object>();   //属性节点集合
        propertyTwos.put("name", "Jack");
        propertyTwos.put("age", 50);

        //创建Xmlformat格式类: 一个Xmlformat为一个层级(以下有两个层级,大家可以回到上面看结果截图)
        XmlFormat xmlformatOne = new XmlFormat(rootName);   //创建xml格式,并传入 根节点名称
        xmlformatOne.setElement(multiplyOne, propertyOnes); //设置层级节点名称 和 属性节点的集合 (setElement为重载方法)

        XmlFormat xmlformatTwo = new XmlFormat(rootName);   //创建xml格式,并传入 根节点名称
        xmlformatTwo.setElement(multiplyTwo, propertyTwos); //设置层级节点名称 和 属性节点的集合(setElement为重载方法)

        //创建XmlHandler
        XmlHandler xmlhandler = new XmlHandler();
        xmlhandler.documentElements.add(xmlformatOne);      //把格式XmlFormat, 设置xmlhandler里面的集合
        xmlhandler.documentElements.add(xmlformatTwo);      //把格式XmlFormat, 设置xmlhandler里面的集合

        String xmlString = xmlhandler.createXml();  //调用xmlHandler的接口方法, 获取xml字符串
        System.out.println(xmlString);
    }
//方法使用2(该方法为第二张结果截图,有一个层级节点下,直接带有内容,没有属性节点)
public static void main(String[] args) {
        //创建数据(这里大家可以从数据库读出)
        String rootName = "rootXml";                    //根节点名称

        String multiplyOne = "multiply";                //层级节点名称
        String multiplyOneValue = "hello multiply!";    //层级节点内容(没有属性节点)

        String multiplyTwo = "multiply2";               //层级节点名称
        HashMap<String, Object> propertyTwos = new HashMap<String, Object>();   //属性节点集合
        propertyTwos.put("name", "Jack");
        propertyTwos.put("age", 50);

        //创建Xmlformat格式类: 一个Xmlformat为一个层级(以下有两个层级,大家可以回到上面看结果截图)
        XmlFormat xmlformatOne = new XmlFormat(rootName);        //创建xml格式,并传入 根节点名称
        xmlformatOne.setElement(multiplyOne, multiplyOneValue);  //设置层级节点名称 和 层级节点内容 (setElement为重载方法)

        XmlFormat xmlformatTwo = new XmlFormat(rootName);        //创建xml格式,并传入 根节点名称
        xmlformatTwo.setElement(multiplyTwo, propertyTwos);      //设置层级节点名称 和 属性节点的集合(setElement为重载方法)

        //创建XmlHandler
        XmlHandler xmlhandler = new XmlHandler();
        xmlhandler.documentElements.add(xmlformatOne);      //把格式XmlFormat, 设置xmlhandler里面的集合
        xmlhandler.documentElements.add(xmlformatTwo);      //把格式XmlFormat, 设置xmlhandler里面的集合

        String xmlString = xmlhandler.createXml();          //调用xmlHandler的接口方法, 获取xml字符串
        System.out.println(xmlString);
    }
//方法使用3(该方法为最后两张结果截图,生成xml本地文件)
public static void main(String[] args) {
        //创建数据(这里大家可以从数据库读出)
        String rootName = "rootXml";                    //根节点名称

        String multiplyOne = "multiply";                //层级节点名称
        String multiplyOneValue = "hello multiply!";    //层级节点内容(没有属性节点)

        String multiplyTwo = "multiply2";               //层级节点名称
        HashMap<String, Object> propertyTwos = new HashMap<String, Object>();   //属性节点集合
        propertyTwos.put("name", "Jack");
        propertyTwos.put("age", 50);

        //创建Xmlformat格式类
        XmlFormat xmlformatOne = new XmlFormat(rootName);        //创建xml格式,并传入 根节点名称
        xmlformatOne.setElement(multiplyOne, multiplyOneValue);  //设置层级节点名称 和 层级节点内容 (setElement为重载方法)

        XmlFormat xmlformatTwo = new XmlFormat(rootName);        //创建xml格式,并传入 根节点名称
        xmlformatTwo.setElement(multiplyTwo, propertyTwos);      //设置层级节点名称 和 属性节点的集合

        //创建XmlHandler
        XmlHandler xmlhandler = new XmlHandler();
        xmlhandler.documentElements.add(xmlformatOne);      //把格式XmlFormat, 设置xmlhandler里面的集合
        xmlhandler.documentElements.add(xmlformatTwo);      //把格式XmlFormat, 设置xmlhandler里面的集合
        //调用xmlHandler的接口方法, 获取xml字符串(createXml重载方法,参数传入url)
        String xmlString = xmlhandler.createXml("D:\\Learn\\abc.xml");  
        System.out.println(xmlString);
    }