在Go中解析Xml信封肥皂的最佳方法

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>

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?

As far as I can see, your envelopes are the same (from a parsing/schema point of view), so you could use struct embedding to reduce the amount of structs.

To further reduce the amout of structs you can use the > syntax in struct tags to wrap nested struct fields in one go (xml.Marshal, xml.Unmarshal)

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

type Msg1 struct {
     Envelope 
     Input string `xml:"soapenv:Body>web:chunkTest>inputText"`
}

I've not tested this to perfection, but it should be enough to get you started.