登录
首页 >  Golang >  Go问答

不使用嵌套循环如何避免深层 XML?

来源:stackoverflow

时间:2024-02-13 21:06:15 285浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《不使用嵌套循环如何避免深层 XML?》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

我有深层嵌套的 xml 对象:

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"`
}

我需要使用正确的键从对象获取元素列表。如何在没有嵌套循环的情况下完成此操作:

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

正确答案


这是一个使用堆栈的完整工作解决方案。它比使用嵌套循环更复杂:

package main

import (
    "encoding/xml"
    "fmt"
)

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

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

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

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

func main() {
    // Example XML data
    xmlData := `
    
        
            
        
    
    `

    var obj Obj
    err := xml.Unmarshal([]byte(xmlData), &obj)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }

    // Call the iterative function to find elements with specific ID and Key
    elements := findElements("requireID", "requireKey", &obj)
    for _, el := range elements {
        fmt.Println("Element Key:", el.Key, "Value:", el.Val)
    }
}

// Helper function to convert slice to []interface{} slice
func toInterfaceSlice(slice interface{}) []interface{} {
    s := make([]interface{}, 0)
    switch slice.(type) {
    case []*Script:
        for _, v := range slice.([]*Script) {
            s = append(s, v)
        }
    case []*Table:
        for _, v := range slice.([]*Table) {
            s = append(s, v)
        }
    case []*Element:
        for _, v := range slice.([]*Element) {
            s = append(s, v)
        }
    }
    return s
}

func findElements(requiredID, requiredKey string, rootObj interface{}) []*Element {
    var elements []*Element
    stack := []interface{}{rootObj}

    for len(stack) > 0 {
        // Pop the top element from the stack
        obj := stack[len(stack)-1]
        stack = stack[:len(stack)-1]

        switch v := obj.(type) {
        case *Obj:
            for _, script := range v.Scripts {
                if script.ID == requiredID {
                    stack = append(stack, script)
                }
            }
        case *Script:
            stack = append(stack, toInterfaceSlice(v.Tables)...)
        case *Table:
            for _, el := range v.Elements {
                if el.Key == requiredKey {
                    elements = append(elements, el)
                }
            }
            stack = append(stack, toInterfaceSlice(v.Tables)...)
        }
    }

    return elements
}

理论要掌握,实操不能落!以上关于《不使用嵌套循环如何避免深层 XML?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>