I am using Golang for an API gateway and we need to remove certain XML elements from documents.
We are unable to use structs/marshalling as the XML structures are huge and variable - but we consistently need to remove a few XML elements based on their name/path
I have tried to "walk" the XML document and "skip" certain elements based on their name.
My example is here, but I am getting errors: https://go.dev/play/p/LJtlYXWvJ_d
panic: xml: end tag </age> does not match start tag <person>
I must be doing something wrong, and most examples I can find use Structs to do this.
If you look at this output:
End Tag of age parent name is age
It gives a good clue. Then look right here:
case xml.EndElement:
println("End Tag of ", t.Name.Local, " parent name is ", parent.Name.Local)
if skip && t.Name == parent.Name {
skip = false
parent = xml.StartElement{}
}
if !skip {
println("Encoding End Element ", t.Name.Local, " buffer is ", buf.String())
err := encoder.EncodeToken(token)
if err != nil {
panic(err)
}
}
encoder.Flush()
From the output we can see that skip && t.Name == parent.Name
will be true. We toggle skip
to be false
and reset parent
. Then we proceed to check if !skip
. We just set skip
to false, so we attempt to encode the token. But we were supposed to skip that token!
The fix is simple: just add a break
to that case condition.
if skip && t.Name == parent.Name {
skip = false
parent = xml.StartElement{}
break
}
gives (debugging output removed):
		<people>
			<person>
				<name>John</name>
				
			</person>
			<person>
				<name>Jane</name>
				
			</person>
		</people>