Mule 3.9:移除XML Payload指定标签并保留命名空间与属性
修复DataWeave 1.0函数以保留XML命名空间与属性并移除指定标签
问题背景
需求:从XML Payload中移除所有userId和companyId标签,同时保留XML的命名空间与属性。现有DataWeave 1.0函数会误删属性和命名空间,无法满足需求。
输入XML
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv=http://www.w3.org/2003/05/soap-envelope> <soapenv:Header> <axis2ns1873:messageheader xmlns:axis2ns1873=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001 soapenv:mustUnderstand="false"> <ns5:providerService xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001> <ns5:name>SVC</ns5:name> <ns5:operation>auditLogPublish</ns5:operation> </ns5:providerService> <ns5:component xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001> Payments</ns5:component> <ns5:activity xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001> Payment</ns5:activity> <ns5:channel xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001>p</ns5:channel> <ns5:traceId xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001>e995d4fb-54d4-4d34-b56a-e0594578db0c</ns5:traceId> <ns5:applicationId xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001>Payments</ns5:applicationId> <ns5:userId xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001>user</ns5:userId> <ns5:companyId xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001>cy</ns5:companyId> <ns5:companyType xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001></ns5:companyType> <ns5:clientMachineId xmlns:ns5=http://www.host.com/xmlschema/resource/metadata/osa/infrastructure/v001>localhost</ns5:clientMachineId> </axis2ns1873:messageheader> <axis2ns1874:messageheader xmlns:axis2ns1874=http://host/xsd/cpsMessageTypes/V002 soapenv:mustUnderstand="false" guid="1ce23ccc-eb30-4fcc-9b1f-927c46921e34" traceId="1ce23ccc-eb30-4fcc-9b1f-927c46921e34" /> </soapenv:Header> <soapenv:Body> <ns2:approvePayments xmlns:ns2=http://host/xsd/service/V002> <ns2:payment> <ns2:MID></ns2:MID> <ns2:version>1</ns2:version> <ns2:documentType></ns2:documentType> </ns2:payment> <ns2:OTPValidated>SUCCESS</ns2:OTPValidated> <ns2:userInfo> <ns2:companyId> </ns2:companyId> <ns2:userId> </ns2:userId> <ns2:userType>CLIENT</ns2:userType> </ns2:userInfo> <ns2:userSiteminderSessionId>id=</ns2:userSiteminderSessionId> <ns2:userIpAddress>localhost</ns2:userIpAddress> </ns2:approvePayments> </soapenv:Body> </soapenv:Envelope>
现有问题代码
%dw 1.0 %output application/xml %function remove(content, y) ((content mapObject (value,key) -> ({} when ((y contains (key as :string)) and (value is :string or value is :boolean or value is :number)) otherwise ((key): remove(value,y)) )) when (content is :object) otherwise ((content map remove($,y)) when (content is :array) otherwise (content) )) --- remove(payload, flowVars.filterList)
问题分析
现有代码的核心问题:
- 未保留XML元素的属性(@节点):在
mapObject处理时直接返回空对象或元素值,丢失了元素的属性信息 - 处理元素键的方式不准确:直接将
key转为字符串,没有明确区分XML元素的本地名称与命名空间,容易导致命名空间丢失 - 过滤逻辑有局限性:只判断值为基础类型的标签,若目标标签包含子元素会漏处理
修复后的代码
%dw 1.0 %output application/xml %function removeElements(content, filterNames) content match { // 处理XML元素对象,保留属性和命名空间 :object -> content mapObject (value, key) -> { // 检查元素本地名称是否在过滤列表,不在则保留元素并递归处理子内容 (key @ ((value.@ default {}))): removeElements(value, filterNames) unless (filterNames contains (key.localName as :string)) }, // 处理数组类型 :array -> content map removeElements($, filterNames), // 基础类型直接返回 else -> content } --- removeElements(payload, flowVars.filterList)
修复说明
- 保留属性与命名空间:通过
key @ ((value.@ default {}))语法,明确保留元素的属性节点,DataWeave输出XML时会自动保留必要的命名空间声明 - 准确匹配元素本地名称:使用
key.localName获取XML元素的本地名称,避免因命名空间前缀不同导致的匹配错误 - 通用处理所有元素类型:不管目标标签的值是基础类型还是包含子元素,都会统一过滤,逻辑更健壮
- 语法优化:使用
match表达式替代嵌套条件判断,逻辑结构更清晰
验证结果
修复后的代码会移除所有userId和companyId标签,同时完整保留XML的命名空间、元素属性(如soapenv:mustUnderstand、guid等)以及其他所有内容。
内容的提问来源于stack exchange,提问作者daringfireball
相关产品推荐
相关产品推荐

