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

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  * HTMLtree.c : implemetation of access function for an HTML tree.
  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 "xmlversion.h"
  14. #ifdef LIBXML_HTML_ENABLED
  15. #include <stdio.h>
  16. #include <string.h> /* for memset() only ! */
  17. #ifdef HAVE_CTYPE_H
  18. #include <ctype.h>
  19. #endif
  20. #ifdef HAVE_STDLIB_H
  21. #include <stdlib.h>
  22. #endif
  23. #include <libxml/xmlmemory.h>
  24. #include <libxml/HTMLparser.h>
  25. #include <libxml/HTMLtree.h>
  26. #include <libxml/entities.h>
  27. #include <libxml/valid.h>
  28. static void
  29. htmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur);
  30. /**
  31.  * htmlDtdDump:
  32.  * @buf:  the HTML buffer output
  33.  * @doc:  the document
  34.  * 
  35.  * Dump the HTML document DTD, if any.
  36.  */
  37. static void
  38. htmlDtdDump(xmlBufferPtr buf, xmlDocPtr doc) {
  39.     xmlDtdPtr cur = doc->intSubset;
  40.     if (cur == NULL) {
  41.         fprintf(stderr, "htmlDtdDump : no internal subsetn");
  42. return;
  43.     }
  44.     xmlBufferWriteChar(buf, "<!DOCTYPE ");
  45.     xmlBufferWriteCHAR(buf, cur->name);
  46.     if (cur->ExternalID != NULL) {
  47. xmlBufferWriteChar(buf, " PUBLIC ");
  48. xmlBufferWriteQuotedString(buf, cur->ExternalID);
  49. if (cur->SystemID != NULL) {
  50.     xmlBufferWriteChar(buf, " ");
  51.     xmlBufferWriteQuotedString(buf, cur->SystemID);
  52.     }  else if (cur->SystemID != NULL) {
  53. xmlBufferWriteChar(buf, " SYSTEM ");
  54. xmlBufferWriteQuotedString(buf, cur->SystemID);
  55.     }
  56.     xmlBufferWriteChar(buf, ">n");
  57. }
  58. /**
  59.  * htmlAttrDump:
  60.  * @buf:  the HTML buffer output
  61.  * @doc:  the document
  62.  * @cur:  the attribute pointer
  63.  *
  64.  * Dump an HTML attribute
  65.  */
  66. static void
  67. htmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
  68.     xmlChar *value;
  69.     if (cur == NULL) {
  70.         fprintf(stderr, "htmlAttrDump : property == NULLn");
  71. return;
  72.     }
  73.     xmlBufferWriteChar(buf, " ");
  74.     xmlBufferWriteCHAR(buf, cur->name);
  75.     value = xmlNodeListGetString(doc, cur->children, 0);
  76.     if (value) {
  77. xmlBufferWriteChar(buf, "=");
  78. xmlBufferWriteQuotedString(buf, value);
  79. xmlFree(value);
  80.     } else  {
  81. xmlBufferWriteChar(buf, "=""");
  82.     }
  83. }
  84. /**
  85.  * htmlAttrListDump:
  86.  * @buf:  the HTML buffer output
  87.  * @doc:  the document
  88.  * @cur:  the first attribute pointer
  89.  *
  90.  * Dump a list of HTML attributes
  91.  */
  92. static void
  93. htmlAttrListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
  94.     if (cur == NULL) {
  95.         fprintf(stderr, "htmlAttrListDump : property == NULLn");
  96. return;
  97.     }
  98.     while (cur != NULL) {
  99.         htmlAttrDump(buf, doc, cur);
  100. cur = cur->next;
  101.     }
  102. }
  103. void
  104. htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur);
  105. /**
  106.  * htmlNodeListDump:
  107.  * @buf:  the HTML buffer output
  108.  * @doc:  the document
  109.  * @cur:  the first node
  110.  *
  111.  * Dump an HTML node list, recursive behaviour,children are printed too.
  112.  */
  113. static void
  114. htmlNodeListDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
  115.     if (cur == NULL) {
  116.         fprintf(stderr, "htmlNodeListDump : node == NULLn");
  117. return;
  118.     }
  119.     while (cur != NULL) {
  120.         htmlNodeDump(buf, doc, cur);
  121. cur = cur->next;
  122.     }
  123. }
  124. /**
  125.  * htmlNodeDump:
  126.  * @buf:  the HTML buffer output
  127.  * @doc:  the document
  128.  * @cur:  the current node
  129.  *
  130.  * Dump an HTML node, recursive behaviour,children are printed too.
  131.  */
  132. void
  133. htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
  134.     htmlElemDescPtr info;
  135.     if (cur == NULL) {
  136.         fprintf(stderr, "htmlNodeDump : node == NULLn");
  137. return;
  138.     }
  139.     /*
  140.      * Special cases.
  141.      */
  142.     if (cur->type == XML_HTML_DOCUMENT_NODE) {
  143. htmlDocContentDump(buf, (xmlDocPtr) cur);
  144. return;
  145.     }
  146.     if (cur->type == HTML_TEXT_NODE) {
  147. if (cur->content != NULL) {
  148.             xmlChar *buffer;
  149.     /* uses the HTML encoding routine !!!!!!!!!! */
  150. #ifndef XML_USE_BUFFER_CONTENT
  151.             buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
  152. #else
  153.             buffer = xmlEncodeEntitiesReentrant(doc, 
  154.                                                 xmlBufferContent(cur->content));
  155. #endif 
  156.     if (buffer != NULL) {
  157. xmlBufferWriteCHAR(buf, buffer);
  158. xmlFree(buffer);
  159.     }
  160. }
  161. return;
  162.     }
  163.     if (cur->type == HTML_COMMENT_NODE) {
  164. if (cur->content != NULL) {
  165.     xmlBufferWriteChar(buf, "<!--");
  166. #ifndef XML_USE_BUFFER_CONTENT
  167.     xmlBufferWriteCHAR(buf, cur->content);
  168. #else
  169.     xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
  170. #endif
  171.     xmlBufferWriteChar(buf, "-->");
  172. }
  173. return;
  174.     }
  175.     if (cur->type == HTML_ENTITY_REF_NODE) {
  176.         xmlBufferWriteChar(buf, "&");
  177. xmlBufferWriteCHAR(buf, cur->name);
  178.         xmlBufferWriteChar(buf, ";");
  179. return;
  180.     }
  181.     /*
  182.      * Get specific HTmL info for taht node.
  183.      */
  184.     info = htmlTagLookup(cur->name);
  185.     xmlBufferWriteChar(buf, "<");
  186.     xmlBufferWriteCHAR(buf, cur->name);
  187.     if (cur->properties != NULL)
  188.         htmlAttrListDump(buf, doc, cur->properties);
  189.     if ((info != NULL) && (info->empty)) {
  190.         xmlBufferWriteChar(buf, ">");
  191. if (cur->next != NULL) {
  192.     if ((cur->next->type != HTML_TEXT_NODE) &&
  193. (cur->next->type != HTML_ENTITY_REF_NODE))
  194. xmlBufferWriteChar(buf, "n");
  195. }
  196. return;
  197.     }
  198.     if ((cur->content == NULL) && (cur->children == NULL)) {
  199.         if ((info != NULL) && (info->endTag != 0))
  200.     xmlBufferWriteChar(buf, ">");
  201. else {
  202.     xmlBufferWriteChar(buf, "></");
  203.     xmlBufferWriteCHAR(buf, cur->name);
  204.     xmlBufferWriteChar(buf, ">");
  205. }
  206. if (cur->next != NULL) {
  207.     if ((cur->next->type != HTML_TEXT_NODE) &&
  208. (cur->next->type != HTML_ENTITY_REF_NODE))
  209. xmlBufferWriteChar(buf, "n");
  210. }
  211. return;
  212.     }
  213.     xmlBufferWriteChar(buf, ">");
  214.     if (cur->content != NULL) {
  215. xmlChar *buffer;
  216. #ifndef XML_USE_BUFFER_CONTENT
  217.     buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
  218. #else
  219.     buffer = xmlEncodeEntitiesReentrant(doc, 
  220.                                         xmlBufferContent(cur->content));
  221. #endif
  222. if (buffer != NULL) {
  223.     xmlBufferWriteCHAR(buf, buffer);
  224.     xmlFree(buffer);
  225. }
  226.     }
  227.     if (cur->children != NULL) {
  228.         if ((cur->children->type != HTML_TEXT_NODE) &&
  229.     (cur->children->type != HTML_ENTITY_REF_NODE) &&
  230.     (cur->children != cur->last))
  231.     xmlBufferWriteChar(buf, "n");
  232. htmlNodeListDump(buf, doc, cur->children);
  233.         if ((cur->last->type != HTML_TEXT_NODE) &&
  234.     (cur->last->type != HTML_ENTITY_REF_NODE) &&
  235.     (cur->children != cur->last))
  236.     xmlBufferWriteChar(buf, "n");
  237.     }
  238.     if (!htmlIsAutoClosed(doc, cur)) {
  239. xmlBufferWriteChar(buf, "</");
  240. xmlBufferWriteCHAR(buf, cur->name);
  241. xmlBufferWriteChar(buf, ">");
  242.     }
  243.     if (cur->next != NULL) {
  244.         if ((cur->next->type != HTML_TEXT_NODE) &&
  245.     (cur->next->type != HTML_ENTITY_REF_NODE))
  246.     xmlBufferWriteChar(buf, "n");
  247.     }
  248. }
  249. /**
  250.  * htmlNodeDumpFile:
  251.  * @out:  the FILE pointer
  252.  * @doc:  the document
  253.  * @cur:  the current node
  254.  *
  255.  * Dump an HTML node, recursive behaviour,children are printed too.
  256.  */
  257. void
  258. htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
  259.     xmlBufferPtr buf;
  260.     buf = xmlBufferCreate();
  261.     if (buf == NULL) return;
  262.     htmlNodeDump(buf, doc, cur);
  263.     xmlBufferDump(out, buf);
  264.     xmlBufferFree(buf);
  265. }
  266. /**
  267.  * htmlDocContentDump:
  268.  * @buf:  the HTML buffer output
  269.  * @cur:  the document
  270.  *
  271.  * Dump an HTML document.
  272.  */
  273. static void
  274. htmlDocContentDump(xmlBufferPtr buf, xmlDocPtr cur) {
  275.     int type;
  276.     /*
  277.      * force to output the stuff as HTML, especially for entities
  278.      */
  279.     type = cur->type;
  280.     cur->type = XML_HTML_DOCUMENT_NODE;
  281.     if (cur->intSubset != NULL)
  282.         htmlDtdDump(buf, cur);
  283.     else {
  284. /* Default to HTML-4.0 transitionnal @@@@ */
  285. xmlBufferWriteChar(buf, "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">");
  286.     }
  287.     if (cur->children != NULL) {
  288.         htmlNodeListDump(buf, cur, cur->children);
  289.     }
  290.     xmlBufferWriteChar(buf, "n");
  291.     cur->type = type;
  292. }
  293. /**
  294.  * htmlDocDumpMemory:
  295.  * @cur:  the document
  296.  * @mem:  OUT: the memory pointer
  297.  * @size:  OUT: the memory lenght
  298.  *
  299.  * Dump an HTML document in memory and return the xmlChar * and it's size.
  300.  * It's up to the caller to free the memory.
  301.  */
  302. void
  303. htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
  304.     xmlBufferPtr buf;
  305.     if (cur == NULL) {
  306. #ifdef DEBUG_TREE
  307.         fprintf(stderr, "htmlxmlDocDumpMemory : document == NULLn");
  308. #endif
  309. *mem = NULL;
  310. *size = 0;
  311. return;
  312.     }
  313.     buf = xmlBufferCreate();
  314.     if (buf == NULL) {
  315. *mem = NULL;
  316. *size = 0;
  317. return;
  318.     }
  319.     htmlDocContentDump(buf, cur);
  320.     *mem = buf->content;
  321.     *size = buf->use;
  322.     memset(buf, -1, sizeof(xmlBuffer));
  323.     xmlFree(buf);
  324. }
  325. /**
  326.  * htmlDocDump:
  327.  * @f:  the FILE*
  328.  * @cur:  the document
  329.  *
  330.  * Dump an HTML document to an open FILE.
  331.  */
  332. void
  333. htmlDocDump(FILE *f, xmlDocPtr cur) {
  334.     xmlBufferPtr buf;
  335.     if (cur == NULL) {
  336. #ifdef DEBUG_TREE
  337.         fprintf(stderr, "htmlDocDump : document == NULLn");
  338. #endif
  339. return;
  340.     }
  341.     buf = xmlBufferCreate();
  342.     if (buf == NULL) return;
  343.     htmlDocContentDump(buf, cur);
  344.     xmlBufferDump(f, buf);
  345.     xmlBufferFree(buf);
  346. }
  347. /**
  348.  * htmlSaveFile:
  349.  * @filename:  the filename
  350.  * @cur:  the document
  351.  *
  352.  * Dump an HTML document to a file.
  353.  * 
  354.  * returns: the number of byte written or -1 in case of failure.
  355.  */
  356. int
  357. htmlSaveFile(const char *filename, xmlDocPtr cur) {
  358.     xmlBufferPtr buf;
  359.     FILE *output = NULL;
  360.     int ret;
  361.     /* 
  362.      * save the content to a temp buffer.
  363.      */
  364.     buf = xmlBufferCreate();
  365.     if (buf == NULL) return(0);
  366.     htmlDocContentDump(buf, cur);
  367.     output = fopen(filename, "w");
  368.     if (output == NULL) return(-1);
  369.     ret = xmlBufferDump(output, buf);
  370.     fclose(output);
  371.     xmlBufferFree(buf);
  372.     return(ret * sizeof(xmlChar));
  373. }
  374. #endif /* LIBXML_HTML_ENABLED */