Проблемы с пространством имен MSXML2 - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь заставить работать некоторые веб-сервисы 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")
...