解组时如何跳过元素?

时间:2017-06-09 10:48:22

标签: go

如何在解组XML时删除<Text Language="de">...</Text>,如下所示)?

我尝试使用UnmarshalXML方法跳过元素,但是,当我这样做时,它会跳过整个元素。

Example in Play Golang Link

package main

import (
    "encoding/xml"
    "fmt"
)

type Root struct {
    Translation []Text `xml:"Texts>Text>Text"`
}

type Text struct {
    Language string `xml:"Language,attr"`
    Value    string `xml:"Value"`
}

func main() {
    foo := `
        <Root>
            <Texts>
                <Text>
                    <Text Language="EN">
                        <Value>One</Value>
                    </Text>
                    <Text Language="de">
                        <Value>Eins</Value>
                    </Text>
                </Text>
            </Texts>
        </Root>
        `

    var root Root
    e := xml.Unmarshal([]byte(foo), &root)
    if e != nil {
        panic(e)
    }

    fmt.Printf("%+v\n", root)
}

func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    tx := struct{ Language, Value string }{}

    if start.Attr[0].Value == "EN" {
        d.DecodeElement(&tx, &start)

        // I couldn't got Language attr here
        *t = Text{tx.Language, tx.Value}
        // fmt.Printf("hey: %+v %s\n", tx, start.Attr[0].Value)
    } else {
        // It outputs DE element with empty fields
        d.Skip()
    }

    return nil
}

当前输出:

{Translation:[{Language: Value:One} {Language: Value:}]}

我想要的:

{Translation:[{Language:EN Value:One}]}

1 个答案:

答案 0 :(得分:2)

您通过在文本级别解组操作太低 - 您仍然是Unmarshalling 2 Texts元素,这就是为什么您会看到一个空的第二个元素。你可以尝试这样的事情:

package main

import (
    "encoding/xml"
    "fmt"
)

type Root struct {
    Translation Text `xml:"Texts>Text>Text"`
}

type Text []struct {
    Language string `xml:"Language,attr"`
    Value    string `xml:"Value"`
}

func main() {
    foo := `
        <Root>
            <Texts>
                <Text>
                    <Text Language="EN">
                        <Value>One</Value>
                    </Text>
                    <Text Language="de">
                        <Value>Eins</Value>
                    </Text>
                </Text>
            </Texts>
        </Root>
        `

    var root Root
    e := xml.Unmarshal([]byte(foo), &root)
    if e != nil {
        panic(e)
    }

    fmt.Printf("%+v\n", root)
}

func (t *Text) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    tx := []struct{
        Language string `xml:"Language,attr"`
        Value    string `xml:"Value"`
    }{}
    d.DecodeElement(&tx, &start)


    tSl := *t
    for _, elem := range tx {
        switch elem.Language {
        case "EN":
            tSl = append(tSl, struct{
                Language string `xml:"Language,attr"`
                Value    string `xml:"Value"`}{elem.Language, elem.Value})
        default:
            d.Skip()
        }
    }
    *t = tSl
    return nil
}

输出:

{Translation:[{Language:EN Value:One}]}