doumeng3080 2017-01-19 02:33
浏览 10
已采纳

通过父级属性动态解组子XML

How do we dynamically unmarshal child XML with attributes from parent?

We have the the following XMLs:

<!-- Report I -->
<report type="YYYY-MM-DD">
  <created_at>2016-01-01</created_at>
</report>

<!-- Report II -->
<report type="DD-MM-YYYY">
  <created_at>01-01-2016</created_at>
</report>

And we have the following structure:

type Report struct {
  XMLName   xml.Name    `xml:"report"`
  Type      string      `xml:"type,attr"`
  CreatedAt *ReportDate `xml:"created_at"`
}

type ReportDate struct {
    time.Time
}

func (c *ReportDate) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
    const format = "02-01-2006" // or "2016-01-02" depending on parent's "type"
    var v string
    d.DecodeElement(&v, &start)
    parse, err := time.Parse(format, v)
    if err != nil {
        return err
    }
    *c = ReportDate{parse}
    return nil
}

Will it be possible for ReportDate to obtain type="?" from it's parent in UnmarshalXML? Or will it be possible for Report to pass down attribute values to all child tags? If it is possible, how do we accomplish this?

  • 写回答

2条回答 默认 最新

  • dongneng5383 2017-01-19 08:30
    关注

    While parsing the parent you can set a 'private' field within the child element that let's it know the time format string to use.

    Here's a working example https://play.golang.org/p/CEqjWoDQR3.

    And here's the code:

    package main
    
    import (
        "encoding/xml"
        "fmt"
        "io"
        "time"
    )
    
    // TypeMap converts the XML date format string to a valid Go date format string
    var typeMap = map[string]string{
        "YYYY-MM-DD": "2006-01-02",
        "DD-MM-YYYY": "02-01-2006",
    }
    
    // Example XML documents
    var reportStrings = []string{
        `<!-- Report I -->
    <report type="YYYY-MM-DD">
      <created_at>2016-01-01</created_at>
    </report>`,
    
        `<!-- Report II -->
    <report type="DD-MM-YYYY">
      <created_at>01-01-2016</created_at>
    </report>`,
    }
    
    type Report struct {
        XMLName   xml.Name   `xml:"report"`
        Type      string     `xml:"type,attr"`
        CreatedAt ReportDate `xml:"created_at"`
    }
    
    type ReportDate struct {
        dateFormatStr string // lower-case field is ignored by decoder/encoder
    
        Time time.Time
    }
    
    func (r *Report) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
        for _, attr := range start.Attr {
            if attr.Name.Local == "type" {
                dateFormatStr, ok := typeMap[attr.Value]
                if !ok {
                    return fmt.Errorf("unknown date type '%s'", attr.Value)
                }
                r.CreatedAt.dateFormatStr = dateFormatStr
            }
        }
    
        for {
            tok, err := d.Token()
            if err == io.EOF {
                break
            }
            if err != nil {
                return err
            }
            switch tok.(type) {
            case xml.StartElement:
                nextStart := tok.(xml.StartElement)
                if nextStart.Name.Local == "created_at" {
                    d.DecodeElement(&r.CreatedAt, &nextStart)
                }
            }
        }
    
        return nil
    }
    
    func (c *ReportDate) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
        var s string
        d.DecodeElement(&s, &start)
        t, err := time.Parse(c.dateFormatStr, s)
        if err != nil {
            return err
        }
        c.Time = t
        return nil
    }
    
    func main() {
        for i, reportStr := range reportStrings {
            var report Report
            if err := xml.Unmarshal([]byte(reportStr), &report); err != nil {
                panic(err)
            }
    
            fmt.Printf("[%d] %s
    ", i, report.CreatedAt.Time)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥60 pb数据库修改或者求完整pb库存系统,需为pb自带数据库
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路