Xml Soap Envelope

Hi there, i’m doing a command line app that acts as interface to some SOAP services.
In order to send and recive some valid response i have to parse a custom xml(envelope) that every soap service has his own frame envelope and in that frame i must add my buff/text/info.

One frame looks like this.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webPosRo.uaic/">
<soapenv:Body>
	<web:parseText_XML>
		<rawTextInput>HERE</rawTextInput>
	</web:parseText_XML>
</soapenv:Body>

</soapenv:Envelope>

And if you look in “HERE” i must place my content that i want to send.
I find it quite strange to use the encoding/xml package because i have 6 services for example and per service i have one envelope type.

And in order to pass them i need to make 6 different pairs of structs like this.

    type Envelope struct {
	XMLName    xml.Name `xml:"Envelope"`
	Val1       string   `xml:"xmlns:soapenv,attr"`
	Val2       string   `xml:"xmlns:web,attr"`
	CreateBody Body     `xml:"soapenv:Body"`
    }

    type Body struct {
    	CreateText Text `xml:"web:parseText_XML"`
    }
    
    type Text struct {
    	TextRow []byte `xml:"rawTextInput"`
    }

And if i have another envelope like.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webNpChunkerRo.uaic/">
   <soapenv:Body>
      <web:chunkText>
         <inputText>
         </inputText>
      </web:chunkText>
   </soapenv:Body>
</soapenv:Envelope>

I have another 3 struct pair type.

type Envelope1 struct {
	XMLName    xml.Name `xml:"Envelope"`
	Val1       string   `xml:"xmlns:soapenv,attr"`
	Val2       string   `xml:"xmlns:web,attr"`
	CreateBody Body1    `xml:"soapenv:Body"`
}

type Body1 struct {
	CreateText Text1 `xml:"web:chunkTest"`
}

type Text1 struct {
	TypeRow []byte `xml:"inputText"`
}

And i find it quite strange… and also in order to parse that first node that has a namespace

<soapenv:Envelope ... >
//content
</soapenv:Envelope>

After i Unmarshall and Marshall i get

<Envelope ... >
//content
</Envelope>

Just the first note loses that namespace “soapenv” and in order to have it compleate i must make a function that sanitize it like this.

func sanitizeEnvelope(buffer []byte) []byte {

	var (
		StartF = []byte("<Envelope")
		FinalF = []byte("</Envelope>")
		StartT = []byte("<soapenv:Envelope ")
		FinalT = []byte("</soapenv:Envelope>")
	)

	// Check all the bytes equal to StartF and FinalF
	// And replace all with StartT and FinalT
	buffer = bytes.Replace(buffer, StartF, StartT, -1)
	buffer = bytes.Replace(buffer, FinalF, FinalT, -1)

	// return the new sanitize envelope buffer
	return buffer
}

It’s there any better solution to parse this and also include that first node namsepace? Or it’s ok with a sanitize solution like one above?

I’d probably just let the envelope be a magic string and be done with it. SOAP is ugly anyway.

func (b Body1) marshalWithEnvelope(w io.Writer) error {
    before := []byte(`<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webPosRo.uaic/">
<soapenv:Body>
	<web:parseText_XML>
		<rawTextInput>`
    after := []byte(`</rawTextInput>
	</web:parseText_XML>
</soapenv:Body>`)

    if _, err := w.Write(before); err != nil {
        return err
    }
    if err := xml.NewEncoder(w).Encode(b); err != nil {
        return err
    }
    if _, err := w.Write(after); err != nil {
        return err
    }
    return nil
}

Or something to that effect.

Only one opinion?

Looks like some hard coded solution.I wonder how to parse the xml more dynamic in order to not change every time the xml struts.

I guess the other end of the spectrum is something like https://github.com/hooklift/gowsdl.

In java is the same, like you pass wsdl link in eclipse for example and it generates all classes and interfaces for that type of service.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.