非标准节点信息问题(XPath,C代码)

时间:2013-06-25 10:31:19

标签: c xpath missing-data

我正在使用libxml2(2-2.7.8)和xpath(v1)从我的C程序中提取wunderground.com生成的XML文件中的一些信息。 如果所有节点都包含信息,那么一切都很好。问题是当某些节点丢失数据时:例如,如果UV数据不可用,wunderground将应用如下语法:

<visibility_km>10.0</visibility_km>
<solarradiation>0.1</solarradiation>
<UV/>
<precip_1hr_string>0.00 in ( 0 mm)</precip_1hr_string>

导致我的XPath停止导航和信息恢复。

后,我的输出将被截断,所有数据都将被截断
<UV/>
迷路了。我想即使我的整个程序执行都会停止。这是正常的行为吗?如何在丢失节点时避免不一致并至少终止我的程序执行?

感谢帮助伙伴,最好的

乔瓦尼

我的XPath表达式:

//current_observation/display_location/full | //current_observation/display_location/country_iso3166 | //current_observation/display_location/elevation | //current_observation/observation_location/full | //current_observation/local_time_rfc822 | //current_observation/weather | //current_observation/temp_c | //current_observation/relative_humidity |//current_observation/wind_dir | //current_observation/wind_kph | //current_observation/pressure_mb | //current_observation/feelslike_c | //visibility_km | //current_observation/UV | //current_observation/precip_today_metric | //simpleforecast/forecastdays/forecastday/date/day | //simpleforecast/forecastdays/forecastday/date/monthname | //simpleforecast/forecastdays/forecastday/date/weekday_short | //simpleforecast/forecastdays/forecastday/date/high/celsius | //simpleforecast/forecastdays/forecastday/low/celsius | //simpleforecast/forecastdays/forecastday/date/conditions | //simpleforecast/forecastdays/forecastday/pop | //simpleforecast/forecastdays/forecastday/avewind/kph | //simpleforecast/forecastdays/forecastday/avehumidity

我的部分代码:

//code

xmlXPathObjectPtr getnodeset (xmlDocPtr doc, xmlChar *xpath, char* thisnames) {
    xmlXPathContextPtr context;
    xmlXPathObjectPtr result;
    context = xmlXPathNewContext(doc);
    if (context == NULL) {
        printf("Error in xmlXPathNewContext\n");
        return NULL;    }

    if(xmlXPathRegisterNs(context,  BAD_CAST "new", BAD_CAST thisnames) != 0) {
    printf("Error: unable to register NS with prefix");
    return NULL;    }


    result = xmlXPathEvalExpression(xpath, context);
    xmlXPathFreeContext(context);
    if (result == NULL) {
        printf("Error in xmlXPathEvalExpression\n");
        return NULL;    }
    if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
        xmlXPathFreeObject(result);
        printf("No result\n");
        return NULL;    }
    return result;
}

//code

doc = xmlParseDoc(chunk.memory);
if (doc == NULL ) {
        printf("Document not parsed successfully. \n");
        return state;   }
result = getnodeset (doc, xpath, thisnames);
if (result) {
    nodeset = result->nodesetval;
    *myarray = malloc((nodeset->nodeNr + 1) * sizeof(*myarray));
    for (i=0; i < nodeset->nodeNr; i++) {
        keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
        (*myarray)[i] = malloc(strlen(keyword)+1);
        if ((*myarray)[i] == NULL) {
        // out of memory.  print error msg then exit
        }
        strcpy((*myarray)[i], keyword);
        printf("id: %d keyword: %s\n",i,keyword);
        xmlFree(keyword);
    }
    xmlXPathFreeObject (result);
    state = i;
}

//code

1 个答案:

答案 0 :(得分:0)

我不是libxml2专家,但是看看你的代码,我怀疑xmlChildrenNode元素为<UV/>,因为它没有子节点。如果你把它传给null我不知道xmlNodeListGetString会做什么,但我想是两件事之一:

  • it segfaults,或
  • 它会将null返回给您,然后您将其视为字符串而不进行验证,这将是段错误。

要解决此问题,您应确保验证可能为空的数据,但为了快速修复,我会尝试更换

keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);

keyword = xmlNodeGetContent(nodeset->nodeTab[i]);