EDGAR XBRLを連続で読み込んだ時に、Memory allocation failed が発生するので、その原因を調べていました。
その結果、エラーの原因までは分からなかったのですが、XMLパーサーの引数に huge_tree=True を設定することでエラーが出なくなりましたので、一応の回避方法として紹介します。
まず、エラーを確認した時の記事がこちらです。
lxml.etree.XMLSyntaxError: Memory allocation failed
この Memory allocation failed というエラーですが、いったん発生すると、その後の etree.fromstring() が失敗し続ける状態になってしまったんですね。問題のある状態が継続してしまう感じです。
これを回避します。
以下のように、XMLパーサーの引数に huge_tree=True を設定して、そのパーサーを etree.fromstring() に渡してあげます。これで、今のところエラー無く読み込めています。
from lxml import etree
file = r'***\xxx-00000000.xml'
# ヒュージ・ツリーに「True」を設定して、XMLパーサーを生成。
parser = etree.XMLParser(huge_tree=True)
with open(file, 'rb') as f:
# 生成したXMLパーサーを渡して解析
root = etree.fromstring(f.read(), parser=parser)
公式マニュアルのページです。XMLパーサーと fromstring のページです。
lxml.etree.fromstring
fromstring(text, parser=None, base_url=None)
さて、このヒュージ・ツリー(huge_tree)ですが、これを設定すると、以下のヒュージ・テキスト・ノードというエラーも出なくなりました。
Traceback (most recent call last):
File "***\test_lxml_etree.py", line 49, in proc
root = etree.fromstring(f.read())
File "src\lxml\etree.pyx", line 3213, in lxml.etree.fromstring
File "src\lxml\parser.pxi", line 1877, in lxml.etree._parseMemoryDocument
File "src\lxml\parser.pxi", line 1765, in lxml.etree._parseDoc
File "src\lxml\parser.pxi", line 1127, in lxml.etree._BaseParser._parseDoc
File "src\lxml\parser.pxi", line 601, in lxml.etree._ParserContext._handleParseResultDoc
File "src\lxml\parser.pxi", line 711, in lxml.etree._handleParseResult
File "src\lxml\parser.pxi", line 640, in lxml.etree._raiseParseError
File "<string>", line 101992
lxml.etree.XMLSyntaxError: xmlSAX2Characters: huge text node, line 101992, column 216
このエラーは、メモリエラーの再現実験で、Memory allocation failed が発生する前に4回出ていたのですが、出なくなりました。なにやら今回のメモリエラーと関係がありそうですが、結局、良くわかりませんでした。
と言いますのも、実験中のログでは、このヒュージ・テキスト・ノードが最後に出てから、さらに4万ファイルを解析して、ようやく Memory allocation failed が出ていたんですね。ここまで離れてると、ちょっと判断しづらいです。
とりあえず、XMLパーサーの設定でこれらのエラーが回避できました。