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

如何将自定义节点作为multimap:Message1的首个子节点插入XML?

问题

使用XMLSlurper读取现有XML文件,需将自定义创建的结构插入指定位置——作为multimap:Message1的首个子节点。目前xml.append()会将节点添加到XML末尾,尝试多种方法均未成功,怀疑是命名空间前缀导致问题。

源XML内容

<?xml version='1.0' encoding='UTF-8'?>
<multimap:Messages xmlns:multimap="http://example.com">
<multimap:Message1>
    <ns1:CostCenter xmlns:ns1="urn:example-com">
        <item>
            <POSID>123</POSID>
            <POSID_FORMATED>P.12.3</POSID_FORMATED>
            <YYBEZ>Apple</YYBEZ>
        </item>
        <item>
            <POSID>456</POSID>
            <POSID_FORMATED>P.45.6</POSID_FORMATED>
            <YYBEZ>Banana</YYBEZ>
        </item>
    </ns1:CostCenter>
    <ns0:CostCenter xmlns:ns0="urn:sap-com:document:sap:rfc:functions">
        <item>
            <KOSTL>0815</KOSTL>
            <LTEXT_DE>Supermarket</LTEXT_DE>
        </item>
        <item>
            <KOSTL>6666</KOSTL>
            <LTEXT_DE>Online Shop</LTEXT_DE>
        </item>
    </ns0:CostCenter>
</multimap:Message1>
</multimap:Messages>

当前代码

def Message processData() {
def countries = ["DE","SP","IT"]
def countriesCode = ["Germany","Spain","Italy"]

def countryList = new Node(null, "CountryList")

countries.eachWithIndex { country, index ->
    def part = countryList.appendNode("part")
    part.appendNode("CountryCode", countriesCode[index]?.trim())
    part.appendNode("Country", country?.trim())
}

// 使用xml.append(countryList)会将节点添加到XML末尾
// 以下代码会将节点添加到multimap:Messages标签之后,但无法放入multimap:Message1下
xml.children().add(1,countryList)

def updatedXml = XmlUtil.serialize(xml)
}

尝试过的方法:

  • 使用路径xml.Message1.children().add(1,countryList)
  • 使用replaceBody()函数
  • 查找节点:def msg1Node = xml.'multimap:Message1'.first()后尝试添加

解决方案

核心问题是命名空间的正确引用和XMLSlurper返回的GPathResult与Node对象的兼容处理,按以下方式修改代码即可实现需求:

方法一:直接在目标节点下创建结构(推荐)

避免Node与GPathResult的兼容问题,直接在multimap:Message1节点内创建并插入自定义结构:

def Message processData() {
    def countries = ["DE","SP","IT"]
    def countriesCode = ["Germany","Spain","Italy"]
    // 定义multimap命名空间的完整URI
    def multimapNs = "http://example.com"

    // 获取目标节点multimap:Message1
    def msg1Node = xml."${multimapNs}:Message1".first()
    // 先保存原有的子节点
    def originalChildren = msg1Node.children().collect()
    // 清空目标节点,先添加自定义的CountryList
    msg1Node.children().clear()
    def countryList = msg1Node.appendNode("CountryList")

    // 填充CountryList的内容
    countries.eachWithIndex { country, index ->
        def part = countryList.appendNode("part")
        part.appendNode("CountryCode", countriesCode[index]?.trim())
        part.appendNode("Country", country?.trim())
    }

    // 把原有的子节点添加回目标节点,确保CountryList是首个子节点
    originalChildren.each { msg1Node.append(it) }

    def updatedXml = XmlUtil.serialize(xml)
    return updatedXml
}

方法二:转换Node为GPathResult后插入

如果坚持先用Node创建自定义结构,可将其序列化为XML字符串后再解析为GPathResult对象:

def Message processData() {
    def countries = ["DE","SP","IT"]
    def countriesCode = ["Germany","Spain","Italy"]
    def multimapNs = "http://example.com"

    // 创建自定义Node结构
    def countryList = new Node(null, "CountryList")
    countries.eachWithIndex { country, index ->
        def part = countryList.appendNode("part")
        part.appendNode("CountryCode", countriesCode[index]?.trim())
        part.appendNode("Country", country?.trim())
    }

    // 将Node转换为XML字符串并去掉声明,再解析为GPathResult
    def countryListXml = XmlUtil.serialize(countryList).replaceAll(/<\?xml.*?\>/, "")
    def countryListNode = new XmlSlurper().parseText(countryListXml)

    // 获取目标节点并插入自定义结构到首位
    def msg1Node = xml."${multimapNs}:Message1".first()
    def originalChildren = msg1Node.children().collect()
    msg1Node.children().clear()
    msg1Node.append(countryListNode)
    originalChildren.each { msg1Node.append(it) }

    def updatedXml = XmlUtil.serialize(xml)
    return updatedXml
}

关键说明

  • 定位命名空间节点时,必须使用完整的命名空间URI而非前缀,XMLSlurper内部通过URI识别命名空间,前缀仅为别名。
  • 操作GPathResult的子节点时,需先收集原有子节点、清空后重新添加,确保自定义结构处于首位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:15:15