使用Nokogiri SAX解析器解析XML文件

时间:2014-11-10 15:40:50

标签: ruby arrays xml nokogiri saxparser

我已经完成了一些阅读,并且我一直在尝试从大型XML文件中获取某些数据。 数据如下所示:

<Provider ID="0042100323">
    <Last_Name>LastName</Last_Name>
    <First_Name>FirstName</First_Name>
    <Mdl_Name>Middle</Mdl_Name>
    <Gndr>M</Gndr>
</Provider>

我想写start_element将所有这些添加到记录数组中,如:

0042100323, LastName, FirstName, Middle, M

使用类似的东西:

def start_element name, attributes = []
    @@records << attributes[0][1] if name == "Provider"
end

如何更新我的代码以将其他标签添加到阵列?

3 个答案:

答案 0 :(得分:1)

使用characters事件获取标记内的文字:

def characters(string)
  @records << string
end
根据OP的评论

更新

根据包含标签选择性地抓取文本;记住上次看到的标签,只有在最后看到的标签符合您的要求时才抓取文字。

def start_element(name, attributes = [])
  @records << attributes[0][1] if name == "Provider"
  @last_seen_tag = name
end

def characters(string)
  if ['Last_Name', 'First_Name', 'Mdl_Name', 'Gndr'].include? @last_seen_tag
    @records << string
  end
end

def end_element name
  @last_seen_tag = nil
end

答案 1 :(得分:0)

您可以采取以下方法: -

require 'nokogiri'

@doc = Nokogiri::XML.parse <<-EOT
<Provider ID="0042100323">
    <Last_Name>LastName</Last_Name>
    <First_Name>FirstName</First_Name>
    <Mdl_Name>Middle</Mdl_Name>
    <Gndr>M</Gndr>
</Provider>
EOT

def start_element name, attributes = [], childs = []
  node = @doc.at("//*[local-name()='#{name}']")
  contents_of_childs = node.search("./child::*").each_with_object([]) do |n, a|
    a << n.text if childs.include?(n.name)
  end
  attributes.each_with_object([]) do |attr, a|
    a << node[attr] unless node[attr].nil?
  end + contents_of_childs
end

start_element('Provider', ['ID'], %w(Last_Name First_Name Mdl_Name Gndr))
# => ["0042100323", "LastName", "FirstName", "Middle", "M"]

答案 2 :(得分:-1)

变化为Arup的回答:

require 'nokogiri'

@doc = Nokogiri::XML.parse <<-EOT
<Provider ID="0042100323">
    <Last_Name>LastName</Last_Name>
    <First_Name>FirstName</First_Name>
    <Mdl_Name>Middle</Mdl_Name>
    <Gndr>M</Gndr>
</Provider>
EOT

(@doc.at("//Provider")["ID"] + @doc.text).split 
 #=> ["0042100323", "LastName", "FirstName", "Middle", "M"]