0

XMLには、約300個のキーの大きなハッシュに変換した多くの固有のイベントがあります。これらのキーのほとんどの値はハッシュであり、これらのキーの一部の値もハッシュです。ハッシュの入れ子がどれだけ深くなるかわかりません。

元の300の各ハッシュとそのすべてのキーと値(いくつ持っていても)をスキーマのないデータベースに書き込みたいと思います。

値に含まれるハッシュの数に関係なく、各ハッシュの値を出力する(乱雑な)メソッドを作成することができました。

私が今直面している問題は、1つのハッシュがどこから始まり、1つのハッシュがどこで終わるかを判断できないことです。したがって、すべてのハッシュの出力が残っているため、データベースに個別のイベントを書き込むことができません。

どちらが個別のイベントであるかをどのように判断できますか?

これが私のコードです:

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'])
4

1 に答える 1

0

複雑なデータファイルや大きなデータファイルを扱う場合は、XMLをハッシュに変換することはお勧めできません。これは、XMLを検索する場合に比べて、ハッシュを歩くのはあまり便利ではないためです。XMLの解析は、 Nokogiriのような適切なツールを使用すると非常に簡単です。

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>、要素をはがし、データベース内のさまざまなテーブルに個別の行を作成できます。それは本当にあなたの頭の中で何がうまくいくか次第です。

于 2013-03-26T05:48:44.920 に答える