我在整理从SEC's edgar database返回的格式错误的xml代码时遇到问题。
出于某种原因,它们有可怕的xml格式。包含任何类型字符串的标记不会关闭,它实际上可以在其他标记中包含其他XML或HTML文档。正常情况下,我会把这个关在Tidy上,但这并没有得到维护。
我试过使用nokogiri::xml::sax::parser,但这似乎让人窒息,因为标记没有关闭。它似乎工作得很好,直到它击中第一个结束标记,然后它不再对他们开火。但它吐出了正确的角色。
class Filing < Nokogiri::XML::SAX::Document
def start_element name, attrs = []
puts "starting: #{name}"
end
def characters str
puts "chars: #{str}"
end
def end_element name
puts "ending: #{name}"
end
end
这似乎是最好的选择,因为我可以让它忽略其他xml或html文档。另外,这将是最有意义的,因为其中一些文档可能会变得很大,因此将整个dom存储在内存中可能行不通。
以下是一些示例文件:123
我开始认为我只需要编写自己的自定义解析器
最佳答案
nokogiri的正常dom模式能够自动修复xml,因此它在语法上是正确的,或者是它的合理传真。它有时会混淆并移动结束标记,但如果需要的话,可以对文件进行预处理,使其朝正确的方向移动。
我将xml 1保存到一个文档中并加载它:
require 'nokogiri'
doc = ''
File.open('./test.xml') do |fi|
doc = Nokogiri::XML(fi)
end
puts doc.to_xml
在解析之后,您可以检查nokogiri::xml::document实例的
errors
方法,查看生成了哪些错误,以获得不正当的乐趣。doc.errors
如果使用nokogiri的dom模型还不够好,您是否考虑过使用XMLLint来预处理和清理数据,发出干净的xml以便sax工作?它的
--recover
选项可能有用。xmllint --recover test.xml
它将在stderr上输出错误,并在stdout上输出代码,因此您可以轻松地将其管道化到另一个文件。
至于编写自己的解析器…为什么?你还有其他的选择,重新设计一个实现良好的轮子并不是一个很好的时间利用。