F# XML 数据解析 ''subtype''
F# XML Data parsing a ''subtype''
所以我正在使用 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,它将 return 上面的汽车集合示例以及单个 Car
和 Car
然后是根元素。但是,我只能使用 ArrayOfCars.Parse
解析 ArrayOfCars
,据我所知,没有 Car.Parse
。
这里有什么我遗漏的吗?或者当它是根元素时,我必须为 Car
生成一个单独的类型来处理吗?
这是个很好的问题!这在当前版本的 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)
所以我正在使用 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,它将 return 上面的汽车集合示例以及单个 Car
和 Car
然后是根元素。但是,我只能使用 ArrayOfCars.Parse
解析 ArrayOfCars
,据我所知,没有 Car.Parse
。
这里有什么我遗漏的吗?或者当它是根元素时,我必须为 Car
生成一个单独的类型来处理吗?
这是个很好的问题!这在当前版本的 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)