所以我使用FSharp.Data库,我有一个生成的类型:
<ArrayOfCar>
<Car>
<LicenseNumber>000</LicenseNumber>
<ProductionYear>2014</ProductionYear>
<Type>Audi</Type>
</Car>
<Car>
<LicenseNumber>999</LicenseNumber>
<ProductionYear>2012</ProductionYear>
<Type>BMW</Type>
</Car>
</ArrayOfCar>
现在我有一个问题,因为看起来F#编译器会生成两种类型,ArrayOfCars
和Car
。
现在我正在调用一个API,该API将返回上面的示例以获取汽车集合,还会返回一个Car
Car
然后作为根元素。但是,我只能使用ArrayOfCars
来解析ArrayOfCars.Parse
,据我所知,没有Car.Parse
。
我在这里缺少什么,或者我必须为Car
生成一个单独的类型来处理它是根元素吗?
答案 0 :(得分:2)
这是一个非常好的问题!这在当前版本的F#Data中并不常用,但我认为这是一个错误,所以我submitted a pull request which fixes this。下面的解决方案使用固定版本的F#Data,因此您可能需要从源代码构建它。
您可以使用IsSampleList=true
参数将多个样本传递给XML提供程序。然后,您可以指定使用Global=true
将所有具有相同名称的元素推断为相同的类型:
type C = XmlProvider<"""
<Samples>
<ArrayOfCar>
<Car><Type>Audi</Type></Car>
<Car><Type>BMW</Type></Car>
</ArrayOfCar>
<Car><Type>Trabant</Type></Car>
</Samples>""", SampleIsList=true, Global=true>
使用这些参数(和修复),F#Data现在将Car
视为这两个样本中的相同类型,因此您所要做的就是读取Car
节点单车或ArrayOfCar
多辆车:
let readCars str =
let doc = C.Parse(str)
match doc.Car, doc.ArrayOfCar with
| Some car, _ -> [| car |]
| _, Some cars -> cars.Cars
此功能现在可以读取两种格式:
readCars "<Car><Type>Audi</Type></Car>"
|> Seq.iter (fun c -> printfn "%s" c.Type)
readCars "<ArrayOfCar><Car><Type>Audi</Type></Car><Car><Type>BMW</Type></Car></ArrayOfCar>"
|> Seq.iter (fun c -> printfn "%s" c.Type)