/* * This program parses the XML data provided by sourceforge to extract the * list of "attached files" (which are not themselves included in the XML * stream and therefore need to be seperately downloaded for archiving). */ #include #include #include #include #include struct artifact_type { char *name; int id; } artifact_types[] = { "Bugs", 109746, "Support Requests", 209746, "Patches", 309746, "Feature Requests", 359746, }; #ifndef NO_ELEMS #define NO_ELEMS(array) (sizeof(array)/sizeof(*(array))) #endif void parse_history(xmlDocPtr doc,const xmlChar *artifact_id, const xmlChar *artifact_type,xmlNodePtr node) { xmlNodePtr field,cur; xmlAttrPtr attr; xmlChar *name=NULL; xmlChar *field_name=NULL; xmlChar *text; int file_id,i; for(field=node->xmlChildrenNode;field;field=field->next) if (!xmlStrcmp(field->name,(const xmlChar *)"field")) { for(attr=field->properties;attr;attr=attr->next) if (!xmlStrcmp(attr->name,(const xmlChar *)"name")) { name=xmlNodeListGetString(doc,attr->children,1); if (!xmlStrcmp(name,(const xmlChar *)"field_name")) field_name=xmlNodeListGetString(doc,field->children,1); if (!xmlStrcmp(field_name,(const xmlChar *)"File Added") && !xmlStrcmp(name,(const xmlChar *)"old_value")) { text=xmlNodeListGetString(doc,field->children,1); if (sscanf(text,"%d",&file_id)==1) { for(i=NO_ELEMS(artifact_types)-1;i>=0;i--) if (!strcmp(artifact_types[i].name, (const char *)artifact_type)) break; if (i>=0) printf("%d %s %d\n", artifact_types[i].id,artifact_id,file_id); else fprintf(stderr, "Warning: Unknown artifact type \"%s\" - " "attached file %s ignored\n", artifact_type,text); } xmlFree(text); } xmlFree(name); } } if (field_name) xmlFree(field_name); } void parse_artifact(xmlDocPtr doc,xmlNodePtr node) { xmlNodePtr field,cur; xmlAttrPtr attr; xmlChar *name=NULL; xmlChar *id=NULL; xmlChar *type=NULL; xmlChar *text; for(field=node->xmlChildrenNode;field;field=field->next) if (!xmlStrcmp(field->name,(const xmlChar *)"field")) { for(attr=field->properties;attr;attr=attr->next) if (!xmlStrcmp(attr->name,(const xmlChar *)"name")) { name=xmlNodeListGetString(doc,attr->children,1); if (!xmlStrcmp(name,(const xmlChar *)"artifact_id")) id=xmlNodeListGetString(doc,field->children,1); if (!xmlStrcmp(name,(const xmlChar *)"artifact_type")) type=xmlNodeListGetString(doc,field->children,1); } if (!xmlStrcmp(name,(const xmlChar *)"artifact_history")) for(cur=field->xmlChildrenNode;cur;cur=cur->next) if (!xmlStrcmp(cur->name,"history")) parse_history(doc,id,type,cur); if (name) { xmlFree(name); name=NULL; } } if (id) xmlFree(id); if (type) xmlFree(type); } int main(int argc,char **argv) { xmlDocPtr doc; xmlNodePtr cur; doc=xmlParseFile(argv[1]); if (!doc) { fprintf(stderr,"Document not parsed successfully.\n"); exit(1); } cur=xmlDocGetRootElement(doc); if (!cur) { fprintf(stderr,"Empty document.\n"); xmlFreeDoc(doc); exit(1); } if (xmlStrcmp(cur->name,(const xmlChar *)"project_export")) { fprintf(stderr,"%s does not appear to be a project export document.\n", argv[1]); xmlFreeDoc(doc); exit(1); } for(cur=cur->xmlChildrenNode;cur;cur=cur->next) if (!xmlStrcmp(cur->name,(const xmlChar *)"artifacts")) break; if (!cur) { fprintf(stderr,"%s does not appear to contain an artifacts node.\n", argv[1]); xmlFreeDoc(doc); exit(1); } for(cur=cur->xmlChildrenNode;cur;cur=cur->next) if (!xmlStrcmp(cur->name,(const xmlChar *)"artifact")) parse_artifact(doc,cur); xmlFreeDoc(doc); exit(0); }