Is there a way to retain xml namespace prefixes when encoding? I am processing XML using the xml.Decoder Token/RawToken function and doing some transformations. There is a large amount of XML we want to remain formatted similar to the original XML. When I write a StartElement token back out unchanged the namespaces get written incorrectly.
Desired output:
<Inq xmlns="http://test/default">
<Num>TestNum</Num>
<test xmlns:t="http://test/prefix">
<t:namespace>test</t:namespace>
</test>
</Inq>
Actual output:
<Inq xmlns="http://test/default">
<Num>TestNum</Num>
<test xmlns:_xmlns="xmlns" _xmlns:t="http://test/prefix">
<namespace xmlns="t">test</namespace>
</test>
</Inq>
Code to reproduce the issue:
package main
import (
"bytes"
"encoding/xml"
"fmt"
"io"
"strings"
)
func main() {
expected := `<Inq xmlns="http://test/default"><Num>TestNum</Num><test xmlns:t="http://test/prefix"><t:namespace>test</t:namespace></test></Inq>`
payloadReader := strings.NewReader(expected)
decoder := xml.NewDecoder(payloadReader)
buf := new(bytes.Buffer)
encoder := xml.NewEncoder(buf)
for {
token, err := decoder.RawToken()
if err != nil {
if err == io.EOF {
break
}
panic(err)
}
if token == nil {
break
}
if err := encoder.EncodeToken(token); err != nil {
panic(err)
}
}
if err := encoder.Flush(); err != nil {
panic(err)
}
actual := buf.String()
if actual != expected {
fmt.Printf("got: %s\nwant: %s\n", actual, expected)
}
}
https://go.dev/play/p/mrjN5xOAp-y
Is there anyway to get the desired behavior other than tracking the namespace and prefixes and recreating the Start and End elements with the desired prefix naming?