如何在VB.NET Web Service中移除SOAP响应的xmlns=""属性
解决VB.NET Web Service返回XML中自动添加xmlns=""属性的问题
问题描述
开发基于VB.NET的Web Service时,返回的XML包含<mensaje>标签,但通过soapUI或Postman调用服务时,SOAP响应会自动给<mensaje>添加xmlns=""属性。尝试过返回XNode对象代替XmlDocument、手动查找移除该属性均未成功。相关代码片段如下:
' Load and extract data from the input XML oXMLDocument.LoadXml(Input) sConvenio = GetSetNodeValue(oXMLDocument, "mensaje/encabezado/convenio", "", Nothing) siden01 = Trim(GetSetNodeValue(oXMLDocument, "mensaje/identificador/iden01", "", Nothing)) ' Check the length of a string If Strings.Len(ConectaCompania(sConvenio)) = 36 Then ' Construct a SOAP request sTemp = "<!-- Query -->" sQuery = "<!-- SOAP request construction code -->" ' Send the SOAP request and receive a response sSOAPans = DISnode.Interact(sQuery) oXMLDoc.LoadXml(sSOAPans) ' Process the SOAP response and set values in the response XML If xmlNL.Count = 0 And oXMLDoc.InnerText <> "oRecordset0.00000000" Then ' Extract and set response tags GetSetNodeValue(oXMLDocument, "mensaje/encabezado/codigoRetorno", "000", Nothing) GetSetNodeValue(oXMLDocument, "mensaje/encabezado/mensajeRetorno", "CONSULTA EXITOSA", Nothing) ' Extract and set identifier and value tags (repeat for others) GetSetNodeValue(oXMLDocument, "mensaje/identificador/iden01", siden01, Nothing) ' ... ' Return the modified XML document Return oXMLDocument End If End If
原因分析
xmlns=""是SOAP框架自动添加的,本质是XML命名空间不匹配导致的:SOAP Envelope有默认命名空间,但你的<mensaje>节点属于空命名空间,框架为了保证XML结构的有效性,会显式添加空命名空间声明。
解决方案
方法1:递归移除所有空命名空间属性
编写递归方法遍历XML节点,移除所有xmlns=""属性,确保返回前执行该操作:
Private Sub RemoveEmptyNamespaces(xmlNode As XmlNode) ' 移除当前节点的空命名空间属性 If xmlNode.Attributes IsNot Nothing Then Dim attrsToRemove As New List(Of XmlAttribute)() For Each attr As XmlAttribute In xmlNode.Attributes If attr.Name = "xmlns" And attr.Value = String.Empty Then attrsToRemove.Add(attr) End If Next For Each attr As XmlAttribute In attrsToRemove xmlNode.Attributes.Remove(attr) Next End If ' 递归处理子元素节点 For Each child As XmlNode In xmlNode.ChildNodes If child.NodeType = XmlNodeType.Element Then RemoveEmptyNamespaces(child) End If Next End Sub
在返回oXMLDocument前调用该方法:
' 移除所有空命名空间属性 RemoveEmptyNamespaces(oXMLDocument.DocumentElement) Return oXMLDocument
方法2:统一XML节点的命名空间
让<mensaje>节点使用SOAP响应的默认命名空间,从根源避免空命名空间声明。假设SOAP的默认命名空间为http://your-soap-namespace.com,示例代码如下:
' 初始化命名空间管理器 Dim nsMgr As New XmlNamespaceManager(oXMLDocument.NameTable) nsMgr.AddNamespace("soap", "http://your-soap-namespace.com") ' 获取mensaje节点并设置命名空间 Dim mensajeNode As XmlNode = oXMLDocument.SelectSingleNode("//mensaje", nsMgr) If mensajeNode IsNot Nothing Then ' 强制设置节点的命名空间为SOAP默认命名空间 mensajeNode.NamespaceURI = "http://your-soap-namespace.com" ' 移除可能存在的空命名空间属性 If mensajeNode.Attributes("xmlns") IsNot Nothing Then mensajeNode.Attributes.Remove(mensajeNode.Attributes("xmlns")) End If End If
方法3:使用XmlWriter控制输出
通过XmlWriterSettings配置输出规则,避免空命名空间被自动添加:
Dim settings As New XmlWriterSettings() settings.OmitXmlDeclaration = False settings.Indent = True settings.NamespaceHandling = NamespaceHandling.OmitDuplicates Using sw As New StringWriter() Using writer As XmlWriter = XmlWriter.Create(sw, settings) oXMLDocument.WriteTo(writer) End Using ' 返回处理后的XML字符串(若你的服务允许返回字符串而非XmlDocument) Return sw.ToString() End Using
内容的提问来源于stack exchange,提问作者Diego Morales
相关产品推荐
相关产品推荐

