我有一个包含产品的巨大XML(> 400MB)。因此排除使用DOM解析器,因此我尝试使用pull解析器解析和处理它。以下是each_product(&block)
方法的片段,其中我遍历产品列表。
基本上,使用堆栈,我将每个<product> ... </product>
节点转换为散列并处理它。
while (reader.read)
case reader.node_type
#start element
when Nokogiri::XML::Node::ELEMENT_NODE
elem_name = reader.name.to_s
stack.push([elem_name, {}])
#text element
when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE
stack.last[1] = reader.value
#end element
when Nokogiri::XML::Node::ELEMENT_DECL
return if stack.empty?
elem = stack.pop
parent = stack.last
if parent.nil?
yield(elem[1])
elem = nil
next
end
key = elem[0]
parent_childs = parent[1]
# ...
parent_childs[key] = elem[1]
end
问题在于自动关闭标签(EG <country/>
),因为我无法区分“正常”标签和“自动关闭”标签。它们都是Nokogiri::XML::Node::ELEMENT_NODE
类型,我无法在documentation中找到任何其他鉴别器。
有关如何解决此问题的任何想法?
答案 0 :(得分:1)
项目页面上有关于此问题的feature request(使用相应的failing test)。
直到它被修复并推入当前版本,我们才会坚持使用good'ol
input_text.gsub! /<([^<>]+)\/>/, '<\1></\1>'
答案 1 :(得分:1)
P.S。 :我知道这是一篇旧帖子:P /文档是HERE