Я пытаюсь заставить работать некоторые веб-сервисы SOAP и хочу избежать создания XML в виде строки, поэтому я пытаюсь использовать MSXML2 (в Excel VBA) для его генерации.Однако сервер требует, чтобы пространства имен отображались очень специфическим образом:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://hostname/service">
<soapenv:Header/>
<soapenv:Body>
<v1:GetData>
<input1>value1</input1>
<input2>value2</input2>
</v1:GetData>
</soapenv:Body>
</soapenv:Envelope>
Я придумал следующий код (частично заимствованный из http://www.vbforums.com/showthread.php?734859-RESOLVED-xml-namespace),, который приближает меня:
Sub createXML()
Const soapNS As String = "http://schemas.xmlsoap.org/soap/envelope/"
Const bodyNS As String = "http://hostname/service"
Dim XmlDom As MSXML2.DOMDocument60
Dim Node As MSXML2.IXMLDOMElement
Dim Attr As MSXML2.IXMLDOMAttribute
Set XmlDom = New MSXML2.DOMDocument60
With XmlDom
Set Node = .createNode(NODE_ELEMENT, "soapenv:Envelope", soapNS)
.appendChild Node
Set Attr = .createNode(NODE_ATTRIBUTE, "xmlns:v1", bodyNS)
Attr.NodeValue = bodyNS
Node.setAttributeNode Attr
Set Attr = Nothing
With Node
Set Node = XmlDom.createNode(NODE_ELEMENT, "soapenv:Header", soapNS)
.appendChild Node
Set Node = XmlDom.createNode(NODE_ELEMENT, "soapenv:Body", soapNS)
.appendChild Node
With Node
Set Node = XmlDom.createNode(NODE_ELEMENT, "v1:GetData", bodyNS)
.appendChild Node
With Node
Set Node = XmlDom.createNode(NODE_ELEMENT, "v1:input1", bodyNS)
.appendChild Node
Node.appendChild XmlDom.createTextNode("value1")
Set Node = XmlDom.createNode(NODE_ELEMENT, "v1:input2", bodyNS)
.appendChild Node
Node.appendChild XmlDom.createTextNode("value2")
End With
End With
End With
End With
End Sub
, который генерирует следующий XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://hostname/service">
<soapenv:Header/>
<soapenv:Body>
<v1:GetData>
<v1:input1>value1</v1:input1>
<v1:input2>value2</v1:input2>
</v1:GetData>
</soapenv:Body>
</soapenv:Envelope>
Однако серверу не нравится префикс "v1" перед любым дочерним элементом "GetData".
Если я удаляю префикс из строк createNode:
Set Node = XmlDom.createNode(NODE_ELEMENT, "v1:input1", bodyNS)
до
Set Node = XmlDom.createNode(NODE_ELEMENT, "input1", bodyNS)
, он выдает следующее, что также не нравится серверу:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://hostname/service">
<soapenv:Header/>
<soapenv:Body>
<v1:GetData>
<input1 xmlns="http://hostname/service">value1</input1>
<input2 xmlns="http://hostname/service">value2</input2>
</v1:GetData>
</soapenv:Body>
</soapenv:Envelope>
Любые идеи о том, как я могу добиться конкретного форматирования, требуемого сервером, без создания XML вручную со строками?
РЕДАКТИРОВАТЬ: это выглядит как неудачное решение, но оно работает. Я бы предпочел решениеэто не требует замены строк:
xmlStr = Replace(Replace(xmlStr, " xmlns=""http://hostname/service""", ""), "GetData", "v1:GetData")