使用Groovy的XMLParser为XML添加SOAP信封时子节点丢失求助
解决Groovy XmlParser添加SOAP信封时丢失子节点的问题
问题现象
使用Groovy的XmlParser将请求XML嵌入SOAP Body时,原请求的子节点(username和password)丢失,仅保留空的login节点,无法生成包含完整请求内容的SOAP信封。
问题原因
直接调用appendNode(parsedIncomingRequest)时,XmlParser解析生成的Node对象在跨文档添加时,不会自动递归复制其子节点和完整属性上下文,仅创建了节点外壳,导致内部内容丢失。
解决方案
使用文档的importNode方法,递归导入整个节点树(包括子节点和属性),确保完整的请求内容被添加到SOAP Body中。
修改后的代码
import groovy.xml.XmlParser import groovy.xml.XmlUtil def soapEnvelope = """<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> </soapenv:Header> <soapenv:Body> </soapenv:Body> </soapenv:Envelope>""" def incomingRequest = """<?xml version="1.0" encoding="UTF-8"?> <ns1:login xmlns:ns1="urn:partner.soap.sforce.com"> <ns1:username>DemoUser</ns1:username> <ns1:password>DemoPass</ns1:password> </ns1:login>""" def parsedSoapEnvelope = new XmlParser().parseText(soapEnvelope) def parsedIncomingRequest = new XmlParser().parseText(incomingRequest) // 获取SOAP Body节点 def bodyNode = parsedSoapEnvelope.'soapenv:Body'[0] // 递归导入请求节点及其所有子节点和属性 def importedLoginNode = bodyNode.ownerDocument.importNode(parsedIncomingRequest, true) // 将导入后的节点添加到Body中 bodyNode.append(importedLoginNode) // 序列化并输出结果 def newXmlString = XmlUtil.serialize(parsedSoapEnvelope) println newXmlString
输出结果
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <ns1:login xmlns:ns1="urn:partner.soap.sforce.com"> <ns1:username>DemoUser</ns1:username> <ns1:password>DemoPass</ns1:password> </ns1:login> </soapenv:Body> </soapenv:Envelope>
替代方案(手动复制节点内容)
如果不想使用importNode,也可以手动复制原节点的属性和所有子节点:
// 替换代码中的导入和添加部分 def loginNode = bodyNode.appendNode(parsedIncomingRequest.name(), parsedIncomingRequest.attributes()) // 遍历并添加所有子节点 parsedIncomingRequest.children().each { child -> loginNode.appendNode(child.name(), child.attributes(), child.value()) }
内容的提问来源于stack exchange,提问作者MMZSTACK
相关产品推荐
相关产品推荐

