image

  • フォト Amazonギフト券
    ※この時計の時刻は、閲覧しているパソコンのものであり、必ずしも正確な時間とは限りません

検索

最近のトラックバック

無料ブログはココログ

« 2009年1月9日 | トップページ | 2009年1月14日 »

2009年1月12日

2009-01-12

ピックアップ:高橋会長の『このコンピュータ書がすごい!2009年版』@ジュンク堂書店池袋店を生中継, インタラクティブな操作が可能なWikipedia, etc...

- http://hochi.yomiuri.co.jp/entertainment/news/20090112-OHT1T00203.htm
> 小倉キャスター降板も…朝青龍への発言で協会が抗議:芸能:スポーツ報知

- http://av.watch.impress.co.jp/docs/20090111/dg109.htm
> 西川善司の大画面☆マニア 第109回: 携帯やiPodにプロジェクタが内蔵される時代が来る!?

- http://fladdict.net/blog/2009/01/nazekyo-yu.html
> fladdict» ブログアーカイブ » 情報共有をしない奴は何故アホなのか?

- http://ameblo.jp/takapon-jp/entry-10191354040.html
> DMM vs SOD|六本木で働いていた元社長のアメブロ

- http://www.sodc.co.jp/special/sch/movie06.html
> 原紗央莉特設サイト: 動画ニュース第6回 2009.1.1 デビュー作PR、公開!

- http://d.hatena.ne.jp/conceal-rs/20090111/1231687469
> 新春座談会『このコンピュータ書がすごい! 2009年版』 - なんとなく日記

- http://d.hatena.ne.jp/onering/20090110/1231582043
> 高橋会長の『このコンピュータ書がすごい!2009年版』@ジュンク堂書店池袋店を生中継するよ!(→したよ!) - OneRingToFind by 榊祐介

- http://www.infoq.com/jp/news/2008/08/ruby-pdf-generation-prawn
> InfoQ: RubyのPDF生成、Prawnを使って簡単かつきれいに

- http://www.100shiki.com/archives/2009/01/wikipediavisual_wikipedia.html
> インタラクティブな操作が可能なWikipedia『Visual Wikipedia』 | 100SHIKI.COM

- http://d.hatena.ne.jp/higayasuo/20090111/1231647504
> 2009年SI企業の不況の乗り切り方 - ひがやすを blog

XBRL ファイルの リンクをたどる

libxml-ruby を使って、XBRL データを読み込む事にした。
(REXML は動作が遅いらしいので)

以前に、XBRLインスタンスファイルを指定すると、
そこからの参照ファイルの Tree 状態をコンソールに表示するものを作った。

今回、REXML -> libxml に書き換えてみた。
(実は 以前のプログラムでは、参照をすべて辿れていなかったことも気がついた)

$ cat filetree.rb

# 2009-01-10 katoy
#   Show imported tree list for XBRL-instnce data.

require 'rubygems'
require 'xml/libxml'
require 'open-uri'
require 'pathname'
require 'pp'
require 'yaml'
require 'benchmark'

class FileTree
  YAML_NAME = 'links.yaml'

  attr_reader :links    # from_url => [to_url, ...] のハッシュ

  def initialize
    @links = { }
#   if File.exist?(YAML_NAME)
#     @links = YAML.load_file(YAML_NAME)
#   end
  end

#  def save_links
#    @links.reject!{ |k, v| k.index("http") != 0 }
#    File.open( YAML_NAME, 'w' ) do |f|
#      YAML.dump( @links, f )
#    end
#  end

  def generate(path, dir = '')
    from_path = Utils::normalize_path(path, dir)
    parent = Utils::parent(from_path)

    if @links[from_path] != nil
      puts "------- skip #{from_path}"
      return
    end

    reader = nil

    begin
      reader = XML::Reader.file(from_path)
      while 1 == reader.read
        href = nil
        name = "#{reader.namespace_uri}:#{reader.local_name}"
        case name
        when 'http://www.w3.org/2001/XMLSchema:import'
          href = reader['schemaLocation']
        when 'http://www.xbrl.org/2003/linkbase:schemaRef'
          href = reader['xlink:href']
        when 'http://www.xbrl.org/2003/linkbase:linkbaseRef'
          href = reader['xlink:href']
        end

        if href != nil
          to_path = Utils::normalize_path(href, parent)
          generate(to_path, parent)
          @links[from_path] = [] if @links[from_path] == nil
          @links[from_path] << to_path
        end
      end
    rescue
      puts "---- error reading #{to_path}"
    ensure
      reader.close if reader != nil
    end
  end

  def print_tree(path, indent=0)

    return if @links[path] == nil
    @links[path].each do |f|
      puts "#{' ' * (4*indent)}#{f}"
      print_tree(f, indent + 1)
    end
  end

end

class Utils
  def self.cleanpath(path)
    Pathname.new(path).to_s
  end

  def self.parent(full_path)
    p = full_path.rindex('/') - 1
    full_path[0..p]
  end

  def self.normalize_path(path, dir='')

    if path.index('http://') == 0
      uri = URI.parse(path)
      full_path = "#{uri.scheme}://#{uri.host}#{Utils::cleanpath(uri.path.to_s)}"
    elsif dir.index('http://') == 0
      uri = URI.parse("#{dir}/#{path}")
      full_path = "#{uri.scheme}://#{uri.host}#{Utils::cleanpath(uri.path.to_s)}"
    else
      path = path[5.. path.length] if path.index('file:') == 0
      dir = File::expand_path('.') if dir == ''
      full_path = Utils::cleanpath(File::expand_path(path, dir))
    end

    full_path
  end
end

# See http://www.sec.gov
# SEC - adobe
# pat = "http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml"
# SEC - microsoft
# pat = "http://www.sec.gov/Archives/edgar/data/789019/000119312508215214/msft-20080930.xml"

# pat = "397-00-ConsistentInstance-valid.xbrl"
# pat = "file:/Users/youichikato/work/www/xbrl.org/XBRL-CONF/Common/instance/397-00-ConsistentInstance-valid.xbrl"
# pat = "/Users/youichikato/work/www/xbrl.org/XBRL-CONF/**/*.xbrl"
# pat = "/Users/youichikato/NetBeansProjects/ruby-xbrl/Edinet/sample/**/*.xbrl"
pat = ARGV[0]

  puts Benchmark.measure {
  ftree = FileTree.new

  if pat.index('http:') == 0
    full_path = Utils::normalize_path(pat)
    ftree.generate(full_path)
    ftree.print_tree(full_path)
  else
    Dir.glob(pat).each do |f|
      full_path = Utils::normalize_path(f)
      ftree.generate(full_path)
      ftree.print_tree(full_path)
    end
  end
#  ftree.save_links
}

$ ruby filetree.rb http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml
     ... 省略
http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829.xsd
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_pre.xml
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_cal.xml
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_def.xml
    http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080829_lab.xml
     ... 省略
                            http://www.xbrl.org/2003/xl-2003-12-31.xsd
                                http://www.xbrl.org/2003/xlink-2003-12-31.xsd
                            http://www.xbrl.org/2003/xlink-2003-12-31.xsd
  4.520000   0.900000   5.420000 (371.585711)

最後の行は benchmak ライブラリーのよるものだ。ここでは 370 秒かかったことがしめされている。

参照ファイルの数(重複も)が多いことが分かる。( Tree 表示の行数は3000 行ほどになる)
また、この処理時間の遅さは、ほとんど ネットアクセスによるものとおもわれる。
(一度 読み込みをしたファイルは、再度 読み込まない工夫はしてあるが)

実用的なものにするには、次のような工夫をすることが考えられる。
  1. ネット経由でアクセスしたファイルは、キャッシュフォルダーの保持し、次回からはキャッシュしたファイルへアクセスする。
     (ブラウザのキャッシュフォルダと同じ考え)
  2. ネット上ファイルの内容は基本的に変化しないはずなので、 ファイル上ファイルについての 解析した参照情報は
     永続化保持して、再利用するようにする。

ここでは、2 番の方法を実装してみよう。

つまり @links を yaml で保持する。
ソースコード中の
   initialize の変更と
   ファイルの最後の save 呼び出し
を追加するだけだ。
# 実は上で示したコードでは、その部分はコメントにしてあった。
この変更を加えると 一回目の実行は遅いが、2回目はもちろん 劇的に速くなる。

$  ruby filetree.rb http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml
     ... 省略
  4.810000   0.950000   5.760000 (382.223170)
$  ruby filetree.rb http://www.sec.gov/Archives/edgar/data/796343/000079634308000007/adbe-20080916.xml
     ... 省略
  0.050000   0.020000   0.070000 (  0.109030)

ここでは、File からの import 情報だけを永続化して再利用したが、
XBRL の他の情報も同様の方法で永続化することも可能だろう。

XBRL データの処理の関門はいくつかある。
1. ファイルの参照を辿らないと完全な情報を得ることができない。
2. xlink, Xpointer を処理する必要がある。

でも、すべての情報を得る必要がないケースもある。
( (科目ID, コンテキスト、値) の組を得るだけなら、インスタンスファイルだけの処理で十分だ)

#インスアンスファイルを libxml をつかって処理する例は、作成済み。
# 数日中に 別途 投稿する予定である。

ファイル参照をすべて辿るのは、基本的には上に示した方法 (130 行程度) で可能なことがわかった。
次は、Xlinkm Xpointer をつかっている 各種のリンクベースファイルを処理することを行おう。

« 2009年1月9日 | トップページ | 2009年1月14日 »

mokuji

2013年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

google

  • twitter
  • __
  • _
    Googleボットチェッカー

合わせて読む

  • 合わせて読む
    フィードメーター - katoy: cocolog あわせて読みたい

リンク