ホームページ >バックエンド開発 >Golang >XPath を使用せずに Go で XML の子孫を効率的に走査するにはどうすればよいですか?

XPath を使用せずに Go で XML の子孫を効率的に走査するにはどうすればよいですか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-12-03 20:15:171002ブラウズ

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

Go を使用した XML データの探索

Go で XML データをナビゲートするという課題、特に、XML データの子孫を横断する方法を見つけるという課題に直面しています。正確な XPath を指定せずに特定のノードを指定します。このタスクを支援できるアプローチを見てみましょう。

再帰とバニラ XML エンコーディング

深いトラバースを実現するには、再帰構造体と直接的なウォークを利用できます。 Go のバニラ エンコーディング/xml パッケージを利用する関数:

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)
        }
    }
}

このコードでは、 walk 関数は各ノードの子を再帰的に訪問します。カスタム関数 f を提供して、個々のノードで操作を実行できます。

たとえば、提供した XML では、以下に示すように、walk 関数を使用してタイプに基づいてノードを処理できます。

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)

属性の包含

ノードに関連付けられた属性にアクセスする必要がある場合は、 Node 構造体を拡張し、それに応じて UnmarshalXML メソッドをカスタマイズできます:

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)
}

この変更された構造を使用すると、walk 関数内の属性を取得できます:

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

再帰を利用し、バニラを採用することによりXML エンコーディングを使用すると、複雑な XML 構造を効果的に横断し、ノードや属性に簡単にアクセスできます。

以上がXPath を使用せずに Go で XML の子孫を効率的に走査するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。