📄 debugxml.c
字号:
if ((dtd == NULL) || (dtd[0] == 0)) { res = xmlValidateDocument(&vctxt, ctxt->doc); } else { xmlDtdPtr subset; subset = xmlParseDTD(NULL, (xmlChar *) dtd); if (subset != NULL) { res = xmlValidateDtd(&vctxt, ctxt->doc, subset); xmlFreeDtd(subset); } } return(res);}/** * xmlShellDu: * @ctxt: the shell context * @arg: unused * @tree: a node defining a subtree * @node2: unused * * Implements the XML shell function "du" * show the structure of the subtree under node @tree * If @tree is null, the command works on the current node. * * Returns 0 or -1 in case of error */int xmlShellDu(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr tree, xmlNodePtr node2) { xmlNodePtr node; int indent = 0,i; if (tree == NULL) return(-1); node = tree; while (node != NULL) { if ((node->type == XML_DOCUMENT_NODE) || (node->type == XML_HTML_DOCUMENT_NODE)) { printf("/\n"); } else if (node->type == XML_ELEMENT_NODE) { for (i = 0;i < indent;i++) printf(" "); printf("%s\n", node->name); } else { } /* * Browse the full subtree, deep first */ if ((node->type == XML_DOCUMENT_NODE) || (node->type == XML_HTML_DOCUMENT_NODE)) { node = ((xmlDocPtr) node)->children; } else if (node->children != NULL) { /* deep first */ node = node->children; indent++; } else if ((node != tree) && (node->next != NULL)) { /* then siblings */ node = node->next; } else if (node != tree) { /* go up to parents->next if needed */ while (node != tree) { if (node->parent != NULL) { node = node->parent; indent--; } if ((node != tree) && (node->next != NULL)) { node = node->next; break; } if (node->parent == NULL) { node = NULL; break; } if (node == tree) { node = NULL; break; } } /* exit condition */ if (node == tree) node = NULL; } else node = NULL; } return(0);}/** * xmlShellPwd: * @ctxt: the shell context * @buffer: the output buffer * @tree: a node * @node2: unused * * Implements the XML shell function "pwd" * Show the full path from the root to the node, if needed building * thumblers when similar elements exists at a given ancestor level. * The output is compatible with XPath commands. * * Returns 0 or -1 in case of error */int xmlShellPwd(xmlShellCtxtPtr ctxt, char *buffer, xmlNodePtr node, xmlNodePtr node2) { xmlNodePtr cur, tmp, next; char buf[500]; char sep; const char *name; int occur = 0; buffer[0] = 0; if (node == NULL) return(-1); cur = node; do { name = ""; sep= '?'; occur = 0; if ((cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_HTML_DOCUMENT_NODE)) { sep = '/'; next = NULL; } else if (cur->type == XML_ELEMENT_NODE) { sep = '/'; name = (const char *)cur->name; next = cur->parent; /* * Thumbler index computation */ tmp = cur->prev; while (tmp != NULL) { if (!xmlStrcmp(cur->name, tmp->name)) occur++; tmp = tmp->prev; } if (occur == 0) { tmp = cur->next; while (tmp != NULL) { if (!xmlStrcmp(cur->name, tmp->name)) occur++; tmp = tmp->next; } if (occur != 0) occur = 1; } else occur++; } else if (cur->type == XML_ATTRIBUTE_NODE) { sep = '@'; name = (const char *) (((xmlAttrPtr) cur)->name); next = ((xmlAttrPtr) cur)->parent; } else { next = cur->parent; } if (occur == 0) sprintf(buf, "%c%s%s", sep, name, buffer); else sprintf(buf, "%c%s[%d]%s", sep, name, occur, buffer); strcpy(buffer, buf); cur = next; } while (cur != NULL); return(0);}/** * xmlShell * @doc: the initial document * @filename: the output buffer * @input: the line reading function * @output: the output FILE* * * Implements the XML shell * This allow to load, validate, view, modify and save a document * using a environment similar to a UNIX commandline. */voidxmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, FILE *output) { char prompt[500] = "/ > "; char *cmdline = NULL; int nbargs; char command[100]; char arg[400]; xmlShellCtxtPtr ctxt; xmlXPathObjectPtr list; if (doc == NULL) return; if (filename == NULL) return; if (input == NULL) return; if (output == NULL) return; ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt)); if (ctxt == NULL) return; ctxt->loaded = 0; ctxt->doc = doc; ctxt->input = input; ctxt->output = output; ctxt->filename = (char *) xmlStrdup((xmlChar *) filename); ctxt->node = (xmlNodePtr) ctxt->doc; #ifdef LIBXML_XPATH_ENABLED ctxt->pctxt = xmlXPathNewContext(ctxt->doc); if (ctxt->pctxt == NULL) { xmlFree(ctxt); return; }#endif /* LIBXML_XPATH_ENABLED */ while (1) { if (ctxt->node == (xmlNodePtr) ctxt->doc) sprintf(prompt, "%s > ", "/"); else if (ctxt->node->name) sprintf(prompt, "%s > ", ctxt->node->name); else sprintf(prompt, "? > "); cmdline = ctxt->input(prompt); if (cmdline == NULL) break; command[0] = 0; arg[0] = 0; nbargs = sscanf(cmdline, "%s %s", command, arg); if (command[0] == 0) continue; if (!strcmp(command, "exit")) break; if (!strcmp(command, "quit")) break; if (!strcmp(command, "bye")) break; if (!strcmp(command, "validate")) { xmlShellValidate(ctxt, arg, NULL, NULL); } else if (!strcmp(command, "load")) { xmlShellLoad(ctxt, arg, NULL, NULL); } else if (!strcmp(command, "save")) { xmlShellSave(ctxt, arg, NULL, NULL); } else if (!strcmp(command, "write")) { xmlShellWrite(ctxt, arg, NULL, NULL); } else if (!strcmp(command, "free")) { if (arg[0] == 0) { xmlMemShow(stdout, 0); } else { int len = 0; sscanf(arg, "%d", &len); xmlMemShow(stdout, len); } } else if (!strcmp(command, "pwd")) { char dir[500]; if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL)) printf("%s\n", dir); } else if (!strcmp(command, "du")) { xmlShellDu(ctxt, NULL, ctxt->node, NULL); } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) { int dir = (!strcmp(command, "dir")); if (arg[0] == 0) { if (dir) xmlShellDir(ctxt, NULL, ctxt->node, NULL); else xmlShellList(ctxt, NULL, ctxt->node, NULL); } else { ctxt->pctxt->node = ctxt->node;#ifdef LIBXML_XPATH_ENABLED if (ctxt->pctxt->nodelist != NULL) xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node); list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);#else list = NULL;#endif /* LIBXML_XPATH_ENABLED */ if (list != NULL) { switch (list->type) { case XPATH_UNDEFINED: fprintf(stderr, "%s: no such node\n", arg); break; case XPATH_NODESET: { int i; for (i = 0;i < list->nodesetval->nodeNr;i++) { if (dir) xmlShellDir(ctxt, NULL, list->nodesetval->nodeTab[i], NULL); else xmlShellList(ctxt, NULL, list->nodesetval->nodeTab[i], NULL); } break; } case XPATH_BOOLEAN: fprintf(stderr, "%s is a Boolean\n", arg); break; case XPATH_NUMBER: fprintf(stderr, "%s is a number\n", arg); break; case XPATH_STRING: fprintf(stderr, "%s is a string\n", arg); break; } xmlXPathFreeNodeSetList(list); } else { fprintf(stderr, "%s: no such node\n", arg); }#ifdef LIBXML_XPATH_ENABLED if (ctxt->pctxt->nodelist != NULL) xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);#endif /* LIBXML_XPATH_ENABLED */ ctxt->pctxt->nodelist = NULL; } } else if (!strcmp(command, "cd")) { if (arg[0] == 0) { ctxt->node = (xmlNodePtr) ctxt->doc; } else { ctxt->pctxt->node = ctxt->node;#ifdef LIBXML_XPATH_ENABLED if (ctxt->pctxt->nodelist != NULL) xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node); list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);#else list = NULL;#endif /* LIBXML_XPATH_ENABLED */ if (list != NULL) { switch (list->type) { case XPATH_UNDEFINED: fprintf(stderr, "%s: no such node\n", arg); break; case XPATH_NODESET: if (list->nodesetval->nodeNr == 1) { ctxt->node = list->nodesetval->nodeTab[0]; } else fprintf(stderr, "%s is a %d Node Set\n", arg, list->nodesetval->nodeNr); break; case XPATH_BOOLEAN: fprintf(stderr, "%s is a Boolean\n", arg); break; case XPATH_NUMBER: fprintf(stderr, "%s is a number\n", arg); break; case XPATH_STRING: fprintf(stderr, "%s is a string\n", arg); break; } xmlXPathFreeNodeSetList(list); } else { fprintf(stderr, "%s: no such node\n", arg); }#ifdef LIBXML_XPATH_ENABLED if (ctxt->pctxt->nodelist != NULL) xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);#endif /* LIBXML_XPATH_ENABLED */ ctxt->pctxt->nodelist = NULL; } } else if (!strcmp(command, "cat")) { if (arg[0] == 0) { xmlShellCat(ctxt, NULL, ctxt->node, NULL); } else { ctxt->pctxt->node = ctxt->node;#ifdef LIBXML_XPATH_ENABLED if (ctxt->pctxt->nodelist != NULL) xmlXPathFreeNodeSet(ctxt->pctxt->nodelist); ctxt->pctxt->nodelist = xmlXPathNodeSetCreate(ctxt->node); list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);#else list = NULL;#endif /* LIBXML_XPATH_ENABLED */ if (list != NULL) { switch (list->type) { case XPATH_UNDEFINED: fprintf(stderr, "%s: no such node\n", arg); break; case XPATH_NODESET: { int i; for (i = 0;i < list->nodesetval->nodeNr;i++) { if (i > 0) printf(" -------\n"); xmlShellCat(ctxt, NULL, list->nodesetval->nodeTab[i], NULL); } break; } case XPATH_BOOLEAN: fprintf(stderr, "%s is a Boolean\n", arg); break; case XPATH_NUMBER: fprintf(stderr, "%s is a number\n", arg); break; case XPATH_STRING: fprintf(stderr, "%s is a string\n", arg); break; } xmlXPathFreeNodeSetList(list); } else { fprintf(stderr, "%s: no such node\n", arg); }#ifdef LIBXML_XPATH_ENABLED if (ctxt->pctxt->nodelist != NULL) xmlXPathFreeNodeSet(ctxt->pctxt->nodelist);#endif /* LIBXML_XPATH_ENABLED */ ctxt->pctxt->nodelist = NULL; } } else { fprintf(stderr, "Unknown command %s\n", command); } free(cmdline); /* not xmlFree here ! */ }#ifdef LIBXML_XPATH_ENABLED xmlXPathFreeContext(ctxt->pctxt);#endif /* LIBXML_XPATH_ENABLED */ if (ctxt->loaded) { xmlFreeDoc(ctxt->doc); } xmlFree(ctxt); if (cmdline != NULL) free(cmdline); /* not xmlFree here ! */}#endif /* LIBXML_DEBUG_ENABLED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -