xmllint.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:17k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  * xmllint.c : a small tester program for XML input.
  3.  *
  4.  * See Copyright for the status of this software.
  5.  *
  6.  * Daniel.Veillard@w3.org
  7.  */
  8. #ifdef WIN32
  9. #include "win32config.h"
  10. #else
  11. #include "config.h"
  12. #endif
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include <stdarg.h>
  17. #ifdef HAVE_SYS_TYPES_H
  18. #include <sys/types.h>
  19. #endif
  20. #ifdef HAVE_SYS_STAT_H
  21. #include <sys/stat.h>
  22. #endif
  23. #ifdef HAVE_FCNTL_H
  24. #include <fcntl.h>
  25. #endif
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #ifdef HAVE_STDLIB_H
  30. #include <stdlib.h>
  31. #endif
  32. #ifdef HAVE_LIBREADLINE
  33. #include <readline/readline.h>
  34. #ifdef HAVE_LIBHISTORY
  35. #include <readline/history.h>
  36. #endif
  37. #endif
  38. #include <libxml/xmlmemory.h>
  39. #include <libxml/parser.h>
  40. #include <libxml/parserInternals.h>
  41. #include <libxml/HTMLparser.h>
  42. #include <libxml/HTMLtree.h>
  43. #include <libxml/tree.h>
  44. #include <libxml/xpath.h>
  45. #include <libxml/debugXML.h>
  46. #ifdef LIBXML_DEBUG_ENABLED
  47. static int debug = 0;
  48. static int shell = 0;
  49. static int debugent = 0;
  50. #endif
  51. static int copy = 0;
  52. static int recovery = 0;
  53. static int noent = 0;
  54. static int noout = 0;
  55. static int nowrap = 0;
  56. static int valid = 0;
  57. static int postvalid = 0;
  58. static int repeat = 0;
  59. static int insert = 0;
  60. static int compress = 0;
  61. static int html = 0;
  62. static int htmlout = 0;
  63. static int push = 0;
  64. static int noblanks = 0;
  65. static int testIO = 0;
  66. extern int xmlDoValidityCheckingDefaultValue;
  67. extern int xmlGetWarningsDefaultValue;
  68. /************************************************************************
  69.  *  *
  70.  *  HTML ouput *
  71.  *  *
  72.  ************************************************************************/
  73. char buffer[50000];
  74. void
  75. xmlHTMLEncodeSend(void) {
  76.     char *result;
  77.     result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
  78.     if (result) {
  79. fprintf(stderr, "%s", result);
  80. xmlFree(result);
  81.     }
  82.     buffer[0] = 0;
  83. }
  84. /**
  85.  * xmlHTMLPrintFileInfo:
  86.  * @input:  an xmlParserInputPtr input
  87.  * 
  88.  * Displays the associated file and line informations for the current input
  89.  */
  90. void
  91. xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
  92.     fprintf(stderr, "<p>");
  93.     if (input != NULL) {
  94. if (input->filename) {
  95.     sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
  96.     input->line);
  97. } else {
  98.     sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
  99. }
  100.     }
  101.     xmlHTMLEncodeSend();
  102. }
  103. /**
  104.  * xmlHTMLPrintFileContext:
  105.  * @input:  an xmlParserInputPtr input
  106.  * 
  107.  * Displays current context within the input content for error tracking
  108.  */
  109. void
  110. xmlHTMLPrintFileContext(xmlParserInputPtr input) {
  111.     const xmlChar *cur, *base;
  112.     int n;
  113.     if (input == NULL) return;
  114.     fprintf(stderr, "<pre>n");
  115.     cur = input->cur;
  116.     base = input->base;
  117.     while ((cur > base) && ((*cur == 'n') || (*cur == 'r'))) {
  118. cur--;
  119.     }
  120.     n = 0;
  121.     while ((n++ < 80) && (cur > base) && (*cur != 'n') && (*cur != 'r'))
  122.         cur--;
  123.     if ((*cur == 'n') || (*cur == 'r')) cur++;
  124.     base = cur;
  125.     n = 0;
  126.     while ((*cur != 0) && (*cur != 'n') && (*cur != 'r') && (n < 79)) {
  127.         sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
  128. n++;
  129.     }
  130.     sprintf(&buffer[strlen(buffer)], "n");
  131.     cur = input->cur;
  132.     while ((*cur == 'n') || (*cur == 'r'))
  133. cur--;
  134.     n = 0;
  135.     while ((cur != base) && (n++ < 80)) {
  136.         sprintf(&buffer[strlen(buffer)], " ");
  137.         base++;
  138.     }
  139.     sprintf(&buffer[strlen(buffer)],"^n");
  140.     xmlHTMLEncodeSend();
  141.     fprintf(stderr, "</pre>");
  142. }
  143. /**
  144.  * xmlHTMLError:
  145.  * @ctx:  an XML parser context
  146.  * @msg:  the message to display/transmit
  147.  * @...:  extra parameters for the message display
  148.  * 
  149.  * Display and format an error messages, gives file, line, position and
  150.  * extra parameters.
  151.  */
  152. void
  153. xmlHTMLError(void *ctx, const char *msg, ...)
  154. {
  155.     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  156.     xmlParserInputPtr input;
  157.     xmlParserInputPtr cur = NULL;
  158.     va_list args;
  159.     buffer[0] = 0;
  160.     input = ctxt->input;
  161.     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
  162. cur = input;
  163.         input = ctxt->inputTab[ctxt->inputNr - 2];
  164.     }
  165.         
  166.     xmlHTMLPrintFileInfo(input);
  167.     fprintf(stderr, "<b>error</b>: ");
  168.     va_start(args, msg);
  169.     vsprintf(&buffer[strlen(buffer)], msg, args);
  170.     va_end(args);
  171.     xmlHTMLEncodeSend();
  172.     fprintf(stderr, "</p>n");
  173.     xmlHTMLPrintFileContext(input);
  174.     xmlHTMLEncodeSend();
  175. }
  176. /**
  177.  * xmlHTMLWarning:
  178.  * @ctx:  an XML parser context
  179.  * @msg:  the message to display/transmit
  180.  * @...:  extra parameters for the message display
  181.  * 
  182.  * Display and format a warning messages, gives file, line, position and
  183.  * extra parameters.
  184.  */
  185. void
  186. xmlHTMLWarning(void *ctx, const char *msg, ...)
  187. {
  188.     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  189.     xmlParserInputPtr input;
  190.     xmlParserInputPtr cur = NULL;
  191.     va_list args;
  192.     buffer[0] = 0;
  193.     input = ctxt->input;
  194.     if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
  195. cur = input;
  196.         input = ctxt->inputTab[ctxt->inputNr - 2];
  197.     }
  198.         
  199.     xmlHTMLPrintFileInfo(input);
  200.         
  201.     fprintf(stderr, "<b>warning</b>: ");
  202.     va_start(args, msg);
  203.     vsprintf(&buffer[strlen(buffer)], msg, args);
  204.     va_end(args);
  205.     xmlHTMLEncodeSend();
  206.     fprintf(stderr, "</p>n");
  207.     xmlHTMLPrintFileContext(input);
  208.     xmlHTMLEncodeSend();
  209. }
  210. /**
  211.  * xmlHTMLValidityError:
  212.  * @ctx:  an XML parser context
  213.  * @msg:  the message to display/transmit
  214.  * @...:  extra parameters for the message display
  215.  * 
  216.  * Display and format an validity error messages, gives file,
  217.  * line, position and extra parameters.
  218.  */
  219. void
  220. xmlHTMLValidityError(void *ctx, const char *msg, ...)
  221. {
  222.     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  223.     xmlParserInputPtr input;
  224.     va_list args;
  225.     buffer[0] = 0;
  226.     input = ctxt->input;
  227.     if ((input->filename == NULL) && (ctxt->inputNr > 1))
  228.         input = ctxt->inputTab[ctxt->inputNr - 2];
  229.         
  230.     xmlHTMLPrintFileInfo(input);
  231.     fprintf(stderr, "<b>validity error</b>: ");
  232.     va_start(args, msg);
  233.     vsprintf(&buffer[strlen(buffer)], msg, args);
  234.     va_end(args);
  235.     xmlHTMLEncodeSend();
  236.     fprintf(stderr, "</p>n");
  237.     xmlHTMLPrintFileContext(input);
  238.     xmlHTMLEncodeSend();
  239. }
  240. /**
  241.  * xmlHTMLValidityWarning:
  242.  * @ctx:  an XML parser context
  243.  * @msg:  the message to display/transmit
  244.  * @...:  extra parameters for the message display
  245.  * 
  246.  * Display and format a validity warning messages, gives file, line,
  247.  * position and extra parameters.
  248.  */
  249. void
  250. xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
  251. {
  252.     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
  253.     xmlParserInputPtr input;
  254.     va_list args;
  255.     buffer[0] = 0;
  256.     input = ctxt->input;
  257.     if ((input->filename == NULL) && (ctxt->inputNr > 1))
  258.         input = ctxt->inputTab[ctxt->inputNr - 2];
  259.     xmlHTMLPrintFileInfo(input);
  260.         
  261.     fprintf(stderr, "<b>validity warning</b>: ");
  262.     va_start(args, msg);
  263.     vsprintf(&buffer[strlen(buffer)], msg, args);
  264.     va_end(args);
  265.     xmlHTMLEncodeSend();
  266.     fprintf(stderr, "</p>n");
  267.     xmlHTMLPrintFileContext(input);
  268.     xmlHTMLEncodeSend();
  269. }
  270. /************************************************************************
  271.  *  *
  272.  *  Shell Interface *
  273.  *  *
  274.  ************************************************************************/
  275. /**
  276.  * xmlShellReadline:
  277.  * @prompt:  the prompt value
  278.  *
  279.  * Read a string
  280.  * 
  281.  * Returns a pointer to it or NULL on EOF the caller is expected to
  282.  *     free the returned string.
  283.  */
  284. char *
  285. xmlShellReadline(char *prompt) {
  286. #ifdef HAVE_LIBREADLINE
  287.     char *line_read;
  288.     /* Get a line from the user. */
  289.     line_read = readline (prompt);
  290.     /* If the line has any text in it, save it on the history. */
  291.     if (line_read && *line_read)
  292. add_history (line_read);
  293.     return (line_read);
  294. #else
  295.     char line_read[501];
  296.     if (prompt != NULL)
  297. fprintf(stdout, "%s", prompt);
  298.     if (!fgets(line_read, 500, stdin))
  299.         return(NULL);
  300.     line_read[500] = 0;
  301.     return(strdup(line_read));
  302. #endif
  303. }
  304. /************************************************************************
  305.  *  *
  306.  *  I/O Interfaces *
  307.  *  *
  308.  ************************************************************************/
  309. int myRead(FILE *f, char * buffer, int len) {
  310.     return(fread(buffer, 1, len, f));
  311. }
  312. void myClose(FILE *f) {
  313.     fclose(f);
  314. }
  315. /************************************************************************
  316.  *  *
  317.  *  Test processing *
  318.  *  *
  319.  ************************************************************************/
  320. void parseAndPrintFile(char *filename) {
  321.     xmlDocPtr doc = NULL, tmp;
  322. #ifdef LIBXML_HTML_ENABLED
  323.     if (html) {
  324. doc = htmlParseFile(filename, NULL);
  325.     } else {
  326. #endif /* LIBXML_HTML_ENABLED */
  327. /*
  328.  * build an XML tree from a string;
  329.  */
  330. if (push) {
  331.     FILE *f;
  332.     f = fopen(filename, "r");
  333.     if (f != NULL) {
  334.         int res, size = 3;
  335.         char chars[1024];
  336.                 xmlParserCtxtPtr ctxt;
  337. if (repeat)
  338.     size = 1024;
  339. res = fread(chars, 1, 4, f);
  340. if (res > 0) {
  341.     ctxt = xmlCreatePushParserCtxt(NULL, NULL,
  342.                 chars, res, filename);
  343.     while ((res = fread(chars, 1, size, f)) > 0) {
  344. xmlParseChunk(ctxt, chars, res, 0);
  345.     }
  346.     xmlParseChunk(ctxt, chars, 0, 1);
  347.     doc = ctxt->myDoc;
  348.     xmlFreeParserCtxt(ctxt);
  349.         }
  350.     }
  351. } else if (testIO) {
  352.     int ret;
  353.     FILE *f;
  354.     f = fopen(filename, "r");
  355.     if (f != NULL) {
  356.                 xmlParserCtxtPtr ctxt;
  357. ctxt = xmlCreateIOParserCtxt(NULL, NULL,
  358.     (xmlInputReadCallback) myRead,
  359.     (xmlInputCloseCallback) myClose,
  360.     f, XML_CHAR_ENCODING_NONE);
  361. xmlParseDocument(ctxt);
  362. ret = ctxt->wellFormed;
  363. doc = ctxt->myDoc;
  364. xmlFreeParserCtxt(ctxt);
  365. if (!ret) {
  366.     xmlFreeDoc(doc);
  367.     doc = NULL;
  368. }
  369.     }
  370. } else if (recovery) {
  371.     doc = xmlRecoverFile(filename);
  372. } else if (htmlout) {
  373.     int ret;
  374.     xmlParserCtxtPtr ctxt;
  375.     xmlSAXHandler silent, *old;
  376.     ctxt = xmlCreateFileParserCtxt(filename);
  377.     memcpy(&silent, ctxt->sax, sizeof(silent));
  378.     old = ctxt->sax;
  379.     silent.error = xmlHTMLError;
  380.     if (xmlGetWarningsDefaultValue)
  381. silent.warning = xmlHTMLWarning;
  382.     else 
  383. silent.warning = NULL;
  384.     silent.fatalError = xmlHTMLError;
  385.             ctxt->sax = &silent;
  386.     ctxt->vctxt.error = xmlHTMLValidityError;
  387.     if (xmlGetWarningsDefaultValue)
  388. ctxt->vctxt.warning = xmlHTMLValidityWarning;
  389.     else 
  390. ctxt->vctxt.warning = NULL;
  391.     xmlParseDocument(ctxt);
  392.     ret = ctxt->wellFormed;
  393.     doc = ctxt->myDoc;
  394.     ctxt->sax = old;
  395.     xmlFreeParserCtxt(ctxt);
  396.     if (!ret) {
  397. xmlFreeDoc(doc);
  398. doc = NULL;
  399.     }
  400. } else
  401.     doc = xmlParseFile(filename);
  402. #ifdef LIBXML_HTML_ENABLED
  403.     }
  404. #endif
  405. #ifdef LIBXML_DEBUG_ENABLED
  406.     /*
  407.      * shell interraction
  408.      */
  409.     if (shell)  
  410.         xmlShell(doc, filename, xmlShellReadline, stdout);
  411. #endif
  412.     /*
  413.      * test intermediate copy if needed.
  414.      */
  415.     if (copy) {
  416.         tmp = doc;
  417. doc = xmlCopyDoc(doc, 1);
  418. xmlFreeDoc(tmp);
  419.     }
  420.     if ((insert) && (!html)) {
  421.         const xmlChar* list[256];
  422. int nb, i;
  423. xmlNodePtr node;
  424. if (doc->children != NULL) {
  425.     node = doc->children;
  426.     while ((node != NULL) && (node->last == NULL)) node = node->next;
  427.     if (node != NULL) {
  428. nb = xmlValidGetValidElements(node->last, NULL, list, 256);
  429. if (nb < 0) {
  430.     printf("could not get valid list of elementsn");
  431. } else if (nb == 0) {
  432.     printf("No element can be indersted under rootn");
  433. } else {
  434.     printf("%d element types can be indersted under root:n",
  435.            nb);
  436.     for (i = 0;i < nb;i++) {
  437.  printf("%sn", list[i]);
  438.     }
  439. }
  440.     }
  441. }    
  442.     }else if (noout == 0) {
  443. /*
  444.  * print it.
  445.  */
  446. #ifdef LIBXML_DEBUG_ENABLED
  447. if (!debug) {
  448. #endif
  449.     if (compress)
  450. xmlSaveFile("-", doc);
  451.     else
  452. xmlDocDump(stdout, doc);
  453. #ifdef LIBXML_DEBUG_ENABLED
  454. } else
  455.     xmlDebugDumpDocument(stdout, doc);
  456. #endif
  457.     }
  458.     /*
  459.      * A posteriori validation test
  460.      */
  461.     if (postvalid) {
  462. xmlValidCtxt cvp;
  463. cvp.userData = (void *) stderr;                                                 cvp.error    = (xmlValidityErrorFunc) fprintf;                                  cvp.warning  = (xmlValidityWarningFunc) fprintf;
  464. xmlValidateDocument(&cvp, doc);
  465.     }
  466. #ifdef LIBXML_DEBUG_ENABLED
  467.     if ((debugent) && (!html))
  468. xmlDebugDumpEntities(stdout, doc);
  469. #endif
  470.     /*
  471.      * free it.
  472.      */
  473.     xmlFreeDoc(doc);
  474. }
  475. int main(int argc, char **argv) {
  476.     int i, count;
  477.     int files = 0;
  478.     for (i = 1; i < argc ; i++) {
  479. #ifdef LIBXML_DEBUG_ENABLED
  480. if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
  481.     debug++;
  482. else if ((!strcmp(argv[i], "-debugent")) || (!strcmp(argv[i], "--debugent")))
  483.     debugent++;
  484. else if ((!strcmp(argv[i], "-shell")) ||
  485.          (!strcmp(argv[i], "--shell"))) {
  486.     shell++;
  487.             noout = 1;
  488.         } else 
  489. #endif
  490. if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
  491.     copy++;
  492. else if ((!strcmp(argv[i], "-recover")) ||
  493.          (!strcmp(argv[i], "--recover")))
  494.     recovery++;
  495. else if ((!strcmp(argv[i], "-noent")) ||
  496.          (!strcmp(argv[i], "--noent")))
  497.     noent++;
  498. else if ((!strcmp(argv[i], "-noout")) ||
  499.          (!strcmp(argv[i], "--noout")))
  500.     noout++;
  501. else if ((!strcmp(argv[i], "-htmlout")) ||
  502.          (!strcmp(argv[i], "--htmlout")))
  503.     htmlout++;
  504. #ifdef LIBXML_HTML_ENABLED
  505. else if ((!strcmp(argv[i], "-html")) ||
  506.          (!strcmp(argv[i], "--html"))) {
  507.     html++;
  508.         }
  509. #endif /* LIBXML_HTML_ENABLED */
  510. else if ((!strcmp(argv[i], "-nowrap")) ||
  511.          (!strcmp(argv[i], "--nowrap")))
  512.     nowrap++;
  513. else if ((!strcmp(argv[i], "-valid")) ||
  514.          (!strcmp(argv[i], "--valid")))
  515.     valid++;
  516. else if ((!strcmp(argv[i], "-postvalid")) ||
  517.          (!strcmp(argv[i], "--postvalid")))
  518.     postvalid++;
  519. else if ((!strcmp(argv[i], "-insert")) ||
  520.          (!strcmp(argv[i], "--insert")))
  521.     insert++;
  522. else if ((!strcmp(argv[i], "-repeat")) ||
  523.          (!strcmp(argv[i], "--repeat")))
  524.     repeat++;
  525. else if ((!strcmp(argv[i], "-push")) ||
  526.          (!strcmp(argv[i], "--push")))
  527.     push++;
  528. else if ((!strcmp(argv[i], "-testIO")) ||
  529.          (!strcmp(argv[i], "--testIO")))
  530.     testIO++;
  531. else if ((!strcmp(argv[i], "-compress")) ||
  532.          (!strcmp(argv[i], "--compress"))) {
  533.     compress++;
  534.     xmlSetCompressMode(9);
  535.         }
  536. else if ((!strcmp(argv[i], "-nowarning")) ||
  537.          (!strcmp(argv[i], "--nowarning"))) {
  538.     xmlGetWarningsDefaultValue = 0;
  539.         }
  540. else if ((!strcmp(argv[i], "-noblanks")) ||
  541.          (!strcmp(argv[i], "--noblanks"))) {
  542.      noblanks++;
  543.      xmlKeepBlanksDefault(0);
  544.         }
  545.     }
  546.     if (noent != 0) xmlSubstituteEntitiesDefault(1);
  547.     if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
  548.     if ((htmlout) && (!nowrap)) {
  549. fprintf(stderr,
  550.          "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"n");
  551. fprintf(stderr, "t"http://www.w3.org/TR/REC-html40/loose.dtd">n");
  552. fprintf(stderr,
  553.  "<html><head><title>%s output</title></head>n",
  554. argv[0]);
  555. fprintf(stderr, 
  556.  "<body bgcolor="#ffffff"><h1 align="center">%s output</h1>n",
  557. argv[0]);
  558.     }
  559.     for (i = 1; i < argc ; i++) {
  560. if (argv[i][0] != '-') {
  561.     if (repeat) {
  562. for (count = 0;count < 100 * repeat;count++)
  563.     parseAndPrintFile(argv[i]);
  564.     } else
  565. parseAndPrintFile(argv[i]);
  566.     files ++;
  567. }
  568.     }
  569.     if ((htmlout) && (!nowrap)) {
  570. fprintf(stderr, "</body></html>n");
  571.     }
  572.     if (files == 0) {
  573. printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...n",
  574.        argv[0]);
  575. printf("tParse the XML files and output the result of the parsingn");
  576. #ifdef LIBXML_DEBUG_ENABLED
  577. printf("t--debug : dump a debug tree of the in-memory documentn");
  578. printf("t--shell : run a navigating shelln");
  579. printf("t--debugent : debug the entities defined in the documentn");
  580. #endif
  581. printf("t--copy : used to test the internal copy implementationn");
  582. printf("t--recover : output what was parsable on broken XML documentsn");
  583. printf("t--noent : substitute entity references by their valuen");
  584. printf("t--noout : don't output the result treen");
  585. printf("t--htmlout : output results as HTMLn");
  586. printf("t--nowarp : do not put HTML doc wrappern");
  587. printf("t--valid : validate the document in addition to std well-formed checkn");
  588. printf("t--postvalid : do a posteriori validation, i.e after parsingn");
  589. printf("t--repeat : repeat 100 times, for timing or profilingn");
  590. printf("t--insert : ad-hoc test for valid insertionsn");
  591. printf("t--compress : turn on gzip compression of outputn");
  592. #ifdef LIBXML_HTML_ENABLED
  593. printf("t--html : use the HTML parsern");
  594. #endif
  595. printf("t--push : use the push mode of the parsern");
  596. printf("t--nowarning : do not emit warnings from parser/validatorn");
  597. printf("t--noblanks : drop (ignorable?) blanks spacesn");
  598. printf("t--testIO : test user I/O supportn");
  599.     }
  600.     xmlCleanupParser();
  601.     xmlMemoryDump();
  602.     return(0);
  603. }