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# 编译器似乎会从中生成两种类型,ArrayOfCarsCar

现在我正在调用一个 API,它将 return 上面的汽车集合示例以及单个 CarCar 然后是根元素。但是,我只能使用 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)