我正在尝试编写一个ruby脚本,以便将export简单的XML结果导出,解析它,并将所需的结果写成更漂亮的格式,以便于查看。我使用Nokogiri解析XML。我的问题是,我有一个嵌套循环,对于每个设备,迭代每个服务部分,并从每个服务部分提取名称、端口和协议属性。这将最终被打印回一个文件,一个文本文件或一个csv。但是,我的嵌套循环似乎只从第一个服务部分提取这三个属性,并反复打印它们。
示例输入(将有多个设备块):
<device address="10.x.x.1" id="20xx">
<fingerprint certainty="0.85">
<description>Microsoft Windows</description>
<vendor>Microsoft</vendor>
<family>Windows</family>
<product>Windows</product>
<version/>
<device-class>General</device-class>
<architecture/>
</fingerprint>
<vulnerabilities>
</vulnerabilities>
<services>
<service name="NTP" port="123" protocol="udp">
<vulnerabilities>
</vulnerabilities>
</service>
<service name="HTTP" port="8080" protocol="tcp">
<fingerprint certainty="0.75">
<description>Apache</description>
</device>
<device address="10.x.x.2" id="20xx">
<fingerprint certainty="0.85">
<description>Microsoft Windows</description>
<vendor>Microsoft</vendor>
<family>Windows</family>
<product>Windows</product>
<version/>
<device-class>General</device-class>
<architecture/>
</fingerprint>
<vulnerabilities>
</vulnerabilities>
<services>
<service name="DNS" port="53" protocol="udp">
<vulnerabilities>
</vulnerabilities>
</service>
<service name="HTTP" port="80" protocol="tcp">
<fingerprint certainty="0.75">
<description>Apache</description>
</device>Ruby代码:
#! /usr/bin/env ruby
require 'rubygems'
require 'nokogiri'
doc = Nokogiri::XML(open('report.xml').read)
device = doc.xpath('//device')
device.each do |d|
service = d.xpath('//service')
puts d.attr('address')
service.each do |s|
name = s.attr('name')
port = s.attr('port')
protocol = s.attr('protocol')
puts port
puts protocol
puts name
end
end期望输出:
10.x.x.1
123
udp
NTP
8080
tcp
HTTP
10.x.x.2
53
udp
DNS
80
tcp
HTTP实际输出:
123
NTP
udp
123
NTP
udp因此,代码应该显示每个设备的每个服务的服务端口、名称和协议的列表。但是,当前的代码似乎只是一次又一次地打印第一个服务的集(即123、NTP和udp)。
我是不是在我的循环逻辑中遗漏了什么?或者你看到循环有什么问题吗?任何帮助都是有帮助的。谢谢。
发布于 2012-10-18 13:27:22
注意,XPath构造//意味着查找文档中任何位置的元素。您不想在内部循环中这样做,因为您已经为您的设备这样做了。
更新
基于新的输入文档,以下是提取所需信息的一种方法。我冒昧地使用CSV作为一个优秀的Excel就绪输出文件。注意,只有一个解析循环。代码:
require 'nokogiri'
require 'csv'
doc = Nokogiri::XML(open('report.xml').read)
CSV.open("devices.csv", "wb") do |csv|
csv << ["Device", "Service", "Port", "Protocol"]
doc.search('//service').each do |s|
device = s.xpath('ancestor::device[1]/@address')
name = s.attr('name')
port = s.attr('port')
protocol = s.attr('protocol')
csv << [device, name, port, protocol]
end
end这是devices.csv的内容
Device,Service,Port,Protocol
10.x.x.1,NTP,123,udp
10.x.x.1,HTTP,8080,tcp
10.x.x.2,DNS,53,udp
10.x.x.2,HTTP,80,tcphttps://stackoverflow.com/questions/12955144
复制相似问题