如何使用Freemarker提取多个XML标签值拼接为URL字符串
Freemarker提取XML多同名节点拼接URL实现方案
场景说明
开发Freemarker模板时需处理如下XML报文:
<?xml version="1.0" encoding="UTF-8"?> <tns:Map xmlns:tns="urn://xxx" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <tns:type>2</tns:type> <tns:code>CAT</tns:code> <tns:code>DOG</tns:code> </tns:Map>
预期实现逻辑:
- 当
tns:type节点值为1时,输出路径http://test.com/somePath - 当
tns:type节点值为2时,提取所有tns:code节点的文本值,用英文逗号拼接,生成格式为http://test.com/test/CAT,DOG的URL
原有写法问题
写法1:遍历逻辑错误抛语法异常
原有代码如下:
<#ftl ns_prefixes={"ns1":"urn://xxx", "ns2":"urn://xxx"}> <#assign type = body["ns1:Request"]["ns1:Content"]["ns2:Map"]["ns2:type"]> <#if type?number == 1> http://test.com/somePath <#elseif type?number == 2> <#list body["ns1:Request"]["ns1:Content"]["ns2:Map"] as codeList> <#assign codes = codeList["ns2:code"]> http://test.com/test/${codes} </#list> </#if>
问题点:错误遍历Map根节点本身,没有定向遍历code子节点集合,循环逻辑不符合Freemarker XML节点遍历规则,直接抛出语法错误。
写法2:节点取值逻辑错误仅取到第一个值
原有代码如下:
<#ftl ns_prefixes={"ns1":"urn://xxx", "ns2":"urn://xxx"}> <#assign type = body["ns1:Request"]["ns1:Content"]["ns2:Map"]["ns2:type"]> <#assign codes = body["ns1:Request"]["ns1:Content"]["ns2:Map"]["ns2:code"]?sequence> <#if type?number == 1> http://test.com/somePath <#elseif type == 2> http://test.com/test/${codes[0]} </#if>
问题点:将code节点转为序列后,没有提取每个节点的文本值,直接取序列第一个元素输出,无法实现多值拼接,?join方法也因为序列内是节点对象而非字符串无法正常生效。
正确实现代码
<#ftl ns_prefixes={"ns1":"urn://xxx", "ns2":"urn://xxx"}> <#-- 提前提取公共Map节点,简化重复路径写法 --> <#assign mapNode = body["ns1:Request"]["ns1:Content"]["ns2:Map"]> <#assign typeVal = mapNode["ns2:type"]?number> <#if typeVal == 1> http://test.com/somePath <#elseif typeVal == 2> <#-- 1. 获取所有code节点转序列 2. 遍历提取每个节点的纯文本 3. 逗号拼接 --> <#assign codeTextList = mapNode["ns2:code"]?sequence?map(node -> node?text)> <#assign joinedCodes = codeTextList?join(",")> http://test.com/test/${joinedCodes} </#if>
关键逻辑说明
- Freemarker中访问XML父节点下的同名子节点时,直接通过
父节点["节点名"]即可拿到所有同名节点的集合,调用?sequence可转为标准Freemarker序列 - 序列中存储的是XML节点对象,必须通过
?map遍历每个节点调用?text取纯文本值,才能得到可拼接的字符串序列 - 字符串序列可直接调用
?join(",")实现指定分隔符拼接,无需手动循环拼接
内容的提问来源于stack exchange,提问作者Rusl Mag
相关产品推荐
相关产品推荐

