如何在Thymeleaf自定义Element Model Processor中处理HTML标签及内容
以下是完整的doProcess方法实现,可直接满足你的需求:
import org.thymeleaf.model.*; @Override protected void doProcess(ITemplateContext context, IModel model, IElementModelStructureHandler structureHandler) { // 1. 处理外层my:form开始标签 IOpenElementTag originalFormOpenTag = (IOpenElementTag) model.get(0); // 保留原有全部属性,添加自动生成的自定义属性 AttributeMap newFormAttrs = originalFormOpenTag.getAttributes() .putAttribute("other-attr", "_generated_value_"); // 替换为不带前缀的form标签 IOpenElementTag newFormOpenTag = originalFormOpenTag .withElementName("form") .withAttributes(newFormAttrs); model.replace(0, newFormOpenTag); // 2. 处理外层my:form闭合标签 ICloseElementTag originalFormCloseTag = (ICloseElementTag) model.get(model.size() - 1); ICloseElementTag newFormCloseTag = originalFormCloseTag .withElementName("form"); model.replace(model.size() - 1, newFormCloseTag); // 3. 获取表单ID,用于后续给input添加属性 String formId = originalFormOpenTag.getAttributeValue("id"); // 4. 遍历所有内部节点,处理my:input标签 for (int i = 1; i < model.size() - 1; i++) { ITemplateEvent event = model.get(i); // 匹配my前缀的input标签(兼容普通打开标签和自闭合标签两种写法) if (event instanceof IElementTag elementTag && "input".equals(elementTag.getElementName().getElementName()) && "my".equals(elementTag.getElementName().getPrefix())) { AttributeMap newInputAttrs = elementTag.getAttributes() .putAttribute("form-id", formId); IElementTag newInputTag = elementTag.withAttributes(newInputAttrs); model.replace(i, newInputTag); } } }
核心逻辑说明
- 操作
IModel的核心是通过get(index)获取对应位置的模板事件,修改后调用replace(index, newEvent)替换回模型序列,整个表单的开始标签、闭合标签、内部子标签都可以通过这个方式修改 - 原有
my:input对应的AbstractAttributeTagProcessor逻辑不会被破坏:我们仅为标签新增属性,没有修改/移除原有属性,也没有变更标签的前缀匹配规则,原有处理器会正常执行后续的标签转换、属性处理逻辑 - 如果需要生成动态的属性值,可以通过
context.getVariable("变量名")获取模板上下文变量,或者调用自定义的ID生成逻辑替换示例中的固定值 - 如果你使用的是Thymeleaf 3.0之前的版本,
AttributeMap的操作API有细微差异,整体遍历、替换标签的逻辑完全通用
内容的提问来源于stack exchange,提问作者Pavel Polyakoff
相关产品推荐
相关产品推荐

