You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:06:52