tags:

views:

1118

answers:

2

I would like to parse a group of elements out of a TinyXml output. Essentially, I need to pick out any port element's "portid" attribute of the port has a state of "open" (shown below for port 23).

What's the best way to do this? Here's the (simplified) listing for the output from TinyXml:

<?xml version="1.0" ?>
<?xml ?>
<nmaprun>
    <host>
        <ports>
            <port protocol="tcp" portid="22">
                <state state="filtered"/>
            </port>
            <port protocol="tcp" portid="23">
                <state state="open "/>
            </port>
            <port protocol="tcp" portid="24">
                <state state="filtered" />
            </port>
            <port protocol="tcp" portid="25">
                <state state="filtered" />
            </port>
            <port protocol="tcp" portid="80">
                <state state="filtered" />
            </port>
        </ports>
    </host>
</nmaprun>
+1  A: 

This will roughly do it:

 TiXmlHandle docHandle( &doc );

 TiXmlElement* child = docHandle.FirstChild( "nmaprun" ).FirstChild( "host" ).FirstChild( "ports" ).FirstChild( "port" ).ToElement();

 int port;
 string state;
 for( child; child; child=child->NextSiblingElement() )
 {

  port = atoi(child->Attribute( "portid"));

  TiXmlElement* state_el = child->FirstChild()->ToElement();

  state = state_el->Attribute( "state" );

  if ("filtered" == state)
   cout << "port: " << port << " is filtered! " << endl;
  else
   cout << "port: " << port << " is unfiltered! " << endl;
 }
Jack BeNimble
+1  A: 

Your best bet is to use the TinyXPath library in addition to TinyXML.

This is my best guess for the right XPath query:

/nmaprun/host/ports/port[state/@state="open "][1]/@portid

You can check it with an online tester. Note, though, that you need to remove the second line of the XML fragment you posted. I'm not sure how that got in there.

Jim Hunziker