I have an XML as below. It is array of structures. Structure inside an array have fixed number of elements, but array may have one or more sructures and beforehand we can't know how many. The documentation describes parsing of fixed amount of XML elements. How should I use xmlrpc_parse_value() function from xmlrpc library to parse such XML:
<methodResponse>
<params>
<param>
<value>
<array>
<data>
<value>
<struct>
<member>
<name>description</name>
<value>
<string>pid 32569, uptime 0:00:23</string>
</value>
</member>
<member>
<name>pid</name>
<value>
<int>32569</int>
</value>
</member>
<member>
<name>stderr_logfile</name>
<value>
<string>/var/log/supervisord/lp-se.err.log</string>
</value>
</member>
<member>
<name>stop</name>
<value>
<int>1519310402</int>
</value>
</member>
<member>
<name>logfile</name>
<value>
<string>/var/log/supervisord/lp-se.out.log</string>
</value>
</member>
<member>
<name>exitstatus</name>
<value>
<int>0</int>
</value>
</member>
<member>
<name>spawnerr</name>
<value>
<string />
</value>
</member>
<member>
<name>now</name>
<value>
<int>1519310425</int>
</value>
</member>
<member>
<name>group</name>
<value>
<string>lp-se</string>
</value>
</member>
<member>
<name>name</name>
<value>
<string>lp-se_0</string>
</value>
</member>
<member>
<name>statename</name>
<value>
<string>RUNNING</string>
</value>
</member>
<member>
<name>start</name>
<value>
<int>1519310402</int>
</value>
</member>
<member>
<name>state</name>
<value>
<int>20</int>
</value>
</member>
<member>
<name>stdout_logfile</name>
<value>
<string>/var/log/supervisord/lp-se.out.log</string>
</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>description</name>
<value>
<string>pid 31107, uptime 0:02:21</string>
</value>
</member>
<member>
<name>pid</name>
<value>
<int>31107</int>
</value>
</member>
<member>
<name>stderr_logfile</name>
<value>
<string>/var/log/supervisord/lp-se.err.log</string>
</value>
</member>
<member>
<name>stop</name>
<value>
<int>1519310284</int>
</value>
</member>
<member>
<name>logfile</name>
<value>
<string>/var/log/supervisord/lp-se.out.log</string>
</value>
</member>
<member>
<name>exitstatus</name>
<value>
<int>0</int>
</value>
</member>
<member>
<name>spawnerr</name>
<value>
<string />
</value>
</member>
<member>
<name>now</name>
<value>
<int>1519310425</int>
</value>
</member>
<member>
<name>group</name>
<value>
<string>lp-se</string>
</value>
</member>
<member>
<name>name</name>
<value>
<string>lp-se_1</string>
</value>
</member>
<member>
<name>statename</name>
<value>
<string>RUNNING</string>
</value>
</member>
<member>
<name>start</name>
<value>
<int>1519310284</int>
</value>
</member>
<member>
<name>state</name>
<value>
<int>20</int>
</value>
</member>
<member>
<name>stdout_logfile</name>
<value>
<string>/var/log/supervisord/lp-se.out.log</string>
</value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name>description</name>
<value>
<string>pid 30801, uptime 0:02:39</string>
</value>
</member>
<member>
<name>pid</name>
<value>
<int>30801</int>
</value>
</member>
<member>
<name>stderr_logfile</name>
<value>
<string>/var/log/supervisord/lp-se.err.log</string>
</value>
</member>
<member>
<name>stop</name>
<value>
<int>1519310265</int>
</value>
</member>
<member>
<name>logfile</name>
<value>
<string>/var/log/supervisord/lp-se.out.log</string>
</value>
</member>
<member>
<name>exitstatus</name>
<value>
<int>0</int>
</value>
</member>
<member>
<name>spawnerr</name>
<value>
<string />
</value>
</member>
<member>
<name>now</name>
<value>
<int>1519310425</int>
</value>
</member>
<member>
<name>group</name>
<value>
<string>lp-se</string>
</value>
</member>
<member>
<name>name</name>
<value>
<string>lp-se_10</string>
</value>
</member>
<member>
<name>statename</name>
<value>
<string>RUNNING</string>
</value>
</member>
<member>
<name>start</name>
<value>
<int>1519310266</int>
</value>
</member>
<member>
<name>state</name>
<value>
<int>20</int>
</value>
</member>
<member>
<name>stdout_logfile</name>
<value>
<string>/var/log/supervisord/lp-se.out.log</string>
</value>
</member>
</struct>
</value>
</data>
</array>
</value>
</param>
</params>
</methodResponse>
The result that I would like to see: count total amount of structures and separately, amount of structures, where the "state" member have value 20.
I have found the answer by oneself. There is my example below:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <xmlrpc.h>
#include <xmlrpc_client.h>
#define NAME "Supervisor XML-RPC client"
#define VERSION "0.1"
#define SERVER_URL "http://127.0.0.1:9001/RPC2"
void die_if_fault_occurred (xmlrpc_env *env)
{
/* Check our error-handling environment for an XML-RPC fault. */
if (env->fault_occurred) {
fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
env->fault_string, env->fault_code);
exit(1);
}
}
int main (int argc, char** argv)
{
xmlrpc_env env;
xmlrpc_value *result = NULL;
unsigned int quotientCt = 0;
unsigned long long int total_process = 0ULL;
unsigned long long int correct_statename_count = 0ULL;
/* Start up our XML-RPC client library. */
xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);
xmlrpc_env_init(&env);
/* Call our XML-RPC server. */
result = xmlrpc_client_call(&env, SERVER_URL,"supervisor.getAllProcessInfo","()");
die_if_fault_occurred(&env);
/* Parse our result value. */
total_process = xmlrpc_array_size(&env, result);
for (unsigned long long int i = 0; i < total_process; i++) {
xmlrpc_value * array_elementP;
char *description;
int pid;
char *stderr_logfile;
int stop;
char *logfile;
int exitstatus;
char *spawnerr;
int now;
char *group;
char *name;
char *statename;
int *start;
int state;
char *stdout_logfile;
xmlrpc_array_read_item(&env, result, i, &array_elementP);
xmlrpc_decompose_value(&env, array_elementP,
"{s:s,s:i,s:s,s:i,s:s,s:i,s:s,s:i,s:s,s:s,s:s,s:i,s:i,s:s,*}",
"description", &description,
"pid",&pid,
"stderr_logfile",&stderr_logfile,
"stop",&stop,
"logfile",&logfile,
"exitstatus",&exitstatus,
"spawnerr",&spawnerr,
"now",&now,
"group",&group,
"name",&name,
"statename",&statename,
"start",&start,
"state",&state,
"stdout_logfile",&stdout_logfile
);
char correct_statename[] = "RUNNING";
if (strncmp(statename, correct_statename,sizeof(correct_statename))==0) {
correct_statename_count++;
}
#if 1
printf("description:%s",description);
printf(" pid:%d",pid);
printf(" stderr_logfile:%s",stderr_logfile);
printf(" stop:%lld",stop);
printf(" logfile:%s",logfile);
printf(" exitstatus:%d",exitstatus);
printf(" spawnerr:%s",spawnerr);
printf(" now:%d",now);
printf(" group:%s",group);
printf(" name:%s",name);
printf(" statename:%s",statename);
printf(" start:%d",start);
printf(" state:%d",state);
printf(" stdout_logfile:%s ",stdout_logfile);
printf("\n");
#endif
die_if_fault_occurred(&env);
/* Dispose of our result value. */
xmlrpc_DECREF(array_elementP);
}
/* Dispose of our result value. */
xmlrpc_DECREF(result);
/* Shutdown our XML-RPC client library. */
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
printf("total_process:%llu; correct_statename_count:%llu;\n",total_process,correct_statename_count);
return 0;
}