2014-03-25 5 views
1

У меня есть следующий XML-документ, и я пытаюсь создать фильтр, который возвращает содержимое элемента (если существует) изнутри элемента.Обработка XML-документа

До сих пор у меня есть следующий код:

val xml = XML.loadString(output) 
val ports = xml \\ "ports" 

Я тогда думаю, что мне нужно сделать что-то вроде этого, чтобы построить фильтр, но я не могу заставить его работать, как я бы ожидать.

for (port <- ports \\ "port"){ 
    println(port \\ "port" filter{ _ \\"script" exists } \\ "script") 
    } 

.

<?xml version="1.0"?> 
<?xml-stylesheet href="file:///usr/local/share/nmap/nmap.xsl" type="text/xsl"?> 
<!-- Nmap 6.40 scan initiated Tue Mar 25 14:14:09 2014 as: /usr/local/bin/nmap -&#45;datadir /usr/local/share/nmap -&#45;script=ssl-cert -p 443,80 -v -oX - www.adobe.com --> 
<nmaprun scanner="nmap" 
     args="/usr/local/bin/nmap -&#45;datadir /usr/local/share/nmap -&#45;script=ssl-cert -p 443,80 -v -oX - www.abc.com" 
     start="1395756849" startstr="Tue Mar 25 14:14:09 2014" version="6.40" xmloutputversion="1.04"> 
    <scaninfo type="connect" protocol="tcp" numservices="2" services="80,443"/> 
    <verbose level="1"/> 
    <debugging level="0"/> 
    <taskbegin task="Ping Scan" time="1395756849"/> 
    <taskend task="Ping Scan" time="1395756849" extrainfo="1 total hosts"/> 
    <taskbegin task="Parallel DNS resolution of 1 host." time="1395756849"/> 
    <taskend task="Parallel DNS resolution of 1 host." time="1395756849"/> 
    <taskbegin task="Connect Scan" time="1395756849"/> 
    <taskend task="Connect Scan" time="1395756849" extrainfo="2 total ports"/> 
    <taskbegin task="NSE" time="1395756849"/> 
    <taskend task="NSE" time="1395756849"/> 
    <host starttime="1395756849" endtime="1395756849"> 
     <status state="up" reason="syn-ack" reason_ttl="0"/> 
     <address addr="111.111.111.11" addrtype="ipv4"/> 
     <hostnames> 
      <hostname name="www.abc.com" type="user"/> 
      <hostname name="www.abc.com" type="PTR"/> 
     </hostnames> 
     <ports> 
      <port protocol="tcp" portid="80"> 
       <state state="open" reason="syn-ack" reason_ttl="0"/> 
       <service name="http" method="table" conf="3"/> 
      </port> 
      <port protocol="tcp" portid="443"> 
       <state state="open" reason="syn-ack" reason_ttl="0"/> 
       <service name="https" method="table" conf="3"/> 
       <script id="ssl-cert" output="placeholder text"> 
        <table key="subject"> 
         <elem key="commonName">www.abc.com</elem> 
         <elem key="organizationalUnitName">Info</elem> 
         <elem key="stateOrProvinceName">London</elem> 
         <elem key="countryName">UK</elem> 
         <elem key="organizationName">ABC Incorporated</elem> 
         <elem key="localityName">London</elem> 
        </table> 
        <table key="issuer"> 
         <elem key="commonName">VeriSign Class 3 International Server CA - G3</elem> 
         <elem key="countryName">US</elem> 
         <elem key="organizationalUnitName">Terms of use at https://www.verisign.com/rpa (c)10</elem> 
         <elem key="organizationName">VeriSign, Inc.</elem> 
        </table> 
        <table key="pubkey"> 
         <elem key="type">rsa</elem> 
         <elem key="bits">2048</elem> 
        </table> 
        <table key="validity"> 
         <elem key="notBefore">2012-11-04T00:00:00+00:00</elem> 
         <elem key="notAfter">2014-11-23T23:59:59+00:00</elem> 
        </table> 
        <elem key="md5">0b96b21786ab67c5531cff08cf044c6b</elem> 
        <elem key="sha1">b3cd7fec0ade71acb0fe83be5e723495313ff426</elem> 
        <elem key="pem">-placeholder</elem> 
       </script> 
      </port> 
     </ports> 
     <times srtt="106198" rttvar="99430" to="503918"/> 
    </host> 
    <runstats> 
     <finished time="1395756849" timestr="Tue Mar 25 14:14:09 2014" elapsed="0.70" 
        summary="Nmap done at Tue Mar 25 14:14:09 2014; 1 IP address (1 host up) scanned in 0.70 seconds" 
        exit="success"/> 
     <hosts up="1" down="0" total="1"/> 
    </runstats> 
</nmaprun> 

ответ

0

фильтрация для script не является необходимым, так как \\ будет пересекать всю структуру и вернуть те элементы, которые соответствуют.

xml \\ "script" 

res1: scala.xml.NodeSeq = NodeSeq(<script id="ssl-cert" output="placeholder text"> 
... 

Печать на script теги в res1

res1.foreach(println(_)) 

<script id="ssl-cert" output="placeholder text"> 
<table key="subject"> 
... 

Update относительно комментариев

Чтобы получить только port узлы, которые содержат script узлы

(xml \\ "ports" \\ "port").filter(n => n.descendant.exists(_.label == "script")) 

Выходы:

res81: scala.xml.NodeSeq = 
NodeSeq(<port protocol="tcp" portid="443"> 
       <state state="open" reason="syn-ack" reason_ttl="0"/> 
       <service name="https" method="table" conf="3"/> 
       <script> 
        <table key="subject"> 
         ... 

descendant дает List[Node], который является одним из способов сделать это. Есть и другие, но это сработало для меня.

+0

Arr - Получаю сейчас! Если бы я хотел вернуть соответствующий номер порта для всех элементов порта, который содержит элемент

Смежные вопросы