2013-06-25 7 views
11

Mam dane XML, które pobieram za pośrednictwem interfejsu API REST, którego nie używam w strukturze GO. Jednym z pól jest pole daty, jednak format daty zwrócony przez interfejs API nie jest zgodny z domyślnym czasem. Format analizowania czasu, a tym samym niepoprawny błąd kończy się niepowodzeniem.Pole Golang XML Unmarshal i time.Time

Czy istnieje sposób na określenie niepoprawnej funkcji, której format daty ma być używany w czasie. Chciałbym użyć poprawnie zdefiniowanych typów i użycie ciągu znaków do przechowywania pola datetime jest nieprawidłowe.

Przykładowa struktura:

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"` 
} 

Format daty zwrócony jest "rrrrmmdd".

+0

To może pomóc, mimo że zajmuje się wyłącznie porządkowaniem. https://groups.google.com/forum/#!topic/golang-nuts/IM3ZIcYXbz4 – Intermernet

+0

Zobacz też: https://code.google.com/p/go/issues/detail?id=2771 – Intermernet

Odpowiedz

40

Miałem ten sam problem.

time.Time nie spełnia wymagań interfejsu xml.Unmarshaler. I nie możesz podać daty fomat.

Jeśli nie chcesz obsługiwać analizowania potem i wolisz niech xml.encoding zrobić, jednym z rozwiązań jest utworzenie struct z anonimowym time.Time dziedzinie i zaimplementować własną UnmarshalXML ze swoimi format daty zwyczaj.

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 
} 

Jeśli twój element XML używa atrybutu jako daty, musisz zaimplementować UnmarshalXMLAttr w ten sam sposób.

Zobacz http://play.golang.org/p/EFXZNsjE4a

+0

To postawiło mnie na właściwej drodze. Łatwiej było sobie z tym poradzić, gdy zamiast tego robiłem 'customTime time.Time' - nie potrzebowałem zajmować się podstawowym' time.Time' jako elementem struct. – Colselaw

+1

Pamiętaj, że DecodeElement zwraca błąd, który powinien zostać sprawdzony i zwrócony, jeśli nie jest zerowy. – AndreiM

1

Z tego co czytałem kodowania/xml ma jakieś znane problemy, które zostały odkładać na później ...

Aby obejść ten problem, zamiast przy użyciu typu time.Time użytkowania string i obsługi parsowanie później.

miałem sporo problemów z dostaniem time.Parse pracować z datami w następującym formacie: „piątek, 09 sierpnia 2013 19:39:39 GMT”

dziwo znalazłem, że „netto/http "ma funkcję ParseTime, która pobiera ciąg, który działał idealnie ... http://golang.org/pkg/net/http/#ParseTime

+0

Najdziwniejsze, jak tylko ustawiłem typ pola daty na ciąg, wszystko zaczęło się parsować ... –