如何通过DataWeave将含@前缀字段的JSON转为带属性的XML
问题:将JSON中带@前缀的字段转换为XML对应元素的属性
在使用DataWeave 2.0将JSON转换为XML时,JSON中带@前缀的字段被错误转换为独立的XML标签(如<@id>1495144</@id>),需要将这些字段转为对应XML元素的属性。
示例请求JSON
{ "trans": { "@id": "1495144", "@TPId": "4aec", "@change": "0", "@count": "1", "@dateStamp": "2024-08-02T03:07:48", "data": { "@id": "d7D173564C5F14FF2AD08D621C188AF19", "StateFlag": "0", "DCC": "B", "LastName": "MMNGorthy", "Name": "Scott", "Structure": "NonProfit", "BusinessType": "Engineering", "meams": "AI", "Count": "0", "CTier": "000", "CTCond": "111", "CTPl": "222", "DO": "1", "AuthObject": "0" } } }
现有DataWeave代码
%dw 2.0 output application/xml ns ns0 http://Test.Sample.Data/1.0 --- ns0#trans: payload.trans
当前错误输出XML
<?xml version='1.0' encoding='UTF-8'?> <ns0:trans xmlns:ns0="http://Test.Sample.Data/1.0"> <@id>1495144</@id> <@TPId>4aec</@TPId> <@change>0</@change> <@count>1</@count> <@dateStamp>2024-08-02T03:07:48</@dateStamp> <data> <@id>d7D173564C5F14FF2AD08D621C188AF19</@id> <StateFlag>0</StateFlag> <DCC>B</DCC> <LastName>MMNGorthy</LastName> <Name>Scott</Name> <Structure>NonProfit</Structure> <BusinessType>Engineering</BusinessType> <meams>AI</meams> <Count>0</Count> <CTier>000</CTier> <CTCond>111</CTCond> <CTPl>222</CTPl> <DO>1</DO> <AuthObject>0</AuthObject> </data> </ns0:trans>
预期输出XML
<?xml version='1.0' encoding='UTF-8'?> <ns0:trans xmlns:ns0="http://Test.Sample.data/1.0" id="1495144" TPId='4aec' change='0' count='1' dateStamp="2024-08-02T03:07:48"> <data id="d7D173564C5F14FF2AD08D621C188AF19"> <StateFlag>0</StateFlag> <DCC>B</DCC> <LastName>MMNGorthy</LastName> <Name>Scott</Name> <Structure>NonProfit</Structure> <BusinessType>Engineering</BusinessType> <meams>AI</meams> <Count>0</Count> <CTier>000</CTier> <CTCond>111</CTCond> <CTPl>222</CTPl> <DO>1</DO> <AuthObject>0</AuthObject> </data> </ns0:trans>
解决方案代码
通过递归处理JSON对象,分离@前缀字段并转换为XML属性(DataWeave中用@前缀标识XML属性),普通字段保留为子元素:
%dw 2.0 output application/xml ns ns0 http://Test.Sample.Data/1.0 // 递归处理对象,分离属性和子元素 fun processXmlNode(obj) = obj // 拆分@开头的属性字段和普通子元素字段 partition ((val, key) -> key startsWith "@") // 转换属性键名(去掉@)并转为XML属性格式,子元素递归处理 mapObject ((group, groupKey) -> if (groupKey == "0") { // 属性组:将键名的@去掉,用@前缀标记为XML属性 (keys group map "@" ++ ($ replace "@" with "")) : values group } else { // 子元素组:递归处理嵌套对象 (keys group) mapObject ((val, key) -> key: if (typeOf(val) == Object) processXmlNode(val) else val ) } ) --- ns0#trans: processXmlNode(payload.trans)
代码说明
- 递归函数
processXmlNode:处理每个JSON对象,拆分属性和子元素 partition操作:将对象中@开头的键和普通键分成两组- 属性转换:把@开头的键去掉@,并用
@前缀标记为XML属性(DataWeave约定) - 递归嵌套:对嵌套的JSON对象(如
data)重复处理,确保深层的@字段也转为属性
内容的提问来源于stack exchange,提问作者Zak01
相关产品推荐
相关产品推荐

