跳至内容

XQuery/文件大小直方图

来自维基教科书,开放世界中的开放书籍

您在一个或多个集合中拥有大量文件,您希望生成一个直方图图表,显示每个大小范围内的文件数量的相对分布。

我们将使用 xmldb:size() 函数来生成给定集合中所有文件大小的列表。然后,我们可以将此列表转换为一系列字符串,这些字符串可以传递到 Google Charts 线形图函数。

size 函数的格式如下

 xmldb:size($collection, $document-name)

此函数返回文件中的字节数。


我们的第一步是创建一个数字序列,代表集合中所有资源的大小

 let $sizes :=
  for $file in xmldb:get-child-resources($collection)
     let $size := xmldb:size($collection, $file)
     return
        $size

这也可以通过组合 collection() 函数和 util:document-name() 函数来完成

  let $sizes :=
     for $file in collection($collection)/*
        let $name := util:document-name($file)
        let $size := xmldb:size($collection, $name)
        return
           $size

示例程序

[编辑 | 编辑源代码]
xquery version "1.0";

declare option exist:serialize "method=xhtml media-type=text/html";

(: Put the collection you want to analyze here :)
let $collection := "/db/test"

(: How many bytes in each section :)
let $increment := 10000

(: How many divisions :)
let $divisions := 20

(: Color for the lines or the bars in RRGGBB :)
let $color := '0000FF'

(: For vertical bar chart use 'bvs', for line chart use 'lc', for spark line (no axis) use 'ls' :)
let $chart-type := 'bvs'

(: this is the max size of a google chart - 30K pixels.  The first number is the width, the second is the height.  :)
let $chart-size := '600x500'

let $uriapi := 'http://chart.apis.google.com/chart?'

let $sizes :=
   for $file in xmldb:get-child-resources($collection)
      let $size := xmldb:size($collection, $file)
      return
         $size

(: the raw data counts for each range.  The 't' is just a marker that it is true that we are in this range. :)
let $raw-data :=
    for $range in (0 to $divisions)
       let $min := $range * $increment
       let $max := ($range + 1) * $increment
       return
          count(
               for $number in $sizes
               return
                 if ($number gt $min and $number lt $max)
                 then ('t') else ()
              )

let $max-value := max($raw-data)

(: scale to the max height :)
let $scaled-data := 
   for $num in $raw-data
   return string(floor($num div ($max-value div 500)))

(: join the strings with commas to get a comma separated list :)
let $data-csv := string-join($scaled-data, ',')

(: construct the URL :)
let $chart-uri := concat($uriapi, 'cht=', $chart-type, '&chs=', $chart-size, '&chco=', $color, '&chd=t:', $data-csv)

(: return the results in an HTML page :)
<html>
<head><title>Google Chart Histogram View of {$collection}</title></head>
<body>
<h1>Google Chart Histogram View of {$collection}</h1>
<p><img src="{request:encode-url(xs:anyURI($chart-uri))}"/></p>
</body>
</html>

示例结果

[编辑 | 编辑源代码]

http://chart.apis.google.com/chart?cht=ls&chs=500x500&chco=0000FF&chd=t:83,6,13,37,85,414,500,87,41,31,11,16,9,12,5,7,4,4,3,1,1

要运行查询,您需要自定义要分析的集合的名称。运行查询后,您可以检查结果是否符合预期,然后将结果复制到浏览器 URL 中。

请注意,如果存在超过最高范围内指示的最大大小的文件,则应添加这些文件大小的额外计数。

 let $top-range := $increment * ($divisions + 1)
 let $top-count := count(
           for $num in $sizes
           return
              if ($num > $overflow)
                then ('t')
                else ()
       )

此查询也可以使用 get-parameter() 函数进行参数化,以便传递到 Google 图表的许多参数也可以在 URL 的 XQuery 中作为参数设置。

华夏公益教科书