func (a *NameID) Element() *etree.Element {
	el := etree.NewElement("saml:NameID")
	if a.NameQualifier != "" {
		el.CreateAttr("NameQualifier", a.NameQualifier)
	}
	if a.SPNameQualifier != "" {
		el.CreateAttr("SPNameQualifier", a.SPNameQualifier)
	}
	if a.Format != "" {
		el.CreateAttr("Format", a.Format)
	}
	if a.SPProvidedID != "" {
		el.CreateAttr("SPProvidedID", a.SPProvidedID)
	}
	if a.Value != "" {
		el.SetText(a.Value)
	}
	return el
}
Element returns an etree.Element representing the object in XML form.
package saml
import (
	"bytes"
	"compress/flate"
	"encoding/xml"
	"strconv"
	"time"
	"github.com/beevik/etree"
	"github.com/russellhaering/goxmldsig/etreeutils"
)
type AuthnRequest struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol AuthnRequest"`
	ID           string    `xml:",attr"`
	Version      string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Destination  string    `xml:",attr"`
	Consent      string    `xml:",attr"`
	Issuer       *Issuer   `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	Signature    *etree.Element
	Subject      *Subject
	NameIDPolicy *NameIDPolicy `xml:"urn:oasis:names:tc:SAML:2.0:protocol NameIDPolicy"`
	Conditions   *Conditions
	ForceAuthn                     *bool  `xml:",attr"`
	IsPassive                      *bool  `xml:",attr"`
	AssertionConsumerServiceIndex  string `xml:",attr"`
	AssertionConsumerServiceURL    string `xml:",attr"`
	ProtocolBinding                string `xml:",attr"`
	AttributeConsumingServiceIndex string `xml:",attr"`
	ProviderName                   string `xml:",attr"`
}
type LogoutRequest struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol LogoutRequest"`
	ID           string    `xml:",attr"`
	Version      string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Destination  string    `xml:",attr"`
	Issuer       *Issuer   `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	NameID       *NameID
	Signature    *etree.Element
	SessionIndex *SessionIndex `xml:"SessionIndex"`
}
func (r *LogoutRequest) Element() *etree.Element {
	el := etree.NewElement("samlp:LogoutRequest")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	el.CreateAttr("ID", r.ID)
	el.CreateAttr("Version", r.Version)
	el.CreateAttr("IssueInstant", r.IssueInstant.Format(timeFormat))
	if r.Destination != "" {
		el.CreateAttr("Destination", r.Destination)
	}
	if r.Issuer != nil {
		el.AddChild(r.Issuer.Element())
	}
	if r.NameID != nil {
		el.AddChild(r.NameID.Element())
	}
	if r.Signature != nil {
		el.AddChild(r.Signature)
	}
	if r.SessionIndex != nil {
		el.AddChild(r.SessionIndex.Element())
	}
	return el
}
func (r *LogoutRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias LogoutRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		IssueInstant: RelaxedTime(r.IssueInstant),
		Alias:        (*Alias)(r),
	}
	return e.Encode(aux)
}
func (r *LogoutRequest) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias LogoutRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(r),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	r.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
func (r *LogoutRequest) Bytes() ([]byte, error) {
	doc := etree.NewDocument()
	doc.SetRoot(r.Element())
	buf, err := doc.WriteToBytes()
	if err != nil {
		return nil, err
	}
	return buf, nil
}
func (r *LogoutRequest) Deflate() ([]byte, error) {
	buf, err := r.Bytes()
	if err != nil {
		return nil, err
	}
	var b bytes.Buffer
	writer, err := flate.NewWriter(&b, flate.DefaultCompression)
	if err != nil {
		return nil, err
	}
	if _, err := writer.Write(buf); err != nil {
		return nil, err
	}
	if err := writer.Close(); err != nil {
		return nil, err
	}
	return b.Bytes(), nil
}
func (r *AuthnRequest) Element() *etree.Element {
	el := etree.NewElement("samlp:AuthnRequest")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	el.CreateAttr("ID", r.ID)
	el.CreateAttr("Version", r.Version)
	el.CreateAttr("IssueInstant", r.IssueInstant.Format(timeFormat))
	if r.Destination != "" {
		el.CreateAttr("Destination", r.Destination)
	}
	if r.Consent != "" {
		el.CreateAttr("Consent", r.Consent)
	}
	if r.Issuer != nil {
		el.AddChild(r.Issuer.Element())
	}
	if r.Signature != nil {
		el.AddChild(r.Signature)
	}
	if r.Subject != nil {
		el.AddChild(r.Subject.Element())
	}
	if r.NameIDPolicy != nil {
		el.AddChild(r.NameIDPolicy.Element())
	}
	if r.Conditions != nil {
		el.AddChild(r.Conditions.Element())
	}
	if r.ForceAuthn != nil {
		el.CreateAttr("ForceAuthn", strconv.FormatBool(*r.ForceAuthn))
	}
	if r.IsPassive != nil {
		el.CreateAttr("IsPassive", strconv.FormatBool(*r.IsPassive))
	}
	if r.AssertionConsumerServiceIndex != "" {
		el.CreateAttr("AssertionConsumerServiceIndex", r.AssertionConsumerServiceIndex)
	}
	if r.AssertionConsumerServiceURL != "" {
		el.CreateAttr("AssertionConsumerServiceURL", r.AssertionConsumerServiceURL)
	}
	if r.ProtocolBinding != "" {
		el.CreateAttr("ProtocolBinding", r.ProtocolBinding)
	}
	if r.AttributeConsumingServiceIndex != "" {
		el.CreateAttr("AttributeConsumingServiceIndex", r.AttributeConsumingServiceIndex)
	}
	if r.ProviderName != "" {
		el.CreateAttr("ProviderName", r.ProviderName)
	}
	return el
}
func (r *AuthnRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias AuthnRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		IssueInstant: RelaxedTime(r.IssueInstant),
		Alias:        (*Alias)(r),
	}
	return e.Encode(aux)
}
func (r *AuthnRequest) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias AuthnRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(r),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	r.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
type Issuer struct {
	XMLName         xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	NameQualifier   string   `xml:",attr"`
	SPNameQualifier string   `xml:",attr"`
	Format          string   `xml:",attr"`
	SPProvidedID    string   `xml:",attr"`
	Value           string   `xml:",chardata"`
}
func (a *Issuer) Element() *etree.Element {
	el := etree.NewElement("saml:Issuer")
	if a.NameQualifier != "" {
		el.CreateAttr("NameQualifier", a.NameQualifier)
	}
	if a.SPNameQualifier != "" {
		el.CreateAttr("SPNameQualifier", a.SPNameQualifier)
	}
	if a.Format != "" {
		el.CreateAttr("Format", a.Format)
	}
	if a.SPProvidedID != "" {
		el.CreateAttr("SPProvidedID", a.SPProvidedID)
	}
	el.SetText(a.Value)
	return el
}
type NameIDPolicy struct {
	XMLName         xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol NameIDPolicy"`
	Format          *string  `xml:",attr"`
	SPNameQualifier *string  `xml:",attr"`
	AllowCreate     *bool    `xml:",attr"`
}
func (a *NameIDPolicy) Element() *etree.Element {
	el := etree.NewElement("samlp:NameIDPolicy")
	if a.Format != nil && *a.Format != "" {
		el.CreateAttr("Format", *a.Format)
	}
	if a.SPNameQualifier != nil {
		el.CreateAttr("SPNameQualifier", *a.SPNameQualifier)
	}
	if a.AllowCreate != nil {
		el.CreateAttr("AllowCreate", strconv.FormatBool(*a.AllowCreate))
	}
	return el
}
type Response struct {
	XMLName      xml.Name  `xml:"urn:oasis:names:tc:SAML:2.0:protocol Response"`
	ID           string    `xml:",attr"`
	InResponseTo string    `xml:",attr"`
	Version      string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Destination  string    `xml:",attr"`
	Consent      string    `xml:",attr"`
	Issuer       *Issuer   `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	Signature    *etree.Element
	Status       Status `xml:"urn:oasis:names:tc:SAML:2.0:protocol Status"`
	EncryptedAssertion *etree.Element `xml:"urn:oasis:names:tc:SAML:2.0:assertion EncryptedAssertion"`
	Assertion *Assertion `xml:"urn:oasis:names:tc:SAML:2.0:assertion Assertion"`
}
func (r *Response) Element() *etree.Element {
	el := etree.NewElement("samlp:Response")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	el.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
	el.CreateAttr("ID", r.ID)
	if r.InResponseTo != "" {
		el.CreateAttr("InResponseTo", r.InResponseTo)
	}
	el.CreateAttr("Version", r.Version)
	el.CreateAttr("IssueInstant", r.IssueInstant.Format(timeFormat))
	if r.Destination != "" {
		el.CreateAttr("Destination", r.Destination)
	}
	if r.Consent != "" {
		el.CreateAttr("Consent", r.Consent)
	}
	if r.Issuer != nil {
		el.AddChild(r.Issuer.Element())
	}
	if r.Signature != nil {
		el.AddChild(r.Signature)
	}
	el.AddChild(r.Status.Element())
	if r.EncryptedAssertion != nil {
		el.AddChild(r.EncryptedAssertion)
	}
	if r.Assertion != nil {
		el.AddChild(r.Assertion.Element())
	}
	return el
}
func (r *Response) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias Response
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		IssueInstant: RelaxedTime(r.IssueInstant),
		Alias:        (*Alias)(r),
	}
	return e.Encode(aux)
}
func (r *Response) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias Response
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(r),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	r.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
type Status struct {
	XMLName       xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol Status"`
	StatusCode    StatusCode
	StatusMessage *StatusMessage
	StatusDetail  *StatusDetail
}
func (s *Status) Element() *etree.Element {
	el := etree.NewElement("samlp:Status")
	el.AddChild(s.StatusCode.Element())
	if s.StatusMessage != nil {
		el.AddChild(s.StatusMessage.Element())
	}
	if s.StatusDetail != nil {
		el.AddChild(s.StatusDetail.Element())
	}
	return el
}
type StatusCode struct {
	XMLName    xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol StatusCode"`
	Value      string   `xml:",attr"`
	StatusCode *StatusCode
}
func (s *StatusCode) Element() *etree.Element {
	el := etree.NewElement("samlp:StatusCode")
	el.CreateAttr("Value", s.Value)
	if s.StatusCode != nil {
		el.AddChild(s.StatusCode.Element())
	}
	return el
}
var StatusSuccess = "urn:oasis:names:tc:SAML:2.0:status:Success"
const (
	StatusRequester = "urn:oasis:names:tc:SAML:2.0:status:Requester"
	StatusResponder = "urn:oasis:names:tc:SAML:2.0:status:Responder"
	StatusVersionMismatch = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
	StatusAuthnFailed = "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
	StatusInvalidAttrNameOrValue = "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue"
	StatusInvalidNameIDPolicy = "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"
	StatusNoAuthnContext = "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"
	StatusNoAvailableIDP = "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"
	StatusNoPassive = "urn:oasis:names:tc:SAML:2.0:status:NoPassive"  
	StatusNoSupportedIDP = "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"
	StatusPartialLogout = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
	StatusProxyCountExceeded = "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"
	StatusRequestDenied = "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"
	StatusRequestUnsupported = "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
	StatusRequestVersionDeprecated = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
	StatusRequestVersionTooHigh = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
	StatusRequestVersionTooLow = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"
	StatusResourceNotRecognized = "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"
	StatusTooManyResponses = "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"
	StatusUnknownAttrProfile = "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile"
	StatusUnknownPrincipal = "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"
	StatusUnsupportedBinding = "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"
)
type StatusMessage struct {
	Value string
}
func (sm StatusMessage) Element() *etree.Element {
	el := etree.NewElement("samlp:StatusMessage")
	el.SetText(sm.Value)
	return el
}
type StatusDetail struct {
	Children []*etree.Element
}
func (sm StatusDetail) Element() *etree.Element {
	el := etree.NewElement("samlp:StatusDetail")
	for _, child := range sm.Children {
		el.AddChild(child)
	}
	return el
}
type Assertion struct {
	XMLName      xml.Name  `xml:"urn:oasis:names:tc:SAML:2.0:assertion Assertion"`
	ID           string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Version      string    `xml:",attr"`
	Issuer       Issuer    `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	Signature    *etree.Element
	Subject      *Subject
	Conditions   *Conditions
	AuthnStatements []AuthnStatement `xml:"AuthnStatement"`
	AttributeStatements []AttributeStatement `xml:"AttributeStatement"`
}
func (a *Assertion) Element() *etree.Element {
	el := etree.NewElement("saml:Assertion")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("Version", "2.0")
	el.CreateAttr("ID", a.ID)
	el.CreateAttr("IssueInstant", a.IssueInstant.Format(timeFormat))
	el.AddChild(a.Issuer.Element())
	if a.Signature != nil {
		el.AddChild(a.Signature)
	}
	if a.Subject != nil {
		el.AddChild(a.Subject.Element())
	}
	if a.Conditions != nil {
		el.AddChild(a.Conditions.Element())
	}
	for _, authnStatement := range a.AuthnStatements {
		el.AddChild(authnStatement.Element())
	}
	for _, attributeStatement := range a.AttributeStatements {
		el.AddChild(attributeStatement.Element())
	}
	err := etreeutils.TransformExcC14n(el, canonicalizerPrefixList)
	if err != nil {
		panic(err)
	}
	return el
}
func (a *Assertion) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias Assertion
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(a),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	a.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
type Subject struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:assertion Subject"`
	NameID *NameID
	SubjectConfirmations []SubjectConfirmation `xml:"SubjectConfirmation"`
}
func (a *Subject) Element() *etree.Element {
	el := etree.NewElement("saml:Subject")
	if a.NameID != nil {
		el.AddChild(a.NameID.Element())
	}
	for _, v := range a.SubjectConfirmations {
		el.AddChild(v.Element())
	}
	return el
}
type NameID struct {
	NameQualifier   string `xml:",attr"`
	SPNameQualifier string `xml:",attr"`
	Format          string `xml:",attr"`
	SPProvidedID    string `xml:",attr"`
	Value           string `xml:",chardata"`
}