【问题标题】:Ruby Nested Hashes - Determining separate eventsRuby 嵌套哈希 - 确定单独的事件
【发布时间】:2013-03-26 00:11:52
【问题描述】:

我在 XML 中有许多独特的事件,我已将它们转换为大约 300 个键的大型哈希。大多数这些键的值是哈希值,其中一些键的值又是哈希值。我不知道哈希嵌套的深度。

我想将原始 300 的每个 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'])

【问题讨论】:

    标签: ruby windows events logging hash


    【解决方案1】:

    在处理复杂或大型数据文件时,将 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"}]}]
    

    您不必构建散列数组。对于每个&lt;Event&gt;,您可以剥离元素并在数据库的各个表中构建单独的行。这完全取决于您的想法。

    【讨论】:

    • 谢谢! Nokogiri 似乎是一个比我已经拥有的更容易的解决方案。我也有删除一些索引值(guid、事件名称、时间戳)的想法,将它们放入我的数据库中,然后将我的哈希转换为字符串并将整个字符串存储在数据库中。这使我可以在数据库中搜索我需要的事件,并在数据库中使用嵌套散列来保存完整的事件。我只是在检索它时将其转换回散列。
    • 是的,提取字段,并存储有价值的字段,但不要费心序列化哈希并存储它,因为这基本上是浪费空间。搜索返回的记录并将其转换回散列或散列数组很简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 2019-02-21
    • 2019-08-08
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多