如何在DataWeave中正确获取XML的u:Id属性值
解决DataWeave 2.0处理SOAP XML时丢失u:Id属性值的问题
问题现象
输入的SOAP格式XML中,<o:UsernameToken>节点的u:Id属性带有具体UUID值,但经过DataWeave 2.0脚本转换后,输出的该属性值变为null。
原因分析
核心原因是脚本未明确处理自定义命名空间(u:前缀对应的命名空间)下的属性,DataWeave默认转换逻辑不会自动保留非默认命名空间的属性,且原脚本未显式引用该属性值。
解决方案
在DataWeave脚本中先声明u命名空间,再在映射<o:UsernameToken>节点时,显式指定保留u:Id属性并直接引用输入payload中的对应值。
示例代码
输入Payload(SOAP XML)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soapenv:Header> <o:Security soapenv:mustUnderstand="1"> <o:UsernameToken u:Id="uuid-abc123-def456-789"> <o:Username>testUser</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">testPass</o:Password> </o:UsernameToken> </o:Security> </soapenv:Header> <soapenv:Body> <!-- 业务内容 --> </soapenv:Body> </soapenv:Envelope>
原问题脚本(导致u:Id为null)
%dw 2.0 output application/xml ns soapenv http://schemas.xmlsoap.org/soap/envelope/ ns o http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd --- soapenv#Envelope: { soapenv#Header: { o#Security @(soapenv#mustUnderstand: "1"): { o#UsernameToken: { o#Username: payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.o#Username, o#Password @(Type: payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.o#Password.@Type): payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.o#Password } } }, soapenv#Body: payload.soapenv#Envelope.soapenv#Body }
修改后的正确脚本
%dw 2.0 output application/xml ns soapenv http://schemas.xmlsoap.org/soap/envelope/ ns o http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd ns u http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd --- soapenv#Envelope: { soapenv#Header: { o#Security @(soapenv#mustUnderstand: "1"): { o#UsernameToken @(u#Id: payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.@u#Id): { o#Username: payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.o#Username, o#Password @(Type: payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.o#Password.@Type): payload.soapenv#Envelope.soapenv#Header.o#Security.o#UsernameToken.o#Password } } }, soapenv#Body: payload.soapenv#Envelope.soapenv#Body }
正确输出结果
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <soapenv:Header> <o:Security soapenv:mustUnderstand="1"> <o:UsernameToken u:Id="uuid-abc123-def456-789"> <o:Username>testUser</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">testPass</o:Password> </o:UsernameToken> </o:Security> </soapenv:Header> <soapenv:Body> <!-- 业务内容 --> </soapenv:Body> </soapenv:Envelope>
关键修改点
- 新增
u命名空间的声明,确保脚本能识别该前缀对应的命名空间规则。 - 在
o#UsernameToken节点后添加@(u#Id: payload...@u#Id),显式将输入中的u:Id属性值映射到输出节点。
内容的提问来源于stack exchange,提问作者smcodemeister
相关产品推荐
相关产品推荐

