|
void startElement(void *userData, const char *name, const char **atts)
{
FRAME * newframe;
TAG * scan;
const char *mark;
int matchoffset;
int att;
const char **attptr;
int on;
int c;
int didit;
newframe = (FRAME *) malloc (sizeof (FRAME));
newframe->next = NULL;
newframe->back = top;
newframe->level = newframe->back->level + 1;
newframe->name = name;
newframe->subitems = NULL;
newframe->offset_in_parent = 0;
newframe->locator = NULL;
newframe->empty = 1;
if (stack.next == NULL) {
stack.next = newframe;
newframe->back = &stack;
} else {
top->next = newframe;
}
top = newframe;
/* If parent is still empty, close its tag. */
#ifdef XMLSNIP
if (!finished && emit_level > -1 && top->back->level - 1 + emit_matching_tag >= emit_level && top->back->empty == 1) {
#else
#ifdef XMLREPLACE
if ((emit_level < 0 || top->back->level + emit_matching_tag <= emit_level) && top->back->empty == 1) {
#else
if (top->back->empty == 1) {
#endif
#endif
if (emit_tags) top->back->empty = 0;
if (emit_tags) printf (">");
}
/* Scan parent's subitems to ascertain our own offset in that list. */
if (top->back) {
scan = top->back->subitems;
while (scan) {
if (!strcmp (scan->name, name)) break;
scan = scan->next;
}
if (scan) {
scan->count++;
} else {
scan = (TAG *) malloc (sizeof (TAG));
scan->name = name;
scan->next = top->back->subitems;
scan->count = 0;
top->back->subitems = scan;
}
top->offset_in_parent = scan->count;
}
/* Now check parent's locator to see whether we match the next bit.
(A null locator means the parent isn't in the match path.) */
if (top->back->locator != NULL) {
if (!strncmp (name, top->back->locator, strlen(name))) {
mark = (char *) top->back->locator + strlen(name);
matchoffset = 0;
if (*mark == '(') {
mark++;
matchoffset = atoi(mark);
while (*mark && *mark != ')') mark++;
if (*mark) mark++;
} else if (*mark == '[') {
mark++;
for (attptr = atts; *attptr && strcmp (*attptr, "id"); attptr += 2);
if (!*attptr) for (attptr = atts; *attptr && strcmp (*attptr, "name"); attptr += 2);
*attptr++;
if (!strncmp (*attptr, mark, strlen(*attptr))) {
mark += strlen(*attptr);
if (*mark == ']') {
matchoffset = top->offset_in_parent;
mark++;
}
}
}
if ((*mark == '\0' || *mark == ' ') && top->offset_in_parent == matchoffset) {
/* Ding, ding! */
emit_level = top->level;
if (emit_locator) print_stack();
emit_level = top->level;
} else if (*mark == '.' && top->offset_in_parent == matchoffset) {
top->locator = mark+1;
}
}
}
#ifdef XMLINSERT
if (top->level == emit_level && !strcmp (insertwhere, "before")) {
while (!feof(stdin)) { c = getchar(); if (!feof(stdin)) putchar(c); }
emit_level = -1;
}
#endif
/* Emit tag. */
#ifdef XMLSNIP
if (!finished && emit_level > -1 && top->level - 1 + emit_matching_tag >= emit_level) {
#else
#ifdef XMLREPLACE
if (emit_level < 0 || top->level + emit_matching_tag <= emit_level) {
#else
if (1) {
#endif
#endif
if (emit_tags) {
printf ("<%s", name);
#ifdef XMLSET
mark = NULL; finished = 0;
#endif
for (att=0, on=1; atts[att]; att++) {
if (on) printf (" %s", atts[att]);
#ifdef XMLSET
if (on && !strcmp (atts[att], setattr) && top->level == emit_level) {
mark = atts[att];
}
if (!on && mark != NULL && top->level == emit_level) {
printf ("=\"%s\"", setvalue);
mark = NULL;
finished = 1;
} else
#endif
if (!on) printf ("=\"%s\"", atts[att]);
on = !on;
}
#ifdef XMLSET
if (!finished && top->level == emit_level)
printf (" %s=\"%s\"", setattr, setvalue);
#endif
}
}
#ifdef XMLSET
emit_level = -1;
finished = 0;
#endif
#ifdef XMLREPLACE
if (emit_level == top->level) {
top->empty = 0;
if (emit_tags && !emit_matching_tag) printf (">");
while (!feof(stdin)) { c = getchar(); if (!feof(stdin)) putchar(c); }
}
#endif
#ifdef XMLINSERT
if (top->level == emit_level && !strcmp (insertwhere, "beforecontent")) {
top->empty = 0;
if (emit_tags && emit_matching_tag) printf (">");
while (!feof(stdin)) { c = getchar(); if (!feof(stdin)) putchar(c); }
emit_level = -1;
}
#endif
}
|