You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用嵌套循环从深度嵌套XML结构中提取指定Element?

避免嵌套循环提取Go嵌套XML结构中的指定Element

我有一个对应XML的深度嵌套Go结构体定义如下:

type Obj struct{
     Scripts  []*Script `xml:"scripts"`
}

type Script struct{
    ID string `xml:"id"`
    Tables []*Table `xml:"tables"`
}

type Table struct{
     Elements []*Element `xml:"elements"`
     Tables   []*Table   `xml:"tables"`
}

type Element struct{
     Key string `xml:"key"`
     Val string `xml:"val"`
}

需要从Obj中提取出符合指定Key的Element列表,当前使用多层嵌套循环实现的代码如下:

var elements []*Element
for _, s := range obj.Scripts {
     if s.ID == "requireID"{
          for _, table := range s.Tables{
                    for _, t := range table.Tables{
                         for _, el := range t.Elements{
                              if el.Key == "requireKey"{
                                   elements = append(elements, el)
                              }    
                         }
                    }
                }
          }
     }
}

请问如何不使用嵌套循环完成这一需求?


方案1:递归遍历(代码简洁易读)

由于Table结构体包含自身类型的子节点,属于递归结构,可以编写一个递归函数来遍历所有层级的Table,收集符合条件的Element,彻底消除嵌套循环:

// collectElementsByKey 递归遍历所有层级的Table,返回符合目标Key的Element列表
func collectElementsByKey(tables []*Table, targetKey string) []*Element {
    var elements []*Element
    for _, table := range tables {
        // 收集当前Table中符合条件的Element
        for _, el := range table.Elements {
            if el.Key == targetKey {
                elements = append(elements, el)
            }
        }
        // 递归处理子Table
        elements = append(elements, collectElementsByKey(table.Tables, targetKey)...)
    }
    return elements
}

在主逻辑中调用该函数:

var elements []*Element
for _, s := range obj.Scripts {
    if s.ID == "requireID" {
        // 直接传入当前Script的Tables,递归收集所有符合条件的Element
        elements = append(elements, collectElementsByKey(s.Tables, "requireKey")...)
    }
}

这种方式将嵌套遍历逻辑封装到独立函数中,代码结构更清晰,后续如果嵌套结构发生变化,只需修改递归函数即可。

方案2:迭代式遍历(避免递归栈溢出)

如果XML结构嵌套极深,递归可能导致栈溢出,此时可以用广度优先遍历的迭代方式实现:

// collectElementsByKeyIterative 迭代式遍历所有层级的Table,返回符合目标Key的Element列表
func collectElementsByKeyIterative(tables []*Table, targetKey string) []*Element {
    var elements []*Element
    // 用队列存储待处理的Table
    queue := make([]*Table, 0, len(tables))
    queue = append(queue, tables...)

    for len(queue) > 0 {
        // 取出队列头部的Table
        table := queue[0]
        queue = queue[1:]

        // 收集当前Table的符合条件的Element
        for _, el := range table.Elements {
            if el.Key == targetKey {
                elements = append(elements, el)
            }
        }
        // 将子Table加入队列,等待处理
        queue = append(queue, table.Tables...)
    }
    return elements
}

调用方式和递归版本完全一致,这种方式不会受递归深度限制,适合处理超深嵌套的场景。

内容的提问来源于stack exchange,提问作者vovanchello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:32:23