F#XML数据解析'''''''

时间:2015-02-14 11:45:51

标签: xml parsing f# type-providers f#-data

所以我使用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,该API将返回上面的示例以获取汽车集合,还会返回一个Car Car然后作为根元素。但是,我只能使用ArrayOfCars来解析ArrayOfCars.Parse,据我所知,没有Car.Parse

我在这里缺少什么,或者我必须为Car生成一个单独的类型来处理它是根元素吗?

1 个答案:

答案 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)