Groovy脚本删除REFCDEEXTERNE为纯数字的DeliveryOrder节点失败求助
问题排查:Groovy XML节点删除逻辑未生效
核心问题
需求是删除所有REFCDEEXTERNE值仅为数字的DeliveryOrder节点(或根据期望输出,实际需求为保留纯数字值的节点、删除非纯数字的节点),但执行脚本后所有节点均未被删除,与预期结果不符。
错误原因拆解
节点路径错误
new XmlParser().parseText(body)解析后,返回的list本身就是XML的根节点<DLF>,无需再通过list.DLF访问子节点,原脚本的路径写法导致无法定位到目标DeliveryOrder节点。正则表达式逻辑与需求不匹配
- 原脚本用
/[^0-9]/匹配“包含非数字字符”的内容,结合removeAll会删除这类节点,但如果你的需求是删除纯数字值的节点,应该用精确匹配正则/^\d+$/(匹配整个字符串全为数字); - 若你的实际需求是保留纯数字值的节点(与提供的期望输出一致),原正则逻辑是对的,但因为路径错误导致没有执行删除操作。
- 原脚本用
XML序列化默认行为干扰
XmlUtil.serialize()会自动添加<Root>包裹节点和XML声明,导致实际输出多出不必要的标签结构。
修正后的Groovy脚本
import java.util.HashMap; import groovy.xml.XmlUtil; import groovy.xml.*; import org.apache.camel.converter.stream.InputStreamCache; def Message processData(Message message) { def body = message.getBody(); if (body instanceof InputStreamCache) { body = body.getText(); } // 解析XML,list直接对应根节点<DLF> def list = new XmlParser().parseText(body) // 按需选择下方其中一个逻辑: // 逻辑1:删除REFCDEEXTERNE值仅为数字的DeliveryOrder节点 // list.DeliveryOrder.removeAll { it.REFCDEEXTERNE.text() ==~ /^\d+$/ } // 逻辑2:保留REFCDEEXTERNE值仅为数字的节点(匹配你的期望输出) list.DeliveryOrder.removeAll { it.REFCDEEXTERNE.text() =~ /[^0-9]/ } // 生成符合格式要求的XML,避免自动添加Root节点 def builder = new StreamingMarkupBuilder() def validData = builder.bind { mkp.declareNamespace("": "") out << list }.toString() message.setBody(validData); return message; }
关键修正说明
- 路径修正:直接用
list.DeliveryOrder定位目标节点,因为list就是根节点<DLF>; - 正则逻辑明确:
- 用
==~ /^\d+$/精确匹配纯数字字符串,实现删除纯数字值节点的需求; - 用
=~ /[^0-9]/匹配含非数字的字符串,实现删除非纯数字节点、保留目标节点的需求;
- 用
- 序列化优化:使用
StreamingMarkupBuilder替代XmlUtil.serialize(),避免生成多余的<Root>标签和XML声明,输出结构与期望一致。
验证结果
执行修正后的脚本后,输出将与期望完全一致:
<DLF> <DeliveryOrder> <COMMETTANT>3260</COMMETTANT> <COMPTE/> <REFCDEEXTERNE>23041533191</REFCDEEXTERNE> <ETATCOMMANDE>EXP</ETATCOMMANDE> <DATEETATDECOMMANDE>190420230940</DATEETATDECOMMANDE> </DeliveryOrder> </DLF>
内容的提问来源于stack exchange,提问作者GameBuilder
相关产品推荐
相关产品推荐

