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);
}
Exemplo n.º 2
0
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");
}