contextRefから日付情報を取得する【XBRL】

EDINET決算分析システム

XBRLの勘定科目タグには日付が設定されています。全上場企業・全期間の勘定科目の決算データベースを作るにあたって、この日付をもとに時系列を整理します。とても重要な情報です。その取得方法です。

contextタグの辞書を作る

勘定科目には「contextRef」という属性がありますが、それを「id」にして日付を定義しているのが「context」タグです。その中の「period」タグに日付が入っています。

 

日付は「startDate(開始日)」、「endDate(終了日)」、「instant(期末日)」というタグに入っています。

 

XBRLを読み込むときに、contextタグのid属性をキーにして日付の辞書を作っておけば、勘定科目を取得すると同時に日付も取得できます。そのプログラム例を示します。

 

XBRLクラスの作成と初期化

XBRLファイルを読み込むためのクラスを作ります。初期化の部分です。
ファイルの読み込み、名前空間の定義、contextのタグ名と属性名を定義します。

"""xbrl_jpcrp.py"""
from lxml.etree import fromstring as etree_fromstring
from collections import OrderedDict
class parser:
    def __init__(self, xbrl_file):
        # XMLファイルを読み込む
        self.xbrl_file = xbrl_file
        self.root = self.get_etree_obj_from_file(self.xbrl_file)

        # 名前空間取得
        self.nsmap = self.root.nsmap

        # 名前空間(ns:NameSpace)の接頭辞を定義
        self.pre_xbrli = 'xbrli'

        # タグ名/属性名定義 
        self.xbrli_context = '{%s}context' % self.nsmap[self.pre_xbrli]
        self.xbrli_period = '{%s}period' % self.nsmap[self.pre_xbrli]
        self.xbrli_start_date = '{%s}startDate' % self.nsmap[self.pre_xbrli]
        self.xbrli_end_date = '{%s}endDate' % self.nsmap[self.pre_xbrli]
        self.xbrli_instant = '{%s}instant' % self.nsmap[self.pre_xbrli]
        return

 

XBRLファイル読み込みメソッドを追加

lxml.etreeでXBRLのテキストを読み込む部分です。これは「xbrl」の他に「xsd」、「lab」などを読み込むのにも使えます。ファイルを決め打ちしないので、selfは不要です。なので、「@staticmethod」でデコレートしてます。

    @staticmethod
    def get_etree_obj_from_file(file):
        """XMLファイルを読み込む"""
        with open(file, 'rb') as f:
            return etree_fromstring(f.read())

 

contextタグ読み込みメソッドを追加

id属性をキーにして、periodタグとその下の日付タグの辞書を作るメソッドです。

    def get_context_tags(self):
        """contextタグ取得"""
        od = OrderedDict()
        for etree in self.root.findall('.//%s' % self.xbrli_context):
            # id属性の値を取得
            key_id = etree.get('id')

            # id属性をキーにして辞書を作成
            od.update({key_id:OrderedDict()})

            # periodタグ取得
            period = OrderedDict()
            et_period = etree.find('.//%s' % self.xbrli_period)
            
            # startDate, endDate, instantタグ取得
            period.update(self.get_date_tags(et_period))
            od[key_id].update({'period':period})
        return od

OrderedDict()を使うと、キーがXBRLファイルと同じ順番に並ぶので、何かとデバッグしやすいです。普通の辞書「{}とかdict()」でも動きます。

 

startDate・endDate・instantを読み込むメソッドを追加

開始日、終了日、期末日を読み込むメソッドです。

    def get_date_tags(self, etree):
        """日付タグ取得"""
        od = OrderedDict()

        # 開始日を検索
        et_start_date = etree.find('.//%s' % self.xbrli_start_date)
        if et_start_date is not None:
            # 開始日を追加
            od.update({'startDate':et_start_date.text})

            # 終了日を検索
            et_end_date = etree.find('.//%s' % self.xbrli_end_date)

            # 終了日を追加
            od.update({'endDate':et_end_date.text})
        else:
            # 期末日を検索
            et_instant = etree.find('.//%s' % self.xbrli_instant)

            # 期末日を追加
            od.update({'instant':et_instant.text})
        return od

これでcontextの辞書が作れますので、実際に使ってみます。

勘定科目のcontextRefから日付を取得する

先ほど作った「xbrl_jpcrp.py」をインポートしてXBRLファイルを読み込みます。
contextの辞書を取得して、勘定科目のcontextRefを入れます。
日付情報が取得できます。

import xbrl_jpcrp
def proc_xbrl(file):
    """XBRLからデータ取得"""
    # ファイル読み込み
    xbrl = xbrl_jpcrp.parser(file)

    # contextタグ取得
    # id属性(contextRef)をキーにして日付の辞書を作成
    context_tags = xbrl.get_context_tags()

    # 【データ取得例】
    # 名前空間(ns:NameSpace)から名前を取得します。
    namespace = xbrl.root.nsmap['jpcrp_cor']

    # タグ名の大文字小文字は保存されます。
    tag = 'NetSalesSummaryOfBusinessResults'

    # 属性名の大文字小文字も保存されます。
    attr = 'contextRef'
    value = 'CurrentYearDuration'

    # 検索(XPATHのように指定します)
    xpath = './/{%s}%s[@%s="%s"]' % (namespace, tag, attr, value)
    data = xbrl.root.find(xpath)

    # contextRef属性取得
    context_ref = data.get(attr)

    # contextタグから日付を取得
    date = context_tags[context_ref]['period']

    # 表示
    print('検索文字列: %s' % xpath)
    print('日付(開始日): %s' % date['startDate'])
    print('日付(終了日): %s' % date['endDate'])
    print('金額: {value:,} {unit}'.format(
        value=int(data.text), unit=data.get('unitRef')))
    return

 

表示例です。

検索文字列: .//{http://disclosure.edinet-fsa.go.jp/taxonomy/jpcrp/2017-02-28/jpcrp_cor}NetSalesSummaryOfBusinessResults[@contextRef=”CurrentYearDuration”]
日付(開始日): 2016-04-01
日付(終了日): 2017-03-31
金額: 11,720,041,000,000 JPY

以上です。

スポンサーリンク
シェアする(押すとSNS投稿用の『編集ページ』に移動します)
フォローする(RSSフィードに移動します)
スポンサーリンク
シラベルノート
タイトルとURLをコピーしました