英文:
How to remove/delete/modify XML elements from an XML document using Golang without using structs
问题
我正在使用Golang编写一个API网关,我们需要从文档中删除特定的XML元素。
由于XML结构庞大且可变,我们无法使用结构体/编组,但我们需要根据名称/路径删除一些XML元素。
我尝试了对XML文档进行“遍历”,并根据名称“跳过”某些元素。
这是我的示例代码,但是我遇到了错误:https://go.dev/play/p/LJtlYXWvJ_d
panic: xml: end tag </age> does not match start tag <person>
我一定做错了什么,而且我找到的大多数示例都使用结构体来实现这一点。
英文:
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.
答案1
得分: 1
如果你看这个输出:
End Tag of age parent name is age
它给了一个很好的线索。然后看这里:
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()
从输出中我们可以看到 skip && t.Name == parent.Name
将为真。我们将 skip
切换为 false
并重置 parent
。然后我们继续检查 if !skip
。我们刚刚将 skip
设置为 false,所以我们尝试对该令牌进行编码。但我们应该跳过该令牌!
修复方法很简单:只需在该 case 条件中添加一个 break
。
if skip && t.Name == parent.Name {
skip = false
parent = xml.StartElement{}
break
}
给出(已删除调试输出):
<people>
<person>
<name>John</name>
</person>
<person>
<name>Jane</name>
</person>
</people>
英文:
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):
&#x9;&#x9;<people>
&#x9;&#x9;&#x9;<person>
&#x9;&#x9;&#x9;&#x9;<name>John</name>
&#x9;&#x9;&#x9;&#x9;
&#x9;&#x9;&#x9;</person>
&#x9;&#x9;&#x9;<person>
&#x9;&#x9;&#x9;&#x9;<name>Jane</name>
&#x9;&#x9;&#x9;&#x9;
&#x9;&#x9;&#x9;</person>
&#x9;&#x9;</people>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论