亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

解組 XML:根據屬性值使用不同的目標類型

解組 XML:根據屬性值使用不同的目標類型

Go
翻過高山走不出你 2023-06-26 16:35:51
我想使用不同的類型根據父節點的 name 屬性來解組子節點的 XML 內容。在下面的示例中,我有 2 個具有屬性“apple”和“peach”的子節點。我想Apple在屬性為 時"apple"使用Peachtype "peach"?;旧螦pple并且Peach有非常不同的結構,所以這就是場景。我將如何實現這一目標或建議的方法是什么?這是解決問題的基本設置的游樂場。<element>    <node name="apple">        <apple>            <color>red<color>        </apple>    </node>    <node name="peach">         <peach>            <size>medium</size>        </peach>    </node></element>var x = `...` // xmltype Element struct {    Nodes []struct{        Name string `xml:"name,attr"`    } `xml:"node"`    Apple Apple    Peach Peach}type Apple struct { // use this struct if name is "apple"    Color string } type Peach struct { // use this struct if name is "peach"    Size string}func main() {    e := Element{}    err := xml.Unmarshal([]byte(x), &e)    if err != nil {        panic(err)    }       fmt.Println(e.Apple.Color)    fmt.Println(e.Peach.Size}
查看完整描述

1 回答

?
桃花長相依

TA貢獻1860條經驗 獲得超8個贊

您可以簡單地迭代您的類型的節點,并通過打開它們的屬性來Element創建Apple和結構:PeachName


    for _, element := range e.Nodes {

        switch element.Name {

        case "apple":

            apples = append(apples, Apple{})

        case "peach":

            peaches = append(peaches, Peach{})

        }

    }

這是游樂場鏈接。


另一個更復雜的解決方案(但也更優雅和實用)是在您的類型上實現您自己的UnmarshalXML方法,這將直接用正確的類型填充它:Element


type Apple struct {

    Color string

}

type Peach struct {

    Size string

}


type Fruits struct {

    Apples  []Apple

    Peaches []Peach

}


type Element struct {

    XMLName xml.Name `xml:"element"`

    Nodes   []struct {

        Name  string `xml:"name,attr"`

        Apple struct {

            Color string `xml:"color"`

        } `xml:"apple"`

        Peach struct {

            Size string `xml:"size"`

        } `xml:"peach"`

    } `xml:"node"`

}


func (f *Fruits) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {

    var element Element

    d.DecodeElement(&element, &start)


    for _, el := range element.Nodes {

        switch el.Name {

        case "apple":

            f.Apples = append(f.Apples, Apple{

                Color: el.Apple.Color,

            })

        case "peach":

            f.Peaches = append(f.Peaches, Peach{

                Size: el.Peach.Size,

            })

        }

    }


    return nil

}


func main() {

    f := Fruits{}


    err := xml.Unmarshal([]byte(x), &f)

    if err != nil {

        panic(err)

    }


    fmt.Println("Apples:", f.Apples)

    fmt.Println("Peaches", f.Peaches)

}

這是第二個解決方案的游樂場鏈接

結果:


Apples: [{red}]

Peaches [{medium}]


查看完整回答
反對 回復 2023-06-26
  • 1 回答
  • 0 關注
  • 214 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號