13.4.1 读取值

13.4.1 读取值

我们首先要做的是从 XML 中读取感兴趣的数据。定义一个函数,参数为 XDocument 对象的列表(对应于数据集的每个页面),返回序列类型,每个元素包含了指标、 地区名,以及观测的年份。
清单 13.14 展示了 readValues 函数,以及辅助函数,从表示一条记录的 XML 节点中读数据,两个函数一个名为 parse 的参数,是真正解析字符串值的函数,我们很快就会知道使用这个参数背后的原因。

清单13.14 从XML 数据中读数据 (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 []                 | [1] 返回的列表,可能
  else [ (year,country),parse(value) ]    | 有 01 个元素

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"); 
      ...]

可以发现,这与我们想要的很接近了,现在可以直接从序列中读出数据了,剩下唯一的不足就是,value 明显是数字,但却当作字符串看待了。不过,这很容易解决

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念