我在XML中有许多独特的事件,我已经将其转换为大约300个密钥的大哈希。大多数这些键的值都是哈希值,而且其中一些键的值又是哈希值。我不知道散列嵌套会有多深。
我想写原始300的每个Hash及其所有键和&无模式数据库的值(无论它有多少)。
我设法写了一个(杂乱的)方法,输出每个Hash的值,无论它的值包含多少哈希值。
我现在面临的问题是我无法确定一个哈希开始的位置,一个哈希结束。因此,我无法将单独的事件写入数据库,因为我只剩下所有哈希的输出。
如何确定哪些是单独的事件?
这是我的代码:
require 'crack'
require 'awesome_print'
def printingOutHash(inputHash)
#ap inputHash
if inputHash.kind_of?(Array)
puts "array"
inputHash.each do |x|
printingOutHash(x)
end
end
if inputHash.kind_of?(Hash)
inputHash.each do |k, v|
if v.kind_of?(Hash)
printingOutHash(v)
else
ap "#{k}: #{v}"
end
end
end
end
h = Crack::XML.parse("<Events><Event><System><Provider Name='Service Control Manager' Guid='{555908d1-a6d7-4695-8e1e-26931d2012f4}' EventSourceName='Service Control Manager'/><EventID Qualifiers='16384'>7036</EventID><Version>0</Version><Level>4</Level><Task>0</Task><Opcode>0</Opcode><Keywords>0x8080000000000000</Keywords><TimeCreated SystemTime='2013-03-25T05:00:38.021800000Z'/><EventRecordID>17629</EventRecordID><Correlation/><Execution ProcessID='476' ThreadID='3028'/><Channel>System</Channel><Computer>AMAZONA-ONIST5V</Computer><Security/></System><EventData><Data Name='param1'>Windows Modules Installer</Data><Data Name='param2'>stopped</Data><Binary>540072007500730074006500640049006E007300740061006C006C00650072002F0031000000</Binary></EventData></Event><Event><System><Provider Name='Service Control Manager' Guid='{555908d1-a6d7-4695-8e1e-26931d2012f4}' EventSourceName='Service Control Manager'/><EventID Qualifiers='16384'>7040</EventID><Version>0</Version><Level>4</Level><Task>0</Task><Opcode>0</Opcode><Keywords>0x8080000000000000</Keywords><TimeCreated SystemTime='2013-03-25T05:00:37.741000000Z'/><EventRecordID>17628</EventRecordID><Correlation/><Execution ProcessID='476' ThreadID='3028'/><Channel>System</Channel><Computer>AMAZONA-ONIST5V</Computer><Security UserID='S-1-5-18'/></System><EventData><Data Name='param1'>Windows Modules Installer</Data><Data Name='param2'>auto start</Data><Data Name='param3'>demand start</Data><Data Name='param4'>TrustedInstaller</Data></EventData></Event></Events>")
printingOutHash(h['Events']['Event'])
答案 0 :(得分:0)
当您处理复杂或大型数据文件时,将XML转换为哈希值不是一个好主意,因为与搜索XML相比,遍历哈希不是很方便。使用Nokogiri等正确的工具解析XML非常简单。
基于XML:
require 'nokogiri'
xml = "
<Events>
<Event>
<System>
<Provider Name='Service Control Manager' Guid='{555908d1-a6d7-4695-8e1e-26931d2012f4}' EventSourceName='Service Control Manager'/>
<EventID Qualifiers='16384'>7036</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8080000000000000</Keywords>
<TimeCreated SystemTime='2013-03-25T05:00:38.021800000Z'/>
<EventRecordID>17629</EventRecordID>
<Correlation/>
<Execution ProcessID='476' ThreadID='3028'/>
<Channel>System</Channel>
<Computer>AMAZONA-ONIST5V</Computer>
<Security/>
</System>
<EventData>
<Data Name='param1'>Windows Modules Installer</Data>
<Data Name='param2'>stopped</Data>
<Binary>540072007500730074006500640049006E007300740061006C006C00650072002F0031000000</Binary>
</EventData>
</Event>
<Event>
<System>
<Provider Name='Service Control Manager' Guid='{555908d1-a6d7-4695-8e1e-26931d2012f4}' EventSourceName='Service Control Manager'/>
<EventID Qualifiers='16384'>7040</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8080000000000000</Keywords>
<TimeCreated SystemTime='2013-03-25T05:00:37.741000000Z'/>
<EventRecordID>17628</EventRecordID>
<Correlation/>
<Execution ProcessID='476' ThreadID='3028'/>
<Channel>System</Channel>
<Computer>AMAZONA-ONIST5V</Computer>
<Security UserID='S-1-5-18'/>
</System>
<EventData>
<Data Name='param1'>Windows Modules Installer</Data>
<Data Name='param2'>auto start</Data>
<Data Name='param3'>demand start</Data>
<Data Name='param4'>TrustedInstaller</Data>
</EventData>
</Event>
</Events>"
以下是我如何获取数据的开始:
doc = Nokogiri::XML(xml)
pp doc.search('Event').map { |event|
system_provider_node = event.at('System Provider')
system = {
provider: {
name: system_provider_node['Name'],
guid: system_provider_node['Guid'],
event_source_name: system_provider_node['EventSourceName']
}
}
event_data = event.search('EventData Data').map{ |data|
{
name: data['Name'],
text: data.text
}
}
{
system: system,
event_data: event_data
}
}
结果是:
[{:system=>
{:provider=>
{:name=>"Service Control Manager",
:guid=>"{555908d1-a6d7-4695-8e1e-26931d2012f4}",
:event_source_name=>"Service Control Manager"}},
:event_data=>
[{:name=>"param1", :text=>"Windows Modules Installer"},
{:name=>"param2", :text=>"stopped"}]},
{:system=>
{:provider=>
{:name=>"Service Control Manager",
:guid=>"{555908d1-a6d7-4695-8e1e-26931d2012f4}",
:event_source_name=>"Service Control Manager"}},
:event_data=>
[{:name=>"param1", :text=>"Windows Modules Installer"},
{:name=>"param2", :text=>"auto start"},
{:name=>"param3", :text=>"demand start"},
{:name=>"param4", :text=>"TrustedInstaller"}]}]
您不必构建哈希数组。对于每个<Event>
,您可以剥离元素并在数据库的各个表中构建单独的行。这真的取决于你的想法。