英文:
Unmarshal XML Into a Map
问题
如标题所述,我正在尝试将XML直接解组为一个映射(map),而不是先解组为结构体,然后再将结构体转换为映射。由于我处理的数据集相当大,双重转换所需的时间比预期的要长。
如果有人能提供任何关于这个问题的指导,我将非常感激。
XML:classAccesses元素重复出现,并且还有其他一些元素。
<classAccesses>
<apexClass>AccountRelationUtility</apexClass>
<enabled>true</enabled>
</classAccesses>
我的当前结构体:我首先解析出每个头元素,然后使用子元素创建一个新的结构体。
type classAccesses struct {
ApexClass string `xml:"apexClass"`
Enabled string `xml:"enabled"`
}
type diffs struct {
ClassAccesses []classAccesses `xml:"classAccesses"`
}
期望的映射:我想保留diffs结构体,但是我希望子结构体"ClassAccesses"变成类似下面的映射。
map[string]string {
"ApexClass": "enabled"
}
英文:
As the title states I am trying to unmarshal my XML directly into a map instead of having to first unmarshal into a struct and then convert the struct into a map. I am dealing a fairly large data set and the dual conversion is taking more time than desired.
If anyone could provide any guidance on this at all it would be greatly appreciated.
XML: The classAccesses repeat and there are a few other elements.
<classAccesses>
<apexClass>AccountRelationUtility</apexClass>
<enabled>true</enabled>
</classAccesses>
My current struct: I parse out each of the header elements first and then create a new struct with the child elemtnts
type classAccesses struct {
ApexClass string `xml:"apexClass"`
Enabled string `xml:"enabled"`
}
type diffs struct {
ClassAccesses []classAccesses `xml:"classAccesses"`
}
Desired map: I want to keep the diffs struct, but I want the child struct "ClassAccesses" to become similar to the below map.
map[string]string {
"ApexClass": "enabled"
}
答案1
得分: 3
如果你创建一个实现了xml.Unmarshaller接口的类型,那么你可以直接将数据编组到map[string]string中。
type classAccessesMap struct {
m map[string]string
}
func (c *classAccessesMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
c.m = map[string]string{}
key := ""
val := ""
for {
t, _ := d.Token()
switch tt := t.(type) {
// TODO: 解析内部结构
case xml.StartElement:
fmt.Println(">", tt)
case xml.EndElement:
fmt.Println("<", tt)
if tt.Name == start.Name {
return nil
}
if tt.Name.Local == "enabled" {
c.m[key] = val
}
}
}
}
这里是一个部分解决方案:https://play.golang.org/p/7aOQ5mcH6zQ
英文:
If you create a type that implements the xml.Unmarshaller interface then you can marshal your data directly into a map[string]string.
type classAccessesMap struct {
m map[string]string
}
func (c *classAccessesMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
c.m = map[string]string{}
key := ""
val := ""
for {
t, _ := d.Token()
switch tt := t.(type) {
// TODO: parse the inner structure
case xml.StartElement:
fmt.Println(">", tt)
case xml.EndElement:
fmt.Println("<", tt)
if tt.Name == start.Name {
return nil
}
if tt.Name.Local == "enabled" {
c.m[key] = val
}
}
}
}
Here is a partial solution; https://play.golang.org/p/7aOQ5mcH6zQ
答案2
得分: 2
截至Go 1.3版本,使用标准Go库无法直接将XML文档解组为map。
标准库中的XML部分可以在这里找到:http://golang.org/pkg/encoding/xml/,但没有提供与你在问题中所要求的功能完全相符的函数。
根据你的具体情况,可能有其他选择,例如:
- 并行化你的算法,即同时从文件中读取和解码。这只在你有多个文件需要读取时才能很好地工作。
- 在Go中编写自己的XML解码算法。
英文:
As of Go 1.3, it is not possible to unmarshal an XML document directly into a map using the standard Go library.
The XML part of the standard library is given here, http://golang.org/pkg/encoding/xml/, there are no functions to do exactly what you ask for in the question.
Depending on the specifics of your situation, you may have other options such as:
- Parallelise your algorithm, i.e. read from the file and decode at the same time. This will only work well if you have multiple files to read from.
- Write your own XML decoding algorithm in Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论