我有一个相当大的XML文档,我想从中获取一些信息。它太大而无法保存在内存中,因此我认为SAX解析器是合适的。
不幸的是,制作XML文档的人没有仔细阅读规范,因此它包含一些非法的XML实体(如
)。除此之外,据我所知,它是好的。
对于任何依赖libxml的库,errors like these will disable future SAX processing unless they are run in recovery mode
/*
* [ WFC: Legal Character ]
* Characters referred to using character references must match the
* production for Char.
*/
if (IS_CHAR(val)) {
return(val);
} else {
ctxt->errNo = XML_ERR_INVALID_CHAR;
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"xmlParseCharRef: invalid xmlChar value %d\n",
val);
ctxt->wellFormed = 0;
if (ctxt->recovery == 0) ctxt->disableSAX = 1;
}
return(0);
但是,LibXML::XML::SaxParser
和Nokogiri::XML::SAX
似乎都是硬编码为而不是在恢复模式下运行,所以一旦遇到非法实体,解析几乎停止(前者抛出一个错误,而后者只是停止显示元素的开始/结束)。
有没有办法在恢复模式下运行其中一个(或另一个SAX解析器)?
答案 0 :(得分:1)
好吧,我找到了一个我不喜欢的解决方案。使用Inline::C
,我可以在运行时为recovery
包裹的xmlParserCtxt
的{{1}}值创建一个访问者。
Nokogiri::XML::SAX::ParserContext