我一直在搜索和搜索有关如何执行此操作的几天,但我似乎无法理解sax解析,这将有助于我完成我想要完成的任务。我理解基本级别的sax解析,但我不能理解如何使用它来提取我需要提取的数据。
我目前正在使用:
这是xml结构的一个示例:
<result created="2015-08-26T09:42:35-05:00" host="testdata" status="
<items>
<client>
<clientid>00001</clientid>
<name>
<![CDATA[ ABC Company ]]>
</name>
<site>
<siteid>222222</siteid>
<name>
<![CDATA[ 123 Blvd ]]>
</name>
<workstations/>
<servers>
<server>
<id>333333</id>
<name>
<![CDATA[ 123BLVD-SRV ]]>
</name>
<failed_checks>
<check>
<checkid>4444444</checkid>
<check_type>0001</check_type>
<description>
<![CDATA[Critical Events Check - Application log]]>
</description>
<dsc_247>2</dsc_247>
<date>2015-08-26</date>
<time>06:03:44</time>
<consecutive_fails>2</consecutive_fails>
<startdate>2015-08-25</startdate>
<starttime>10:43:51</starttime>
<formatted_output>
<![CDATA[Event log issues[CLIENT:]]>
</formatted_output>
<checkstatus>
<![CDATA[ Status ]]>
</checkstatus>
</check>
</failed_checks>
</server>
</servers>
</site>
</client>
我尝试提取的是一系列客户端。每个客户端都有一个名称,一个clientid,一组工作站(及其属性),以及一组服务器(及其属性)。像这样:
clients_array = [
{
:name => 'ABC Company',
:clientid => '00001',
:workstations => [
{
:name => 'hostname',
:id => '00002',
:failed_checks => [
{
:description => 'description', :cause => 'cause'
}
]
},
{
:name => 'hostname2',
:id => '00003',
...
}
]
},
{
:name => 'Second Company',
:clientid => '...',
...
}
]
我遇到的问题是我可以很容易地提取客户端节点的信息,但是很难提取每个客户端节点的工作站和服务器信息。
旁注:我只会使用DOM解析,这在过去我已经取得了巨大的成功,但我使用的XML太大而且已经崩溃了服务器。
这是我到目前为止所做的工作。我一直卡在站点/工作站/服务器节点上,因为有时会有一个站点(哈希元素),有时会有多个站点(数组元素)。工作站和服务器也是如此。
由于这是sax解析,我不明白如何将工作站和服务器指向每个客户端。我不需要网站数据,只需要每个客户的工作站和服务器:
require 'saxerator'
def parse_sax
clients_array = []
parser = Saxerator.parser(File.new("data.xml"))
parser.for_tag(:client).each do |client|
# Create a hash to store 'this' client's data in
client_hash = Hash.new
# Grab some data
client_hash[:name] = client['name']
client_hash[:clientid] = client['clientid']
# Here's where the workstation/server code would go
parser.for_tag(:site).each do |site|
# This just goes through and finds ALL sites
end
clients_array << client_hash
end
当我考虑分别解析客户端,工作站和服务器时,我以为我已经弄明白了:
parser.for_tag(:client).each do |client|
...
end
parser.for_tag(:workstation).each do |ws|
...
end
parser.for_tag(:server).each do |srv|
...
end
但后来我最终得到了一堆独立的客户端,工作站和服务器对象,无法将设备与各自的客户端联系起来。
我很有可能掌握萨克斯语解析,以至于我只是缺少一些可以实现我想要的微不足道的东西,但我似乎无法找到解决方案。
我非常乐意在需要的地方提供说明,并且非常感谢任何帮助。