2017-08-02 2 views
2

Ich habe gerade angefangen Go zu lernen. Ich möchte einen SOAP-Dienst analysieren. Ich habe Schwierigkeiten, das XML zu analysieren. Hier ist der XML:Parse SOAP in Go

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 

    <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
     <wsse:UsernameToken> 
     <wsse:Username>USERNAME</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SECRET</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </SOAP-ENV:Header> 

    <SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <OTA_HotelAvailNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" EchoToken="abc123" Version="1.0" TimeStamp="2005-08-01T09:30:47+08:00"> 
     <AvailStatusMessages HotelCode="HOTEL"> 
     <AvailStatusMessage BookingLimit="10"> 
      <StatusApplicationControl Start="2010-01-01" End="2010-01-14" InvTypeCode="A1K" RatePlanCode="GLD"/> 
     </AvailStatusMessage> 
     </AvailStatusMessages> 
    </OTA_HotelAvailNotifRQ> 
    </SOAP-ENV:Body> 

</SOAP-ENV:Envelope> 

Und hier ist der Code, den ich schreiben die XML zu analysieren:

package main 

import (
    "fmt" 
    "encoding/xml" 
) 

type Envelope struct { 
    XMLName xml.Name 
    SOAPENV string `xml:"xmlns:SOAP-ENV,attr"` 
    XSD  string `xml:"xmlns:xsd,attr"` 
    XSI  string `xml:"xmlns:xsi,attr"` 
    SOAPENC string `xml:"xmlns:SOAP-ENC,attr"` 
    NS9132 string `xml:"xmlns:ns9132,attr"` 
    Header Header `xml:"SOAP-ENV:Header"` 
} 

type Header struct { 
    XMLName xml.Name `xml:"SOAP-ENV:Header"` 
    Security Security `xml:"wsse:Security"` 
} 

type Security struct { 
    XMLName  xml.Name `xml:"wsse:Security"` 
    MustUnderstand string `xml:"soap:mustUnderstand,attr"` 
    WSSE   string `xml:"xmlns:wsse,attr"` 
    SOAP   string `xml:"xmlns:soap,attr"` 
    UsernameToken struct { 
     XMLName xml.Name `xml:"wsse:UsernameToken"` 
     Username string `xml:"wsse:Username"` 
     Password string `xml:"wsse:Password"` 
    } 
} 

func main() { 

    Soap := []byte(`<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 

    <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
     <wsse:UsernameToken> 
     <wsse:Username>USERNAME</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SECRET</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </SOAP-ENV:Header> 

    <SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <OTA_HotelAvailNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" EchoToken="abc123" Version="1.0" TimeStamp="2005-08-01T09:30:47+08:00"> 
     <AvailStatusMessages HotelCode="HOTEL"> 
     <AvailStatusMessage BookingLimit="10"> 
      <StatusApplicationControl Start="2010-01-01" End="2010-01-14" InvTypeCode="A1K" RatePlanCode="GLD"/> 
     </AvailStatusMessage> 
     </AvailStatusMessages> 
    </OTA_HotelAvailNotifRQ> 
    </SOAP-ENV:Body> 

</SOAP-ENV:Envelope>`) 

    res := &Envelope{} 
    err := xml.Unmarshal(Soap, res) 

    fmt.Println(res.Header.Security.UsernameToken.Username, err) 
} 

Warum ist es nil zurückgibt. Ich erwarte, den Benutzernamen-Wert von ihm zu erhalten. Warum kann ich auch nicht xml:"SOAP-ENV:Envelope" für XMLName in der Envelop-Struktur verwenden? Die Fehlermeldung ist expected element type <SOAP-ENV:Envelope> but have <Envelope>

My Go Version 1.8.3

Antwort

4

Verwenden Sie einfach xml:"UsernameToken" statt xml:"wsse:UsernameToken" ist, xml:"wsse:Security" ->xml:"Security" usw.

package main 

import (
    "fmt" 
    "encoding/xml" 
) 

type Envelope struct { 
    XMLName xml.Name 
    Header Header 
} 

type Header struct { 
    XMLName xml.Name `xml:"Header"` 
    Security Security `xml:"Security"` 
} 

type Security struct { 
    XMLName  xml.Name `xml:"Security"` 
    MustUnderstand string `xml:"mustUnderstand,attr"` 
    WSSE   string `xml:"wsse,attr"` 
    SOAP   string `xml:"soap,attr"` 
    UsernameToken struct { 
     XMLName xml.Name `xml:"UsernameToken"` 
     Username string `xml:"Username"` 
     Password string `xml:"Password"` 
    } 
} 

func main() { 

    Soap := []byte(`<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 

    <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
     <wsse:UsernameToken> 
     <wsse:Username>USERNAME</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SECRET</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    </SOAP-ENV:Header> 

    <SOAP-ENV:Body xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <OTA_HotelAvailNotifRQ xmlns="http://www.opentravel.org/OTA/2003/05" EchoToken="abc123" Version="1.0" TimeStamp="2005-08-01T09:30:47+08:00"> 
     <AvailStatusMessages HotelCode="HOTEL"> 
     <AvailStatusMessage BookingLimit="10"> 
      <StatusApplicationControl Start="2010-01-01" End="2010-01-14" InvTypeCode="A1K" RatePlanCode="GLD"/> 
     </AvailStatusMessage> 
     </AvailStatusMessages> 
    </OTA_HotelAvailNotifRQ> 
    </SOAP-ENV:Body> 

</SOAP-ENV:Envelope>`) 

    res := &Envelope{} 
    err := xml.Unmarshal(Soap, res) 

    fmt.Println(res.Header.Security.UsernameToken.Username, err) 
} 

Ausgang: USERNAME <nil>

+0

Es ist funktioniert. Gibt es eine Erklärung, warum ich "wsse:" -Teil weglassen kann? – otezz

+1

@otezz: 'wsse:' ist ein [Namespacepräfix] (https://en.wikipedia.org/wiki/XML_namespace), es ist nicht Teil des Elementnamens. – JimB

+0

@ JimB jetzt bekomme ich es. Vielen Dank. – otezz