还在拼接字符串生成XML?(Java)

FreeMarker是一个功能强大的Java模板引擎,广泛应用于生成动态内容,如HTML、XML和其他文本格式。本文将介绍FreeMarker的基本使用方法,并提供一个更丰富的XML模板示例,以及模板标签和标识的含义。

1. 引入依赖

XML 复制代码
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

2. 编写生成XML的方法

以下是一个实现IXMLGeneratorService接口的服务类示例,该类负责加载FreeMarker模板并生成XML文件。

java 复制代码
@Service("InitXMLGeneratorServiceImpl")
@Slf4j
public class InitXMLGeneratorServiceImpl implements IXMLGeneratorService {
    @Value("${project.path:config.cfg}")
    private String path;

    /**
     * 模板加载方法
     *
     * @param templateContent 模板内容字符串
     * @return 加载的模板
     */
    @Override
    public Template templateBuild(String templateContent) {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
        cfg.setClassForTemplateLoading(InitXMLGeneratorServiceImpl.class, "/");
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        stringTemplateLoader.putTemplate("config.ftl", templateContent);
        cfg.setTemplateLoader(stringTemplateLoader);
        try {
            return cfg.getTemplate("config.ftl");
        } catch (IOException e) {
            log.error("加载配置XML模板出现异常:{}", e.getMessage());
            return null;
        }
    }

    /**
     * 生成XML
     *
     * @param template 模板对象
     * @param data 数据模型
     * @param path 文件保存路径
     * @param fileName 文件名
     * @return 生成的XML内容及文件信息
     */
    @Override
    public JSONObject createXMLAndGetAllPath(Template template, JSONObject data, String path, String fileName) {
        JSONObject jsonObject = new JSONObject();
        try {
            StringWriter writer = new StringWriter();
            template.process(data, writer);
            String xml = writer.toString();
            File file = new File(path + "/" + fileName);
            try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
                bw.write(xml);
                bw.flush();
                jsonObject.set("xmlContent", xml);
                jsonObject.set("file", file);
                return jsonObject;
            } catch (Exception e) {
                log.error("写出XML模板出现异常:{}", e.getMessage());
                return null;
            }
        } catch (IOException | TemplateException e) {
            log.error("生成XML模板出现异常:{}", e.getMessage());
            return null;
        }
    }
}

3. 定义更丰富的XML模板

以下是一个更丰富的XML模板示例,适用于生成配置文件:

XML 复制代码
<!-- config.ftl -->
<configuration>
    <#if itemList?has_content>
    <itemList>
        <#list itemList as item>
            <item name="${item.name}" value="${item.value}" status="${item.status}">
                <description>${item.description}</description>
                <#if item.attributes?has_content>
                    <attributes>
                        <#list item.attributes as attribute>
                            <attribute name="${attribute.name}" value="${attribute.value}"/>
                        </#list>
                    </attributes>
                </#if>
            </item>
        </#list>
    </itemList>
    </#if>
    <version value="${version}"/>
    <date>${date}</date>
    <author>${author}</author>
    <comments>
        <#if comments?has_content>
            <#list comments as comment>
                <comment>${comment}</comment>
            </#list>
        </#if>
    </comments>
</configuration>

模板说明

<item>: 表示单个配置项,包含名称、值和状态等信息。

<attributes>: 可选元素,包含配置项的属性列表。

<author>: 添加了作者信息,标识配置文件的创建者。

<comments>: 包含可选的注释信息,用于提供额外的上下文。

模板标签与标识含义

4.1 模板标签

<#if>:条件判断标签,用于检查变量是否存在或有内容。

用法示例:<#if condition> ... </#if>

<#list>:循环标签,用于遍历集合。

用法示例:<#list collection as item> ... </#list>

${}:变量插值,用于输出数据模型中的值。

用法示例:${variable}

?has_content:检查变量是否有内容,返回布尔值。

用法示例:variable?has_content

?size:获取集合的大小。

用法示例:collection?size

4.2 模板标签属性参数说明

name:配置项的名称,标识该项的唯一性。

示例:<item name="${item.name}">

value:配置项的值,表示该项的具体内容。

示例:<item value="${item.value}">

status:配置项的状态,表示该项的启用或禁用状态。

示例:<item status="${item.status}">

description:对配置项的描述,提供更多上下文信息。

示例:<description>${item.description}</description>

attributes:可选属性,包含额外的配置信息。

示例:<attribute name="{attribute.name}" value="{attribute.value}"/>

DOM4J生成XML方式

优点

编程方式:通过Java代码直接构建XML,适合简单结构的生成。

类型安全:直接使用Java对象,避免了模板解析的潜在错误。

灵活性:适合动态生成XML,不依赖外部模板文件。

示例代码

java 复制代码
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.dom4j.DocumentHelper;

import java.io.FileOutputStream;

public class XMLGenerator {
    public void generateXML() {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("configuration");

        Element itemList = root.addElement("itemList");

        for (Item item : itemListData) {
            Element itemElement = itemList.addElement("item");
            itemElement.addAttribute("name", item.getName());
            itemElement.addAttribute("value", item.getValue());
            itemElement.addAttribute("status", item.getStatus());
            itemElement.addElement("description").setText(item.getDescription());

            if (item.getAttributes() != null) {
                Element attributes = itemElement.addElement("attributes");
                for (Attribute attribute : item.getAttributes()) {
                    Element attributeElement = attributes.addElement("attribute");
                    attributeElement.addAttribute("name", attribute.getName());
                    attributeElement.addAttribute("value", attribute.getValue());
                }
            }
        }

        root.addElement("version").addAttribute("value", "1.0");
        root.addElement("date").setText("2024-08-23");
        root.addElement("author").setText("Your Name");

        try (FileOutputStream fileOutputStream = new FileOutputStream("output.xml")) {
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer = new XMLWriter(fileOutputStream, format);
            writer.write(document);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

对比总结

生成方式:FreeMarker基于模板文件,适合动态内容;DOM4J通过Java代码构建,适合简单结构。

可读性:FreeMarker模板结构清晰,易于维护;DOM4J代码较长,结构不如模板清晰。

灵活性:FreeMarker支持复杂逻辑和条件判断;DOM4J动态生成XML,但不支持复杂条件。

类型安全:FreeMarker依赖于模板解析,可能出现运行时错误;DOM4J直接使用Java对象,类型安全。

适用场景:FreeMarker适合需要频繁修改的动态内容生成;DOM4J适合简单、固定结构的XML生成。

相关推荐
慢慢雨夜14 分钟前
uniapp 苹果安全域适配
java·前端·uni-app
敲代码不忘补水19 分钟前
二十种编程语言庆祝中秋节
java·javascript·python·golang·html
码农研究僧33 分钟前
Java或者前端 实现中文排序(调API的Demo)
java·前端·localecompare·中文排序·collator
Chase-Hart33 分钟前
【每日一题】LeetCode 7.整数反转(数学)
java·数据结构·算法·leetcode·eclipse
四角小裤儿儿40 分钟前
Java数据结构(十一)——归并排序、计数排序
java·数据结构·排序算法
guangzhi06331 小时前
JVM本地方法栈
java·jvm·面试
akhfuiigabv1 小时前
使用LangChain创建简单的语言模型应用程序【快速入门指南】
java·python·语言模型·langchain
忘却的纪念1 小时前
基于SpringBoot的考研资讯平台设计与实现
java·spring boot·spring
.生产的驴1 小时前
SpringBoot 消息队列RabbitMQ死信交换机
java·spring boot·后端·rabbitmq·java-rabbitmq
振华OPPO1 小时前
我的5周年创作纪念日,不忘初心,方得始终。
android·java·android studio·安卓·安卓app