void autoXml(char *dtdxFile, char *outRoot) /* autoXml - Generate structures code and parser for XML file from DTD-like spec. */ { struct dtdElement *elList = NULL; struct hash *elHash = NULL; char hName[512], cName[512]; char outDir[256]; splitPath(outRoot, outDir, prefix, NULL); if (cgiVarExists("prefix")) strcpy(prefix, cgiString("prefix")); if (outDir[0] != 0) makeDir(outDir); dtdParse(dtdxFile, prefix, textField, &elList, &elHash); printf("Parsed %d elements in %s\n", slCount(elList), dtdxFile); sprintf(hName, "%s.h", outRoot); makeH(elList, hName); sprintf(cName, "%s.c", outRoot); makeC(elList, cName, hName); printf("Generated code in %s\n", cName); }
void xmlToSql(char *xmlFileName, char *dtdFileName, char *statsFileName, char *outDir) /* xmlToSql - Convert XML dump into a fairly normalized relational database. */ { struct elStat *elStatList = NULL; struct dtdElement *dtdList, *dtdEl; struct hash *dtdHash, *dtdMixedHash = hashNew(0); struct table *tableList = NULL, *table; struct hash *tableHash = hashNew(0); struct xap *xap = xapNew(startHandler, endHandler, xmlFileName); char outFile[PATH_LEN]; /* Load up dtd and stats file. */ elStatList = elStatLoadAll(statsFileName); verbose(2, "%d elements in %s\n", slCount(elStatList), statsFileName); dtdParse(dtdFileName, globalPrefix, textField, &dtdList, &dtdHash); dtdRenameMixedCase(dtdList); verbose(1, "%d elements in %s\n", dtdHash->elCount, dtdFileName); /* Build up hash of dtdElements keyed by mixed name rather * than tag name. */ for (dtdEl = dtdList; dtdEl != NULL; dtdEl = dtdEl->next) hashAdd(dtdMixedHash, dtdEl->mixedCaseName, dtdEl); /* Create list of tables that correspond to tag types. * This doesn't include any association tables we create * to handle lists of child elements. */ tableList = elsIntoTables(elStatList, dtdHash); verbose(2, "Made tableList\n"); /* Create hashes of the table lists - one keyed by the * table name, and one keyed by the tag name. */ xmlTableHash = hashNew(0); for (table = tableList; table != NULL; table = table->next) { hashAdd(tableHash, table->name, table); hashAdd(xmlTableHash, table->dtdElement->name, table); } verbose(2, "Made table hashes\n"); /* Find top level tag (which we won't actually output). */ countUsesAsChild(dtdList, tableHash); verbose(2, "Past countUsesAsChild\n"); rootTable = findRootTable(tableList); verbose(2, "Root table is %s\n", rootTable->name); /* Add stuff to support parent-child relationships. */ addParentKeys(rootTable->dtdElement, tableHash, &tableList); verbose(2, "Added parent keys\n"); /* Now that all the fields, both attributes and made up * keys are in place, figure out index of field in table. */ calcTablePosOfFields(tableList); /* Make output directory. */ makeDir(outDir); /* Make table creation SQL files. */ for (table = tableList; table != NULL; table = table->next) { if (!table->promoted) { safef(outFile, sizeof(outFile), "%s/%s.sql", outDir, table->name); writeCreateSql(outFile, table); } } verbose(2, "Made sql table creation files\n"); /* Set up output directory and open tab-separated files. */ for (table = tableList; table != NULL; table = table->next) { if (!table->promoted) { safef(outFile, sizeof(outFile), "%s/%s.tab", outDir, table->name); table->tabFile = mustOpen(outFile, "w"); } } verbose(2, "Created output files.\n"); /* Stream through XML adding to tab-separated files.. */ xapParseFile(xap, xmlFileName); verbose(2, "Streamed through XML\n"); /* Close down files */ for (table = tableList; table != NULL; table = table->next) carefulClose(&table->tabFile); verbose(2, "Closed tab files\n"); verbose(1, "All done\n"); }