du7133 2014-11-16 12:21
浏览 112
已采纳

进行XML解析:将缺少的属性设置为“ true”

The snippet below,

package main
import (
    "encoding/xml"
    "fmt"
)

func main() {
    var r struct {
        Item []struct {
            Value string `xml:"value,attr"`
            Flag bool `xml:"flag,attr"`
        } `xml:"item"`
    }
    xml.Unmarshal([]byte(`
        <result>
            <item value="1" flag="false" />
            <item value="2" flag="true" />
            <item value="3" />
        </result>`,
    ), &r)
    fmt.Printf("%+v
", r)
}

Will print the following result:

{Item:[{Value:1 Flag:false} {Value:2 Flag:true} {Value:3 Flag:false}]}

In some elements, flag attribute will be missing (e.g. item 3 above), but I want it to take the default value of true, instead than false.

  1. I cannot assign it in the constructor, because I don't know the number of elements in the array upfront.
  2. I cannot use a custom type that implements UnmarshalerAttr and assign during unmarshaling because if the attribute is missing, UnmarshalXMLAttr is not run.
  3. I could make it a pointer, and then check if nil, then true, but that's just gross and error-prone.

How would I go about doing this?

  • 写回答

1条回答 默认 最新

  • dozc58418381 2014-11-16 14:14
    关注

    You're correct in that you cannot use UnmarshalerAttr for this. Instead, ResultItem can implement Unmarshaler which will allow you to set default attribute values:

    package main
    import (
        "encoding/xml"
        "fmt"
    )
    
    type ResultItem struct {
      Value string `xml:"value,attr"`
      Flag bool `xml:"flag,attr"`
    }
    
    func (ri *ResultItem) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
      type resultItem ResultItem // new type to prevent recursion
      item := resultItem{
        Flag: true,
      }
      if err := d.DecodeElement(&item, &start); err != nil {
        return err
      }
      *ri = (ResultItem)(item)
      return nil
    }
    
    func main() {
        var r struct {
          Item[] ResultItem `xml:"item"`
        }
        xml.Unmarshal([]byte(`
            <result x="ASDASD">
                <item value="1" flag="false" />
                <item value="2" flag="true" />
                <item value="3" />
            </result>`,
        ), &r)
        fmt.Printf("%+v
    ", r)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题