EDINET・TDnet to 財務が見え~るのまとめで述べたように、日本基準の場合 EDINETで規定した勘定科目コード表を精査し、財務が見え~るの科目への対応付けを行えば、十分な精度で自動的に変換できることが分かった。
それに対し、IFRS基準または米国基準の場合 採用している科目名 および htmlの編集方法が統一されておらず、現状では人的介入は避けられない。
調査の結果、既に目的の企業名・EDINET コード・会計基準等は、EDINET開示情報の表紙に記載されていることが分かっている。
以下、EDINETで開示されている年間の有価証券報告書の表紙の情報から、企業名・EDINET コード・会計基準等の一覧を求めた方法と結果を示す。
- 年間の有価証券報告書をEDINETから求める
http://resource.ufocatch.com/atom/edinetx/query/ で有報キャッチャーにアクセスし、 linkタグのrelationshipType=”next”となっている URLをたぐることで 開示データが順次取得できる。
今回は、年間の有価証券報告書のデータを拾うため以下の条件を満たすデータを処理対象とした。
- 2016年1月1日以降開示
- タイトル中のEDINETコードの上1桁が E(一般の企業?)
- タイトルの報告書名が 有価証券報告書
有報キャッチャーにアクセスした例
<feed xmlns="http://www.w3.org/2005/Atom"> <title>有報キャッチャー - EDINET情報配信サービス</title> <link href="http://resource.ufocatch.com/"/> <updated>2017-02-21T02:06:01Z</updated> <id>http://resource.ufocatch.com/atom/edinetx/1</id> <link rel="self" href="http://resource.ufocatch.com/atom/edinetx/1"/> <link rel="first" href="http://resource.ufocatch.com/atom/edinetx/1"/> <link rel="last" href="http://resource.ufocatch.com/atom/edinetx/696"/> <link rel="next" href="http://resource.ufocatch.com/atom/edinetx/2"/> <entry> <title> 【G03769】ソシエテジェネラルアセットマネジメント株式会社 有価証券報告書(内国投資信託受益証券)-第13期(平成27年11月21日-平成28年11月21日) </title> <link rel="alternate" type="application/pdf" href="http://resource.ufocatch.com/pdf/edinet/ED2017022100001"/> <id>ED2017022100001</id> <docid>S1009FZQ</docid> <updated>2017-02-21T00:00:00+09:00</updated> <link rel="related" type="application/zip" href="http://resource.ufocatch.com/data/edinet/ED2017022100001"/>
メイン
class Program { //解析結果(CSV)出力用にwriterを準備する static Encoding sjisEnc; static StreamWriter writer; static void Main(string[] args) { sjisEnc = Encoding.GetEncoding("Shift_JIS"); writer = new StreamWriter(@"C:\Temp\DEI.txt", false, sjisEnc); DateTime min_dt = DateTime.Parse("2016/01/01"); // 開示日の最小値 XmlReader rdr = null; string url = @"http://resource.ufocatch.com/atom/edinetx/query/"; while (url != "") { rdr = XmlReader.Create(url); SyndicationFeed feed = SyndicationFeed.Load(rdr); string nextUrl = ""; for (int i = 1; i < feed.Links.Count; i++) { if (feed.Links[i].RelationshipType == "next") nextUrl = @"http://resource.ufocatch.com" + feed.Links[i].Uri.AbsolutePath; } foreach (SyndicationItem item in feed.Items) { DateTime dtekaijibi = DateTime.Parse(item.LastUpdatedTime.ToString()); if (dtekaijibi < min_dt) { nextUrl = ""; break; } string title = item.Title.Text; // 一般企業の有価証券報告書だけ選択 if (title.IndexOf("【E") > -1 && title.IndexOf("有価証券報告書") > -1 && title.IndexOf("訂正有価証券報告書") == -1) { for (int i = 1; i < item.Links.Count; i++) { if (item.Links[i].Uri.AbsolutePath.IndexOf(@"PublicDoc/0000000_header") > 0) { // 表紙のurl string szUrl = "http://resource.ufocatch.com" + item.Links[i].Uri.AbsolutePath; // 表紙のソースを取得 string szHtml = getHtmlstring(szUrl); // html解析 ここで目的の項目を取得する analyzHtmlDocument(szHtml); } } } } url = nextUrl; } writer.Close(); }
- 表紙のurlから、htmlソースを取得する
static string getHtmlstring(string szUrl) { WebClient wc = new WebClient(); Encoding enc = Encoding.GetEncoding("Shift_JIS"); Stream st = wc.OpenRead(szUrl); StreamReader sr = new StreamReader(st, enc); string sz = sr.ReadToEnd(); sr.Close(); st.Close(); return sz; }
- 表紙のhtmlソースを解析し、目的の項目を取得する
HtmlAgilityPackを用いてタクソノミ要素リストに示す要素コードに従い、目的の項目の値を取得し、コンソー表示およびCSV出力を行う。
なお要素コードは、
<ix:nonNumeric contextRef="FilingDateInstant" name="jpcrp_cor:CompanyNameCoverPage">富士重工業株式会社</ix:nonNumeric>
のように、名前空間 ix 付のタグ内に記述されており、 NameSpace Manager の指定が必要な形式になっている。NameSpace の指定をしないまま ノード検索を行うと 当然 エラーになる。
HtmlAgilityPackには、XmlNamespaceManagerクラスのようにNamespaceの追加機能はない。ここを参考に、Linqを併用してノード検索を行った。
static void analyzHtmlDocument(string szHtml) { // HtmlDocumentオブジェクトを構築する HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument(); htmlDoc.OptionAutoCloseOnEnd = false; //最後に自動で閉じる(?) htmlDoc.OptionCheckSyntax = false; //文法チェック。 htmlDoc.OptionFixNestedTags = true; //閉じタグが欠如している場合の処理 htmlDoc.LoadHtml(szHtml); string szName = getValueByCode(htmlDoc, "jpcrp_cor:CompanyNameCoverPage"); string EDIcode = getValueByCode(htmlDoc, "jpdei_cor:EDINETCodeDEI"); string SECcode = getValueByCode(htmlDoc, "jpdei_cor:SecurityCodeDEI"); string szAccStd = getValueByCode(htmlDoc, "jpdei_cor:AccountingStandardsDEI"); string szConsolidated = getValueByCode(htmlDoc, "jpdei_cor:WhetherConsolidatedFinancialStatementsArePreparedDEI"); Console.WriteLine("name: {0} EDI: {1} SEC: {2} ACC {3} Con {4}", szName, EDIcode, SECcode, szAccStd, szConsolidated); writer.WriteLine("{0},{1},{2},{3},{4}", szName, EDIcode, SECcode, szAccStd, szConsolidated); } static string getValueByCode(HtmlAgilityPack.HtmlDocument htmlDoc, string szCode) { var ixNodes = htmlDoc.DocumentNode.Descendants().Where(n => n.Name.StartsWith("ix:nonnumeric") && n.Attributes["name"].Value == szCode); foreach (var ixNode in ixNodes) { return (ixNode.InnerText); } return null; }
- 処理結果
上記プログラムを実行し、CSVをEXcelにした結果をここに示す。その結果 4100件中 IFRSが87件(2.1%) 米国基準が22件(0.05%)と圧倒的に日本基準が多いことが分かった。