2013-06-25 7 views
11

У меня есть данные XML, которые я извлекаю с помощью API REST, что я не подключаюсь к структуре GO. Одним из полей является поле даты, однако формат даты, возвращаемый API, не соответствует формату времени по умолчанию. Формат синтаксического анализа и, следовательно, немаршаль не выполняется.Golang XML Unmarshal и time.Time fields

Есть ли способ указать функцию unmarshal, формат даты которой будет использоваться в time.Time parsing? Я хотел бы использовать правильно определенные типы, и использование строки для хранения поля datetime кажется неправильным.

Образец структура:

type Transaction struct { 

    Id int64 `xml:"sequencenumber"` 
    ReferenceNumber string `xml:"ourref"` 
    Description string `xml:"description"` 
    Type string `xml:"type"` 
    CustomerID string `xml:"namecode"` 
    DateEntered time.Time `xml:"enterdate"` //this is the field in question 
    Gross float64 `xml:"gross"` 
    Container TransactionDetailContainer `xml:"subfile"` 
} 

Формат даты Возвращается "ггггммдд".

+0

Это может помочь, хотя это касается только сортировки. https://groups.google.com/forum/#!topic/golang-nuts/IM3ZIcYXbz4 – Intermernet

+0

Также ознакомьтесь с https://code.google.com/p/go/issues/detail?id=2771 – Intermernet

ответ

40

У меня была та же проблема.

time.Time не удовлетворяет интерфейсу xml.Unmarshaler. И вы не можете указать дату fomat.

Если вы не хотите, чтобы справиться с синтаксическим потом и вы предпочитаете, чтобы позволить xml.encoding сделать это, одно решение создать на структуру с анонимным time.Time области и реализовать свой собственный UnmarshalXML с вашим форматом даты.

type Transaction struct { 
    //... 
    DateEntered  customTime  `xml:"enterdate"` // use your own type that satisfies UnmarshalXML 
    //... 
} 

type customTime struct { 
    time.Time 
} 

func (c *customTime) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 
    const shortForm = "20060102" // yyyymmdd date format 
    var v string 
    d.DecodeElement(&v, &start) 
    parse, err := time.Parse(shortForm, v) 
    if err != nil { 
     return err 
    } 
    *c = customTime{parse} 
    return nil 
} 

Если ваш XML элемент использует attribut в качестве даты, вы должны реализовать UnmarshalXMLAttr таким же образом.

См http://play.golang.org/p/EFXZNsjE4a

+0

Это привело меня к правильному пути. Было даже легче иметь дело с тем, когда я делал «customTime time.Time» вместо этого - не нужно иметь дело с базовым «time.Time» как элементом структуры. – Colselaw

+1

Остерегайтесь того, что DecodeElement возвращает ошибку, которая должна быть проверена и возвращена, если не равна нулю. – AndreiM

1

Из того, что я прочитал кодирования/XML имеет некоторые известные проблемы, которые не были отложены до более поздней даты ...

Чтобы обойти эту проблему, вместо того, чтобы использовать тип time.Time использовать string и обрабатывать синтаксический анализ впоследствии.

я был совсем немного хлопот получать time.Parse работать с датами в следующем формате: «Пт, 9 августа 2013 19:39:39 GMT»

Как ни странно, я обнаружил, что «сеть/HTTP "имеет функцию ParseTime, которая принимает строку, которая отлично работает ... http://golang.org/pkg/net/http/#ParseTime

+0

. Самое странное, как только я установил тип поля даты в строку, все началось с разбора .... –

Смежные вопросы