2013-03-26 65 views
0

我有很多獨特的XML事件,我已經轉換成大約300個密鑰的哈希。這些鍵中大多數的值都是哈希值,再次,其中一些鍵的值是哈希值。我不知道散列嵌套會走多深。紅寶石嵌套散列 - 確定單獨的事件

我想寫一個無模式數據庫的原始300的每個哈希值及其所有關鍵字&值(無論它有多少)。

我已經設法編寫一個(messy)方法來輸出每個Hash的值,而不管它的值可能包含多少個Hashes。

我現在面臨的問題是我無法確定一個哈希開始的位置,而一個哈希結束。因此,我無法將單獨的事件寫入數據庫,因爲我只剩下所有Hashes的輸出。

如何確定哪些是單獨的事件?

這裏是我的代碼:

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

轉換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>,您都可以剝離這些元素並在數據庫中的各個表中構建單獨的行。這真的取決於你的想法。

+0

謝謝! Nokogiri似乎是我已經擁有的更簡單的解決方案。我也想過剝離一些索引值(guid,event name,timestamp),把它們放到我的數據庫中,然後將我的散列轉換爲一個字符串並將整個字符串存儲在數據庫中。這使我可以在數據庫中搜索我需要的事件,並在嵌套散列的數據庫中擁有完整的事件。當我檢索它時,我只是將它轉換回散列。 – Michael 2013-04-08 01:24:29

+0

是的,提取字段並存儲那​​些有價值的字段,但不要麻煩序列化哈希並存儲它,因爲它基本上是浪費空間。搜索並將返回的記錄轉換回散列或散列數組很簡單。 – 2013-04-08 01:32:03