XMLRPC C库。解析具有可变数量结构的数组

时间:2018-02-22 15:13:31

标签: c string parsing xml-rpc

我有一个XML,如下所示。它是一系列结构。数组内部的结构具有固定数量的元素,但数组可能有一个或多个结构,事先我们不知道有多少。 The documentation描述了解析固定数量的XML元素。我应该如何使用xmlrpc库中的xmlrpc_parse_value()函数来解析这样的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>

我希望看到的结果:计算结构总数和单独的结构数量,“州”成员的值为20。

1 个答案:

答案 0 :(得分:0)

我自己找到了答案。我的例子如下:

#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;
}