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

如何在MuleSoft DataWeave中移除XML命名空间

如何在DataWeave 2.0中移除XML的所有命名空间?

我在使用MuleSoft DataWeave转换XML消息时,想要移除所有的xmlns命名空间,但当前的转换结果里仍残留着命名空间声明。以下是我的具体场景:

输入XML

<?xml version='1.0' encoding='UTF-8'?>
<Entries xmlns="http://www.example.nl/Entries" type="Catalog" name="xxx Catalog" exportDate="2018-01-18T10:08:27.609Z">
<Entry id="264063" deleted="0" creationDate="2017-05-26T14:26:09.511Z" lastModifiedDate="2017-10-13T22:46:39.000Z">
<Attributes>
<Attribute>
<MetadataPath>Just an example 1</MetadataPath>
<Locale/>
</Attribute>
<Attribute>
<MetadataPath>Just an example 2</MetadataPath>
<Locale>en_GB</Locale>
</Attribute>
</Attributes>
<Categories>
<Category>
<Hierarchy>GPC_Hierarchy</Hierarchy>
<Id>999999</Id>
</Category>
<Category>
<Hierarchy>GPC_xx_Hierarchy</Hierarchy>
<Id>999998</Id>
</Category>
</Categories>
<Specs>
<Spec>Validatie Spec</Spec>
<Spec>Item Spec</Spec>
</Specs>
</Entry>
</Entries>

当前使用的DataWeave代码

%dw 2.0
var x = payload.Entries
output application/xml encoding="utf-8"
---
{
 Entry @('type': x.@'type', name: x.@name, exportDate: x.@exportDate, id: x.Entry.@id, deleted: x.Entry.@deleted, creationDate: x.Entry.@creationDate, lastModifiedDate: x.Entry.@lastModifiedDate ) : {(x.Entry.Attributes ), ( Categories: (x.Entry.Categories) ), ( Specs: (x.Entry.Specs) ) }
}

当前转换结果(仍有残留命名空间)

<?xml version='1.0' encoding='UTF-8'?>
<Entry type="Catalog" name="xxx Catalog" exportDate="2018-01-18T10:08:27.609Z" id="264063" deleted="0" creationDate="2017-05-26T14:26:09.511Z" lastModifiedDate="2017-10-13T22:46:39.000Z">
<Attribute xmlns="http://www.example.nl/Entries">
<MetadataPath>Just an example 1</MetadataPath>
<Locale/>
</Attribute>
<Attribute xmlns="http://www.example.nl/Entries">
<MetadataPath>Just an example 2</MetadataPath>
<Locale>en_GB</Locale>
</Attribute>
<Categories>
<Category xmlns="http://www.example.nl/Entries">
<Hierarchy>GPC_Hierarchy</Hierarchy>
<Id>999999</Id>
</Category>
<Category xmlns="http://www.example.nl/Entries">
<Hierarchy>GPC_xx_Hierarchy</Hierarchy>
<Id>999998</Id>
</Category>
</Categories>
<Specs>
<Spec xmlns="http://www.example.nl/Entries">Validatie Spec</Spec>
<Spec xmlns="http://www.example.nl/Entries">Item Spec</Spec>
</Specs>
</Entry>

我不想完全重写整个消息结构,想知道有没有类似output application/xml removeAllNamespaces这样的简洁语法来一次性移除所有命名空间?


解决方案:递归移除所有命名空间

遗憾的是,DataWeave 2.0并没有提供直接的removeAllNamespaces输出参数,但我们可以通过递归遍历XML节点并移除命名空间的方式实现需求,而且不需要完全重写消息结构。这里有几种实用的方法:

方法1:通用递归函数处理全节点

写一个通用递归函数,遍历XML的每个元素和属性,自动移除命名空间:

%dw 2.0
output application/xml encoding="utf-8"

// 递归函数:移除节点与属性的命名空间
fun removeNamespaces(node) = 
    if (node is Object) 
        node mapObject (value, key) -> {
            // 提取不带命名空间的节点名
            (key as String splitBy ":")[-1] @(removeNamespaces(key.@)): 
                if (value is Array) value map removeNamespaces($) 
                else removeNamespaces(value)
        }
    else if (node is Array)
        node map removeNamespaces($)
    else
        node
---
// 对整个payload应用函数后,提取需要的结构
removeNamespaces(payload).Entries 

这个函数会自动处理所有层级的元素和属性,把带命名空间的节点名(如ns:Attribute)转换成纯节点名Attribute,同时清除所有xmlns声明。

方法2:基于现有转换代码快速修改

如果你想保留当前的转换逻辑,只需对最终生成的对象应用命名空间移除即可:

%dw 2.0
var x = payload.Entries
output application/xml encoding="utf-8"

fun removeNamespaces(node) = 
    if (node is Object) 
        node mapObject (value, key) -> {
            (key as String splitBy ":")[-1] @(removeNamespaces(key.@)): 
                if (value is Array) value map removeNamespaces($) 
                else removeNamespaces(value)
        }
    else if (node is Array)
        node map removeNamespaces($)
    else
        node
---
removeNamespaces({
 Entry @('type': x.@'type', name: x.@name, exportDate: x.@exportDate, id: x.Entry.@id, deleted: x.Entry.@deleted, creationDate: x.Entry.@creationDate, lastModifiedDate: x.Entry.@lastModifiedDate ) : {(x.Entry.Attributes ), ( Categories: (x.Entry.Categories) ), ( Specs: (x.Entry.Specs) ) }
})

方法3:用namespace函数清空命名空间

另一种更简洁的方式是利用namespace函数,直接为所有节点指定空命名空间:

%dw 2.0
output application/xml encoding="utf-8"
---
namespace "" payload.Entries.*Entry map ((entry) -> {
    Entry @(
        type: payload.Entries.@type,
        name: payload.Entries.@name,
        exportDate: payload.Entries.@exportDate,
        id: entry.@id,
        deleted: entry.@deleted,
        creationDate: entry.@creationDate,
        lastModifiedDate: entry.@lastModifiedDate
    ): {
        (entry.Attributes.*Attribute),
        Categories: entry.Categories.*Category,
        Specs: entry.Specs.*Spec
    }
})

最终效果

以上方法都会生成无任何命名空间的XML结果,示例如下:

<?xml version='1.0' encoding='UTF-8'?>
<Entry type="Catalog" name="xxx Catalog" exportDate="2018-01-18T10:08:27.609Z" id="264063" deleted="0" creationDate="2017-05-26T14:26:09.511Z" lastModifiedDate="2017-10-13T22:46:39.000Z">
<Attribute>
<MetadataPath>Just an example 1</MetadataPath>
<Locale/>
</Attribute>
<Attribute>
<MetadataPath>Just an example 2</MetadataPath>
<Locale>en_GB</Locale>
</Attribute>
<Categories>
<Category>
<Hierarchy>GPC_Hierarchy</Hierarchy>
<Id>999999</Id>
</Category>
<Category>
<Hierarchy>GPC_xx_Hierarchy</Hierarchy>
<Id>999998</Id>
</Category>
</Categories>
<Specs>
<Spec>Validatie Spec</Spec>
<Spec>Item Spec</Spec>
</Specs>
</Entry>

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:05:35