ruby on rails - Retrieve nested results with Nokogiri -
i'm trying parse nmap xml retrieve various values via nokogiri, having quite time figuring out recursion. want grab ip_address
, port
element has child element of status='open'
. want able put each group json object save database column later display:
so far, here's code:
require 'nokogiri' require 'json' doc = file.open("network_ports.xml") { |f| nokogiri::xml(f) } doc.xpath('//host').each |host| @ip_address = host.at_xpath("address[@addrtype='ipv4']").at_xpath("@addr").value puts "found host: #{@ip_address}" host.xpath('ports/port').each |port| if port.at_xpath("state[@state='open']") puts port.at_xpath("port[@portid]").value end end end
however output broken right following error:
port_parser.rb:11:in `block (2 levels) in <main>': undefined method `value' nil:nilclass (nomethoderror)
some same input file:
<host starttime="1501187906" endtime="1501189103"><status state="up" reason="syn-ack" reason_ttl="0"/> <address addr="10.10.10.1" addrtype="ipv4"/> <hostnames> <hostname name="eclipse" type="ptr"/> </hostnames> <ports><extraports state="closed" count="996"> <extrareasons reason="conn-refused" count="996"/> </extraports> <port protocol="tcp" portid="53"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="domain" product="dnsmasq" version="2.45" method="probed" conf="10"><cpe>cpe:/a:thekelleys:dnsmasq:2.45</cpe></service></port> <port protocol="tcp" portid="80"><state state="filtered" reason="syn-ack" reason_ttl="0"/><service name="http" product="dd-wrt milli_httpd" hostname="eclipse" method="probed" conf="10"/></port> <port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="https" tunnel="ssl" method="table" conf="3"/></port> <port protocol="tcp" portid="2222"><state state="open" reason="syn-ack" reason_ttl="0"/><service name="ssh" product="dropbear sshd" version="0.52" extrainfo="protocol 2.0" ostype="linux" method="probed" conf="10"><cpe>cpe:/a:matt_johnston:dropbear_ssh_server:0.52</cpe><cpe>cpe:/o:linux:linux_kernel</cpe></service></port> </ports> <times srtt="4727" rttvar="1840" to="100000"/> </host>
am running issue because i'm dependent on nested state
element within port
element need able portid
attribute value out of?
in end, i'm hoping output like:
found host: 10.10.10.1 port 22/tcp open port 23/tcp open found host: 10.10.10.2 port 443/tcp open port 5432/tcp open etc...
if have suggestions on cleaning code, i'm ears well!
everything code seems working fine, except for
puts port.at_xpath("port[@portid]").value
you're @ port
element, need xpath @portid
puts port.at_xpath("@portid").value
and, example network_ports.xml, outputs
# found host: 10.10.10.1 # 53 # 443 # 2222
Comments
Post a Comment