本文介绍一下使用golang解析XML

const(
	_xmlMsg = `
<?xml version="1.0" encoding="utf-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">  
  <Owner> 
    <ID>AB258CD4B097495A95CF79E3223CAB3F</ID>  
    <DisplayName>app_AB258CD4B097495A95CF79E3223CAB3F</DisplayName> 
  </Owner>  
  <AccessControlList> 
    <Grant> 
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">  
        <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI> 
      </Grantee>  
      <Permission>READ</Permission> 
    </Grant>  
    <Grant> 
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
        <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
      </Grantee>
      <Permission>WRITE</Permission>
    </Grant>
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
        <ID>AB258CD4B097495A95CF79E3223CAB3F</ID>
        <DisplayName>app_AB258CD4B097495A95CF79E3223CAB3F</DisplayName>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy>
`
)

type _ACLContainer struct{
	XMLName xml.Name `xml:"AccessControlPolicy"`
	Owner _ACLOwner `xml:"Owner"`
	//AccessControlList _ACLControlList `xml:"AccessControlList"`
	Grant []_ACLGrant `xml:"AccessControlList>Grant"`
}
type _ACLOwner struct{
	ID string `xml:"ID"`
	DisplayName string `xml:"DisplayName"`
}

type _ACLControlList struct{
	Grant []_ACLGrant `xml:"Grant"`
}

type  _ACLGrant struct{
	Grantee struct {
		Type string `xml:"type,attr"`
		URI string `xml:"URI,omitempty"`
		ID string `xml:"ID,omitempty"`
		DisplayName string `xml:"DisplayName,omitempty"`
	} `xml:"Grantee"`
	Permission string `xml:"Permission"`
}
func TestXML(t *testing.T){
	container := &_ACLContainer{

	}
	err := xml.Unmarshal([]byte(_xmlMsg), container)
	if err != nil{
		logging.Error("unmarshal xml failure: %s", err.Error())
		return
	}
	logging.Info("unmarshal xml success")
	logging.Info("Owner: %s %s", container.Owner.ID, container.Owner.DisplayName)
	for _, grantee := range container.Grant{
		logging.Info("grantee: (type: %s URI: %s ID: %s displayName: %s permission: %s)",
			grantee.Grantee.Type,
			grantee.Grantee.URI,
			grantee.Grantee.ID,
			grantee.Grantee.DisplayName,
			grantee.Permission)
	}

}

上面注意一下_ACLContainer中关于AccessControlList的定义,如果我们对AccessControlList中的Grant是一级一级定义下来的,那么就不能使用AccessControlList>Grant;而如果我们省略了AccessControlList这一层级的定义,那么我们就需要用到AccessControlList>Grant


下面再给出一个有些怪异的示例:

const(
	xml3Str = `
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">south-china</LocationConstraint>
	`
)


type SXml3 struct{
	LC xml.Name `xml:"LocationConstraint"`
	Location string `xml:",cdata"`
}
func TestXml3(t *testing.T){
	v := &SXml3{}
	if err := xml.Unmarshal([]byte(xml3Str), &v); err != nil {
		t.Fatalf("Unmarshal: %s", err)
		return
	}
	logging.Info("location: %s", v.Location)
}



[参看]: