Go XML解析:将缺少的属性设置为" true"

时间:2014-11-16 12:21:39

标签: xml go

下面的代码段,

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\n", r)
}

将打印以下结果:

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

在某些元素中,flag属性将丢失(例如上面的第3项),但我希望它采用默认值true,而不是false

  1. 我无法在构造函数中分配它,因为我不知道数组中的元素数量。
  2. 我无法使用实现UnmarshalerAttr的自定义类型并在解组期间分配,因为如果缺少该属性,则不会运行UnmarshalXMLAttr
  3. 我可以把它作为一个指针,然后检查是否为零,然后是真的,但这只是粗略且容易出错。
  4. 我将如何做到这一点?

1 个答案:

答案 0 :(得分:3)

您的更正是因为您无法使用UnmarshalerAttr。相反,ResultItem可以实现Unmarshaler,这将允许您设置默认属性值:

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\n", r)
}