部分问题在于您的 XML 示例不正确:尽管您正在使用名称空间,但您缺少名称空间声明,并且您缺少包含标签。第一个可以解决,但第二个需要对 XML 进行调整。
require 'nokogiri'
require 'pp'
xml = <<EOT
<xml xmlns:a="http://schemas.datacontract.org/2004/07/OpenAPI.Entity"> # <-- changed
<a:HBeat>
<a:ElapsedTime>3 ms</a:ElapsedTime>
<a:Name>Service 1</a:Name>
<a:Status>true</a:Status>
</a:HBeat>
<a:HBeat>
<a:ElapsedTime>4 ms</a:ElapsedTime>
<a:Name>Service 2</a:Name>
<a:Status>true</a:Status>
</a:HBeat>
<a:HBeat>
</xml>
EOT
doc = Nokogiri::XML(xml)
service_state = doc.css('a|Status').map(&:text) # <-- changed to show CSS with namespace
pp service_state
service_state = doc.search('//a:Status').map(&:text) # <-- added
pp service_state # <-- added
>> ruby test.rb
>> ["true", "true"]
>> ["true", "true"] # <-- added
命名空间是一件好事,但是当您只想获取数据时,处理它们可能会很痛苦。 Nokogiri 有一些技巧可以让它们不那么烦人,比如像我上面那样使用 CSS 访问器,这意味着“在所有命名空间中找到 Status 标记”,所以即使命名空间没有被声明它仍然是好的。
如果您可以控制 XML,那么您可以取消命名空间。它们在处理可能的标签冲突时很棒,但当您拥有生成文件的机制时,这不太可能,因此,如果是这种情况,您可能可以取消它们。如果你需要命名空间,那么它应该像这样声明:
<xml xmlns:a="http://schemas.datacontract.org/2004/07/OpenAPI.Entity">
没有它,XML 解析会出现很多命名空间错误:
(rdb:1) pp doc.errors
[#<Nokogiri::XML::SyntaxError: Namespace prefix a on HBeat is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on ElapsedTime is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on Name is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on Status is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on HBeat is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on ElapsedTime is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on Name is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on Status is not defined>,
#<Nokogiri::XML::SyntaxError: Namespace prefix a on HBeat is not defined>,
#<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: HBeat line 12 and xml>,
#<Nokogiri::XML::SyntaxError: Premature end of data in tag xml line 1>]
但添加后,文档的错误列表要小得多:
(rdb:1) pp doc.errors
[#<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: HBeat line 12 and xml>,
#<Nokogiri::XML::SyntaxError: Premature end of data in tag xml line 1>]
另见“How to avoid joining all text from Nodes when scraping”。