Home >Backend Development >Golang >How Can I Efficiently Traverse XML Descendants in Go Without Using XPath?

How Can I Efficiently Traverse XML Descendants in Go Without Using XPath?

Linda Hamilton
Linda HamiltonOriginal
2024-12-03 20:15:17998browse

How Can I Efficiently Traverse XML Descendants in Go Without Using XPath?

Exploring XML Data with Go

You're facing challenges in navigating XML data in Go, specifically finding a method to traverse through descendants of a particular node without specifying the exact XPath. Let's explore an approach that can assist you in this task.

Recursion and Vanilla XML Encoding

To achieve deep traversal, you can utilize a recursive struct and a straightforward walk function leveraging Go's vanilla encoding/xml package:

type Node struct {
    XMLName xml.Name
    Content []byte `xml:",innerxml"`
    Nodes   []Node `xml:",any"`
}

func walk(nodes []Node, f func(Node) bool) {
    for _, n := range nodes {
        if f(n) {
            walk(n.Nodes, f)
        }
    }
}

In this code, the walk function recursively visits each node's children. You can provide a custom function f to perform operations on individual nodes.

For instance, in the XML you provided, you can employ the walk function to process nodes based on their type, as shown below:

func handleNode(n Node) bool {
    switch n.XMLName.Local {
    case "p":
        // Process paragraphs
    case "dog":
        // Process dogs
    }
    return true // Keep traversing
}

walk([]Node{root}, handleNode)

Attributes Inclusion

In case you need to access attributes associated with nodes, you can extend the Node struct and customize the UnmarshalXML method accordingly:

type Node struct {
    XMLName xml.Name
    Attrs   []xml.Attr `xml:",any,attr"`
    Content []byte     `xml:",innerxml"`
    Nodes   []Node     `xml:",any"`
}

func (n *Node) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    n.Attrs = start.Attr
    type node Node
    return d.DecodeElement((*node)(n), &start)
}

With this modified structure, you can retrieve attributes within the walk function:

func handleNode(n Node) bool {
    for _, a := range n.Attrs {
        // Process attributes
    }
    return true // Keep traversing
}

By harnessing recursion and embracing vanilla XML encoding, you can effectively traverse complex XML structures, accessing nodes and attributes with ease.

The above is the detailed content of How Can I Efficiently Traverse XML Descendants in Go Without Using XPath?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn