13.4.1_读取值

13.4.1 读取值

 

    我们要做的第一件事,是从 XML 中读取我们感兴趣的数据。我们要写一个函数,取一个 XDocument 对象的列表(用于数据集的每个页面),并返回一个序列,每个元素包含指示器、 地区名,年,其中的值被测量。

    清单 13.14 显示,以 readValues 函数的形式,以及辅助函数,从表示一条记录的 XML 节点读数据。每个函数有一个参数,名为 parse,这是一个函数,用来解析实际字符串值。我们很快就会看到此参数背后的原因。

 

Listing 13.14 Reading values from the XML data (F#)

 

let readSingleValue parse node =
  let value = node |> xelem "value" |> xvalue
  let country = node |> xelem "country" |> xvlue
  let year = node |> xelem "date" |> xvalue |> int
  if (value = "") then []
  else [ (year, country), parse(value) ]

let readValues parse data = seq {
  for page in data do
    let root = page |> xnested [ "data" ]
    for node in root |> xelems "data" do
      yield! node |> readSingleValue parse }

 

    我们首先写工具函数,取格式化函数,和包含一个数据元素的 XML 节点(作为参数值)。它从子节点和属性中读值,将年转换为整数。如果你看看我们下载的数据,可以看到,value 元素有时是空的。如果这个值省略,通过返回空列表,来处理,否则,列表包含一个元素。注意,我们可以使用 option 类型代替,但是,列表使第二个函数更优雅:我们不必要区分这两种情况;我们简单地返回所有元素 (既可以是空,也可以是一个),使用 yield! 基元。

    第二个函数取整个输入的数据作为一个 XDocument 对象的序列,它查找所有 XML 元素,包含数据输入,格式化,返回序列。返回序列的元素类型是  (int * string) * 'a。第一个元组包含年和国家名。我们将把这作为键,以后用于搜索数据,这就是为什么使用嵌套的元组。第二个元素是使用 parse 函数格式化的值,所以,该函数无论返回什么,其类型将与之相同。

    和往常一样,我们可以立即尝试该函数。函数的输入键是数据源,写作最后一个参数,所以,我们可以使用流操作符。我们可以使用 (用于测试目的)的最简单解析器是,给它什么字符串,就返回什么字符串,而不要处理它。下面的代码片断说明如何处理第一个数据集,其中包含 1990 年所有国家的总面积。我们使用恒等函数(identity function) id,解析输入,因此,这些值将被格式化成字符串:

 

> data.[0] |> readValues id;;
val it : seq<(int * string) * string> =
seq [ ((1990, "ABW"), "180"); ((1990, "ADO"), "470");
((1990, "AFG"), "652090"); ((1990, "AGO"), "1246700");
...]

 

    你可以看到,我们正在接近所需要的东西:现在可以直接从序列读数据。剩余的唯一刺激是,值明显是数字,但我们却把它作为字符串看待。幸运的是,这是容易解决的问题。

你可能感兴趣的:(字符串,记录,元素,测量,指示器)