2013-08-15 3 views
7

XML для JsonКак передать данные-структуру в качестве параметра в golang

package main 

import (
    "encoding/json" 
    "encoding/xml" 
    "fmt" 
) 

type Persons struct { 
    Person []struct { 
     Name string 
     Age int 
    } 
} 
type Places struct { 
    Place []struct { 
     Name string 
     Country string 
    } 
} 

type Parks struct { 
    Park struct { 
     Name  []string 
     Capacity []int 
    } 
} 

const personXml = ` 
    <Persons> 
     <Person><Name>Koti</Name><Age>30</Age></Person> 
     <Person><Name>Kanna</Name><Age>29</Age></Person> 
    </Persons> 
` 

const placeXml = ` 
    <Places> 
     <Place><Name>Chennai</Name><Country>India</Country></Place> 
     <Place><Name>London</Name><Country>UK</Country></Place> 
    </Places> 
` 

const parkXml = ` 
    <Parks> 
     <Park><Name>National Park</Name><Capacity>10000</Capacity></Park> 
     <Park>Asian Park</Name><Capacity>20000</Capacity></Park> 
    </Parks> 
` 

func WhatIamUsing() { 
    var persons Persons 
    xml.Unmarshal([]byte(personXml), &persons) 
    per, _ := json.Marshal(persons) 
    fmt.Printf("%s\n", per) 

    var places Places 
    xml.Unmarshal([]byte(placeXml), &places) 
    pla, _ := json.Marshal(places) 
    fmt.Printf("%s\n", pla) 

    var parks Parks 
    xml.Unmarshal([]byte(parkXml), &parks) 
    par, _ := json.Marshal(parks) 
    fmt.Printf("%s\n", par) 
} 

Что я хочу, это общая функция, которая принимает XML-строку и dataStruct и возвращает выход JSon. Но ниже функция бросает ошибку Как это сделать? сообщение

func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) { 
    var dataStruct DataStruct 
    xml.Unmarshal([]byte(personXml), &dataStruct) 
    js, _ := json.Marshal(dataStruct) 
    return fmt.Sprintf("%s\n", js), nil 
} 

func main() { 
    jsonstring, _ := Xml2Json(personXml, Persons) 
} 

Ошибка:

prog.go: 73: DataStruct не является типом

prog.go: 80: Тип Лица, не является выражением

GoPlay ссылка: http://play.golang.org/p/vayb0bawKx

ответ

12

Вы не можете сохранить тип (например, Persons) в интерфейсе. Вы можете передать reflect.Type вашей функции. Тогда ваш звонок будет выглядеть как Xml2Json(personXml, reflect.TypeOf(Persons)), что довольно уродливо, на мой взгляд.

Лучше подход, вероятно:

func Xml2Json(xmlString string, value interface{}) (string, error) { 
    if err := xml.Unmarshal([]byte(xmlString), value); err != nil { 
     return "", err 
    } 
    js, err := json.Marshal(value) 
    if err != nil { 
     return "", err 
    } 
    return string(js), nil 
} 

Вы можете использовать эту функцию с Xml2Json(personXml, new(Persons)), если вы не заинтересованы в самой ценности, и

var persons Persons 
Xml2Json(personXML, &persons) 

, когда вы хотите получить-структуру значение для последующей обработки.

1

Функция Xml2Json объявляет параметр с именем DataStruct. В той же области идентификатор DataStruct не может обозначать имя типа. Если вы хотите использовать имя типа DataStruct в той же области действия, вы должны указать свой параметр по-разному.

В основной функции проблема заключается в том, что синтаксис вызова функции ожидает список выражений в скобках. Там вы передаете имя типа, что явно не может быть выражением.

Итак, чтобы ответить на ваш вопрос: Нет, вы не можете передать тип в качестве аргумента функции. Но вы можете передать экземпляр типа (в данном случае указатель на такой, например), чтобы получить эффект, который вы собираетесь:

package main 

import (
     "encoding/json" 
     "encoding/xml" 
     "fmt" 
     "log" 
) 

type Persons struct { 
     Person []struct { 
       Name string 
       Age int 
     } 
} 

type Places struct { 
     Place []struct { 
       Name string 
       Country string 
     } 
} 

type Parks struct { 
     Park struct { 
       Name  []string 
       Capacity []int 
     } 
} 

const (
     personXml = ` 
    <Persons> 
     <Person><Name>Koti</Name><Age>30</Age></Person> 
     <Person><Name>Kanna</Name><Age>29</Age></Person> 
    </Persons> 
` 
     placeXml = ` 
    <Places> 
     <Place><Name>Chennai</Name><Country>India</Country></Place> 
     <Place><Name>London</Name><Country>UK</Country></Place> 
    </Places> 
` 

     parkXml = ` 
    <Parks> 
     <Park><Name>National Park</Name><Capacity>10000</Capacity></Park> 
     <Park><Name>Asian Park</Name><Capacity>20000</Capacity></Park> 
    </Parks> 
` 
) 

func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) { 
     if err = xml.Unmarshal([]byte(xmlString), DataStruct); err != nil { 
       return 
     } 

     js, err := json.Marshal(DataStruct) 
     if err != nil { 
       return 
     } 

     return fmt.Sprintf("%s", js), nil 
} 

func main() { 
     var p Persons 
     jsonstring, err := Xml2Json(personXml, &p) 
     if err != nil { 
       log.Fatal(err) 
     } 

     fmt.Println(jsonstring) 

     var q Places 
     jsonstring, err = Xml2Json(placeXml, &q) 
     if err != nil { 
       log.Fatal(err) 
     } 

     fmt.Println(jsonstring) 

     var r Parks 
     jsonstring, err = Xml2Json(parkXml, &r) 
     if err != nil { 
       log.Fatal(err) 
     } 

     fmt.Println(jsonstring) 

} 

Playground


Выход:

{"Person":[{"Name":"Koti","Age":30},{"Name":"Kanna","Age":29}]} 
{"Place":[{"Name":"Chennai","Country":"India"},{"Name":"London","Country":"UK"}]} 
{"Park":{"Name":["National Park","Asian Park"],"Capacity":[10000,20000]}} 
Смежные вопросы