gpt4 book ai didi

ruby - Nokogiri SAX 忽略空字符

转载 作者:太空宇宙 更新时间:2023-11-03 16:12:48 25 4
gpt4 key购买 nike

我正在尝试使用 sax 解析器解析大型 xml 文件。当解析器到达一个空节点时,字符方法不会触发。这是一个例子...

require 'nokogiri'

class Parser < Nokogiri::XML::SAX::Document
def initialize
@count=1
end
def start_element(name, attrs = [])
puts name
end
def characters(string)
string.strip!
puts "#{@count} #{string}"
@count += 1
end
def end_element(name)
puts name
end
end

Nokogiri::XML::SAX::Parser.new(Parser.new).parse(File.open('sax_example3.xml'))

这是示例 xml 文档。

<?xml version="1.0" encoding="UTF-8"?>
<root>
<ISA type="array">
<ISA>
<I02>
<name>Information1</name>
<value>
<raw>00</raw>
<description></description>
</value>
</I02>
<I02>
<name>Information2</name>
<value>
<raw></raw>
<description nil="true"/>
</value>
</I02>
</ISA>
</ISA>
</root>

我不得不使用 sax,因为该文件有大约 650 万行

我想做的是将所有 name 值和 raw 值收集到单独的数组中,稍后我可以压缩这两个数组以获得键值对。

我的处理方式是否正确?还有其他方法吗?

编辑:

我所期望的

array1 = ["Information1","Information2"]  
array2 = ["00", ""]

所有 name 值都分配给 array1,raw 值分配给 array2,如上所示。

我得到了什么

array1 = ["Information1","Information2"]  
array2 = ["00"]

array2 没有与 array1 相同数量的元素,这意味着无法将名称映射到数组。我认为这是因为如果节点为空,则不会调用 characters 方法。

这是上面程序的输出(编辑了上面的脚本并添加了行号)

root           
1
ISA
2
ISA
3
I02
4
name
5 Information1
name
6
value
7
raw
8 00
raw
9
description
description
10
value
11
I02
12
I02
13
name
14 Information2
name
15
value
16
raw
raw
17
description
description
18
value
19
I02
20
ISA
21
ISA
22
root

如您所见,在第 (9 & 10)、(16 & 17) 和 (17 & 18) 行之间,执行了 start_elementend_element 方法,但是characters 方法不是。

最佳答案

characters可能不会被调用,您需要注意 <name><raw>元素本身。如果我们可以假设 <name><raw>总是成对出现并且按照这个顺序,我们可以在每次遇到前者时创建一个新的“空”对(例如 { name: nil, raw: nil } ),然后在(如果) characters 时填写值被称为:

class Parser < Nokogiri::XML::SAX::Document
def initialize(*args)
@vals = []
@current_el = nil
super
end

def start_element(el_name, attrs = [])
if el_name == "name"
@vals << { name: nil, raw: nil }
@current_el = "name"
elsif el_name == "raw"
@current_el = "raw"
else
@current_el = nil
end
end

def end_element(el_name)
if el_name == "name" || el_name == "raw"
@current_el = nil
end
end

def characters(str)
str = str.strip
if @current_el == "name"
@vals.last[:name] = str
elsif @current_el == "raw"
@vals.last[:raw] = str
end
end

def end_document
pp @vals
end
end

您可以在 repl.it 上看到它的实际效果(但请注意,第一次运行需要很长时间,因为 Nokogiri):https://repl.it/@jrunning/SpitefulRichLists

关于ruby - Nokogiri SAX 忽略空字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56735220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com