ReactOS 0.4.15-dev-8092-ge0ba2f3
HTMLtree.c
Go to the documentation of this file.
1/*
2 * HTMLtree.c : implementation of access function for an HTML tree.
3 *
4 * See Copyright for the status of this software.
5 *
6 * daniel@veillard.com
7 */
8
9
10#define IN_LIBXML
11#include "libxml.h"
12#ifdef LIBXML_HTML_ENABLED
13
14#include <string.h> /* for memset() only ! */
15#include <ctype.h>
16#include <stdlib.h>
17
18#include <libxml/xmlmemory.h>
19#include <libxml/HTMLparser.h>
20#include <libxml/HTMLtree.h>
21#include <libxml/entities.h>
22#include <libxml/valid.h>
23#include <libxml/xmlerror.h>
25#include <libxml/globals.h>
26#include <libxml/uri.h>
27
28#include "buf.h"
29
30/************************************************************************
31 * *
32 * Getting/Setting encoding meta tags *
33 * *
34 ************************************************************************/
35
44const xmlChar *
45htmlGetMetaEncoding(htmlDocPtr doc) {
46 htmlNodePtr cur;
47 const xmlChar *content;
48 const xmlChar *encoding;
49
50 if (doc == NULL)
51 return(NULL);
52 cur = doc->children;
53
54 /*
55 * Search the html
56 */
57 while (cur != NULL) {
58 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
59 if (xmlStrEqual(cur->name, BAD_CAST"html"))
60 break;
61 if (xmlStrEqual(cur->name, BAD_CAST"head"))
62 goto found_head;
63 if (xmlStrEqual(cur->name, BAD_CAST"meta"))
64 goto found_meta;
65 }
66 cur = cur->next;
67 }
68 if (cur == NULL)
69 return(NULL);
70 cur = cur->children;
71
72 /*
73 * Search the head
74 */
75 while (cur != NULL) {
76 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
77 if (xmlStrEqual(cur->name, BAD_CAST"head"))
78 break;
79 if (xmlStrEqual(cur->name, BAD_CAST"meta"))
80 goto found_meta;
81 }
82 cur = cur->next;
83 }
84 if (cur == NULL)
85 return(NULL);
86found_head:
87 cur = cur->children;
88
89 /*
90 * Search the meta elements
91 */
92found_meta:
93 while (cur != NULL) {
94 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
95 if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
96 xmlAttrPtr attr = cur->properties;
97 int http;
98 const xmlChar *value;
99
100 content = NULL;
101 http = 0;
102 while (attr != NULL) {
103 if ((attr->children != NULL) &&
104 (attr->children->type == XML_TEXT_NODE) &&
105 (attr->children->next == NULL)) {
106 value = attr->children->content;
107 if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
108 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
109 http = 1;
110 else if ((value != NULL)
111 && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
112 content = value;
113 if ((http != 0) && (content != NULL))
114 goto found_content;
115 }
116 attr = attr->next;
117 }
118 }
119 }
120 cur = cur->next;
121 }
122 return(NULL);
123
124found_content:
125 encoding = xmlStrstr(content, BAD_CAST"charset=");
126 if (encoding == NULL)
127 encoding = xmlStrstr(content, BAD_CAST"Charset=");
128 if (encoding == NULL)
129 encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
130 if (encoding != NULL) {
131 encoding += 8;
132 } else {
133 encoding = xmlStrstr(content, BAD_CAST"charset =");
134 if (encoding == NULL)
135 encoding = xmlStrstr(content, BAD_CAST"Charset =");
136 if (encoding == NULL)
137 encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
138 if (encoding != NULL)
139 encoding += 9;
140 }
141 if (encoding != NULL) {
142 while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
143 }
144 return(encoding);
145}
146
158int
159htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
160 htmlNodePtr cur, meta = NULL, head = NULL;
161 const xmlChar *content = NULL;
162 char newcontent[100];
163
164 newcontent[0] = 0;
165
166 if (doc == NULL)
167 return(-1);
168
169 /* html isn't a real encoding it's just libxml2 way to get entities */
170 if (!xmlStrcasecmp(encoding, BAD_CAST "html"))
171 return(-1);
172
173 if (encoding != NULL) {
174 snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
175 (char *)encoding);
176 newcontent[sizeof(newcontent) - 1] = 0;
177 }
178
179 cur = doc->children;
180
181 /*
182 * Search the html
183 */
184 while (cur != NULL) {
185 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
186 if (xmlStrcasecmp(cur->name, BAD_CAST"html") == 0)
187 break;
188 if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
189 goto found_head;
190 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
191 goto found_meta;
192 }
193 cur = cur->next;
194 }
195 if (cur == NULL)
196 return(-1);
197 cur = cur->children;
198
199 /*
200 * Search the head
201 */
202 while (cur != NULL) {
203 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
204 if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
205 break;
206 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
207 head = cur->parent;
208 goto found_meta;
209 }
210 }
211 cur = cur->next;
212 }
213 if (cur == NULL)
214 return(-1);
215found_head:
216 head = cur;
217 if (cur->children == NULL)
218 goto create;
219 cur = cur->children;
220
221found_meta:
222 /*
223 * Search and update all the remaining the meta elements carrying
224 * encoding information
225 */
226 while (cur != NULL) {
227 if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
228 if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
229 xmlAttrPtr attr = cur->properties;
230 int http;
231 const xmlChar *value;
232
233 content = NULL;
234 http = 0;
235 while (attr != NULL) {
236 if ((attr->children != NULL) &&
237 (attr->children->type == XML_TEXT_NODE) &&
238 (attr->children->next == NULL)) {
239 value = attr->children->content;
240 if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
241 && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
242 http = 1;
243 else
244 {
245 if ((value != NULL) &&
246 (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
247 content = value;
248 }
249 if ((http != 0) && (content != NULL))
250 break;
251 }
252 attr = attr->next;
253 }
254 if ((http != 0) && (content != NULL)) {
255 meta = cur;
256 break;
257 }
258
259 }
260 }
261 cur = cur->next;
262 }
263create:
264 if (meta == NULL) {
265 if ((encoding != NULL) && (head != NULL)) {
266 /*
267 * Create a new Meta element with the right attributes
268 */
269
270 meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
271 if (head->children == NULL)
272 xmlAddChild(head, meta);
273 else
274 xmlAddPrevSibling(head->children, meta);
275 xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
276 xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
277 }
278 } else {
279 /* remove the meta tag if NULL is passed */
280 if (encoding == NULL) {
281 xmlUnlinkNode(meta);
282 xmlFreeNode(meta);
283 }
284 /* change the document only if there is a real encoding change */
285 else if (xmlStrcasestr(content, encoding) == NULL) {
286 xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent);
287 }
288 }
289
290
291 return(0);
292}
293
302static const char* const htmlBooleanAttrs[] = {
303 "checked", "compact", "declare", "defer", "disabled", "ismap",
304 "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
305 "selected", NULL
306};
307
308
317int
318htmlIsBooleanAttr(const xmlChar *name)
319{
320 int i = 0;
321
322 while (htmlBooleanAttrs[i] != NULL) {
323 if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0)
324 return 1;
325 i++;
326 }
327 return 0;
328}
329
330#ifdef LIBXML_OUTPUT_ENABLED
331/*
332 * private routine exported from xmlIO.c
333 */
335xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
336/************************************************************************
337 * *
338 * Output error handlers *
339 * *
340 ************************************************************************/
347static void
348htmlSaveErrMemory(const char *extra)
349{
350 __xmlSimpleError(XML_FROM_OUTPUT, XML_ERR_NO_MEMORY, NULL, NULL, extra);
351}
352
361static void
362htmlSaveErr(int code, xmlNodePtr node, const char *extra)
363{
364 const char *msg = NULL;
365
366 switch(code) {
368 msg = "string is not in UTF-8\n";
369 break;
371 msg = "invalid character value\n";
372 break;
374 msg = "unknown encoding %s\n";
375 break;
377 msg = "HTML has no DOCTYPE\n";
378 break;
379 default:
380 msg = "unexpected error number\n";
381 }
382 __xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra);
383}
384
385/************************************************************************
386 * *
387 * Dumping HTML tree content to a simple buffer *
388 * *
389 ************************************************************************/
390
402static size_t
403htmlBufNodeDumpFormat(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur,
404 int format) {
405 size_t use;
406 int ret;
407 xmlOutputBufferPtr outbuf;
408
409 if (cur == NULL) {
410 return (-1);
411 }
412 if (buf == NULL) {
413 return (-1);
414 }
415 outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
416 if (outbuf == NULL) {
417 htmlSaveErrMemory("allocating HTML output buffer");
418 return (-1);
419 }
420 memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
421 outbuf->buffer = buf;
422 outbuf->encoder = NULL;
423 outbuf->writecallback = NULL;
424 outbuf->closecallback = NULL;
425 outbuf->context = NULL;
426 outbuf->written = 0;
427
428 use = xmlBufUse(buf);
429 htmlNodeDumpFormatOutput(outbuf, doc, cur, NULL, format);
430 xmlFree(outbuf);
431 ret = xmlBufUse(buf) - use;
432 return (ret);
433}
434
446int
447htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
449 size_t ret;
450
451 if ((buf == NULL) || (cur == NULL))
452 return(-1);
453
456 if (buffer == NULL)
457 return(-1);
458
459 ret = htmlBufNodeDumpFormat(buffer, doc, cur, 1);
460
462
463 if (ret > INT_MAX)
464 return(-1);
465 return((int) ret);
466}
467
482int
483htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
484 xmlNodePtr cur, const char *encoding, int format) {
487 int ret;
488
490
491 if (encoding != NULL) {
492 xmlCharEncoding enc;
493
495 if (enc != XML_CHAR_ENCODING_UTF8) {
497 if (handler == NULL)
499 }
500 } else {
501 /*
502 * Fallback to HTML or ASCII when the encoding is unspecified
503 */
504 if (handler == NULL)
506 if (handler == NULL)
508 }
509
510 /*
511 * save the content to a temp buffer.
512 */
513 buf = xmlOutputBufferCreateFile(out, handler);
514 if (buf == NULL) return(0);
515
516 htmlNodeDumpFormatOutput(buf, doc, cur, NULL, format);
517
518 ret = xmlOutputBufferClose(buf);
519 return(ret);
520}
521
531void
532htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
533 htmlNodeDumpFileFormat(out, doc, cur, NULL, 1);
534}
535
546void
547htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
550 const char *encoding;
551
553
554 if ((mem == NULL) || (size == NULL))
555 return;
556 if (cur == NULL) {
557 *mem = NULL;
558 *size = 0;
559 return;
560 }
561
562 encoding = (const char *) htmlGetMetaEncoding(cur);
563
564 if (encoding != NULL) {
565 xmlCharEncoding enc;
566
568 if (enc != XML_CHAR_ENCODING_UTF8) {
570 if (handler == NULL)
572
573 }
574 } else {
575 /*
576 * Fallback to HTML or ASCII when the encoding is unspecified
577 */
578 if (handler == NULL)
580 if (handler == NULL)
582 }
583
584 buf = xmlAllocOutputBufferInternal(handler);
585 if (buf == NULL) {
586 *mem = NULL;
587 *size = 0;
588 return;
589 }
590
591 htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
592
593 xmlOutputBufferFlush(buf);
594 if (buf->conv != NULL) {
595 *size = xmlBufUse(buf->conv);
596 *mem = xmlStrndup(xmlBufContent(buf->conv), *size);
597 } else {
598 *size = xmlBufUse(buf->buffer);
599 *mem = xmlStrndup(xmlBufContent(buf->buffer), *size);
600 }
601 (void)xmlOutputBufferClose(buf);
602}
603
613void
614htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
615 htmlDocDumpMemoryFormat(cur, mem, size, 1);
616}
617
618
619/************************************************************************
620 * *
621 * Dumping HTML tree content to an I/O output buffer *
622 * *
623 ************************************************************************/
624
625void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
626
637static void
638htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
639 const char *encoding ATTRIBUTE_UNUSED) {
640 xmlDtdPtr cur = doc->intSubset;
641
642 if (cur == NULL) {
643 htmlSaveErr(XML_SAVE_NO_DOCTYPE, (xmlNodePtr) doc, NULL);
644 return;
645 }
646 xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
647 xmlOutputBufferWriteString(buf, (const char *)cur->name);
648 if (cur->ExternalID != NULL) {
649 xmlOutputBufferWriteString(buf, " PUBLIC ");
650 xmlBufWriteQuotedString(buf->buffer, cur->ExternalID);
651 if (cur->SystemID != NULL) {
652 xmlOutputBufferWriteString(buf, " ");
653 xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
654 }
655 } else if (cur->SystemID != NULL &&
656 xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
657 xmlOutputBufferWriteString(buf, " SYSTEM ");
658 xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
659 }
660 xmlOutputBufferWriteString(buf, ">\n");
661}
662
671static void
672htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) {
673 xmlChar *value;
674
675 /*
676 * The html output method should not escape a & character
677 * occurring in an attribute value immediately followed by
678 * a { character (see Section B.7.1 of the HTML 4.0 Recommendation).
679 * This is implemented in xmlEncodeEntitiesReentrant
680 */
681
682 if (cur == NULL) {
683 return;
684 }
685 xmlOutputBufferWriteString(buf, " ");
686 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
687 xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
688 xmlOutputBufferWriteString(buf, ":");
689 }
690 xmlOutputBufferWriteString(buf, (const char *)cur->name);
691 if ((cur->children != NULL) && (!htmlIsBooleanAttr(cur->name))) {
692 value = xmlNodeListGetString(doc, cur->children, 0);
693 if (value) {
694 xmlOutputBufferWriteString(buf, "=");
695 if ((cur->ns == NULL) && (cur->parent != NULL) &&
696 (cur->parent->ns == NULL) &&
697 ((!xmlStrcasecmp(cur->name, BAD_CAST "href")) ||
698 (!xmlStrcasecmp(cur->name, BAD_CAST "action")) ||
699 (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
700 ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
701 (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
702 xmlChar *escaped;
703 xmlChar *tmp = value;
704
705 while (IS_BLANK_CH(*tmp)) tmp++;
706
707 /*
708 * the < and > have already been escaped at the entity level
709 * And doing so here breaks server side includes
710 */
711 escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>");
712 if (escaped != NULL) {
713 xmlBufWriteQuotedString(buf->buffer, escaped);
714 xmlFree(escaped);
715 } else {
717 }
718 } else {
720 }
721 xmlFree(value);
722 } else {
723 xmlOutputBufferWriteString(buf, "=\"\"");
724 }
725 }
726}
727
738void
739htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
741 int format) {
744 const htmlElemDesc * info;
745
747
748 if ((cur == NULL) || (buf == NULL)) {
749 return;
750 }
751
752 root = cur;
753 parent = cur->parent;
754 while (1) {
755 switch (cur->type) {
758 if (((xmlDocPtr) cur)->intSubset != NULL) {
759 htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL);
760 }
761 if (cur->children != NULL) {
762 /* Always validate cur->parent when descending. */
763 if (cur->parent == parent) {
764 parent = cur;
765 cur = cur->children;
766 continue;
767 }
768 } else {
769 xmlOutputBufferWriteString(buf, "\n");
770 }
771 break;
772
773 case XML_ELEMENT_NODE:
774 /*
775 * Some users like lxml are known to pass nodes with a corrupted
776 * tree structure. Fall back to a recursive call to handle this
777 * case.
778 */
779 if ((cur->parent != parent) && (cur->children != NULL)) {
780 htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
781 break;
782 }
783
784 /*
785 * Get specific HTML info for that node.
786 */
787 if (cur->ns == NULL)
788 info = htmlTagLookup(cur->name);
789 else
790 info = NULL;
791
792 xmlOutputBufferWriteString(buf, "<");
793 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
794 xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
795 xmlOutputBufferWriteString(buf, ":");
796 }
797 xmlOutputBufferWriteString(buf, (const char *)cur->name);
798 if (cur->nsDef)
799 xmlNsListDumpOutput(buf, cur->nsDef);
800 attr = cur->properties;
801 while (attr != NULL) {
802 htmlAttrDumpOutput(buf, doc, attr);
803 attr = attr->next;
804 }
805
806 if ((info != NULL) && (info->empty)) {
807 xmlOutputBufferWriteString(buf, ">");
808 } else if (cur->children == NULL) {
809 if ((info != NULL) && (info->saveEndTag != 0) &&
810 (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) &&
811 (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) {
812 xmlOutputBufferWriteString(buf, ">");
813 } else {
814 xmlOutputBufferWriteString(buf, "></");
815 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
816 xmlOutputBufferWriteString(buf,
817 (const char *)cur->ns->prefix);
818 xmlOutputBufferWriteString(buf, ":");
819 }
820 xmlOutputBufferWriteString(buf, (const char *)cur->name);
821 xmlOutputBufferWriteString(buf, ">");
822 }
823 } else {
824 xmlOutputBufferWriteString(buf, ">");
825 if ((format) && (info != NULL) && (!info->isinline) &&
826 (cur->children->type != HTML_TEXT_NODE) &&
827 (cur->children->type != HTML_ENTITY_REF_NODE) &&
828 (cur->children != cur->last) &&
829 (cur->name != NULL) &&
830 (cur->name[0] != 'p')) /* p, pre, param */
831 xmlOutputBufferWriteString(buf, "\n");
832 parent = cur;
833 cur = cur->children;
834 continue;
835 }
836
837 if ((format) && (cur->next != NULL) &&
838 (info != NULL) && (!info->isinline)) {
839 if ((cur->next->type != HTML_TEXT_NODE) &&
840 (cur->next->type != HTML_ENTITY_REF_NODE) &&
841 (parent != NULL) &&
842 (parent->name != NULL) &&
843 (parent->name[0] != 'p')) /* p, pre, param */
844 xmlOutputBufferWriteString(buf, "\n");
845 }
846
847 break;
848
850 htmlAttrDumpOutput(buf, doc, (xmlAttrPtr) cur);
851 break;
852
853 case HTML_TEXT_NODE:
854 if (cur->content == NULL)
855 break;
856 if (((cur->name == (const xmlChar *)xmlStringText) ||
857 (cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
858 ((parent == NULL) ||
859 ((xmlStrcasecmp(parent->name, BAD_CAST "script")) &&
860 (xmlStrcasecmp(parent->name, BAD_CAST "style"))))) {
862
863 buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
864 if (buffer != NULL) {
865 xmlOutputBufferWriteString(buf, (const char *)buffer);
867 }
868 } else {
869 xmlOutputBufferWriteString(buf, (const char *)cur->content);
870 }
871 break;
872
873 case HTML_COMMENT_NODE:
874 if (cur->content != NULL) {
875 xmlOutputBufferWriteString(buf, "<!--");
876 xmlOutputBufferWriteString(buf, (const char *)cur->content);
877 xmlOutputBufferWriteString(buf, "-->");
878 }
879 break;
880
881 case HTML_PI_NODE:
882 if (cur->name != NULL) {
883 xmlOutputBufferWriteString(buf, "<?");
884 xmlOutputBufferWriteString(buf, (const char *)cur->name);
885 if (cur->content != NULL) {
886 xmlOutputBufferWriteString(buf, " ");
887 xmlOutputBufferWriteString(buf,
888 (const char *)cur->content);
889 }
890 xmlOutputBufferWriteString(buf, ">");
891 }
892 break;
893
894 case HTML_ENTITY_REF_NODE:
895 xmlOutputBufferWriteString(buf, "&");
896 xmlOutputBufferWriteString(buf, (const char *)cur->name);
897 xmlOutputBufferWriteString(buf, ";");
898 break;
899
900 case HTML_PRESERVE_NODE:
901 if (cur->content != NULL) {
902 xmlOutputBufferWriteString(buf, (const char *)cur->content);
903 }
904 break;
905
906 default:
907 break;
908 }
909
910 while (1) {
911 if (cur == root)
912 return;
913 if (cur->next != NULL) {
914 cur = cur->next;
915 break;
916 }
917
918 cur = parent;
919 /* cur->parent was validated when descending. */
920 parent = cur->parent;
921
922 if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
923 (cur->type == XML_DOCUMENT_NODE)) {
924 xmlOutputBufferWriteString(buf, "\n");
925 } else {
926 if ((format) && (cur->ns == NULL))
927 info = htmlTagLookup(cur->name);
928 else
929 info = NULL;
930
931 if ((format) && (info != NULL) && (!info->isinline) &&
932 (cur->last->type != HTML_TEXT_NODE) &&
933 (cur->last->type != HTML_ENTITY_REF_NODE) &&
934 (cur->children != cur->last) &&
935 (cur->name != NULL) &&
936 (cur->name[0] != 'p')) /* p, pre, param */
937 xmlOutputBufferWriteString(buf, "\n");
938
939 xmlOutputBufferWriteString(buf, "</");
940 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
941 xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
942 xmlOutputBufferWriteString(buf, ":");
943 }
944 xmlOutputBufferWriteString(buf, (const char *)cur->name);
945 xmlOutputBufferWriteString(buf, ">");
946
947 if ((format) && (info != NULL) && (!info->isinline) &&
948 (cur->next != NULL)) {
949 if ((cur->next->type != HTML_TEXT_NODE) &&
950 (cur->next->type != HTML_ENTITY_REF_NODE) &&
951 (parent != NULL) &&
952 (parent->name != NULL) &&
953 (parent->name[0] != 'p')) /* p, pre, param */
954 xmlOutputBufferWriteString(buf, "\n");
955 }
956 }
957 }
958 }
959}
960
971void
972htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
974 htmlNodeDumpFormatOutput(buf, doc, cur, NULL, 1);
975}
976
986void
987htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
988 const char *encoding ATTRIBUTE_UNUSED,
989 int format) {
990 int type = 0;
991 if (cur) {
992 type = cur->type;
994 }
995 htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, format);
996 if (cur)
997 cur->type = (xmlElementType) type;
998}
999
1008void
1009htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
1010 const char *encoding ATTRIBUTE_UNUSED) {
1011 htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, 1);
1012}
1013
1014/************************************************************************
1015 * *
1016 * Saving functions front-ends *
1017 * *
1018 ************************************************************************/
1019
1029int
1030htmlDocDump(FILE *f, xmlDocPtr cur) {
1033 const char *encoding;
1034 int ret;
1035
1036 xmlInitParser();
1037
1038 if ((cur == NULL) || (f == NULL)) {
1039 return(-1);
1040 }
1041
1042 encoding = (const char *) htmlGetMetaEncoding(cur);
1043
1044 if (encoding != NULL) {
1045 xmlCharEncoding enc;
1046
1048 if (enc != XML_CHAR_ENCODING_UTF8) {
1050 if (handler == NULL)
1052 }
1053 } else {
1054 /*
1055 * Fallback to HTML or ASCII when the encoding is unspecified
1056 */
1057 if (handler == NULL)
1059 if (handler == NULL)
1061 }
1062
1063 buf = xmlOutputBufferCreateFile(f, handler);
1064 if (buf == NULL) return(-1);
1065 htmlDocContentDumpOutput(buf, cur, NULL);
1066
1067 ret = xmlOutputBufferClose(buf);
1068 return(ret);
1069}
1070
1080int
1081htmlSaveFile(const char *filename, xmlDocPtr cur) {
1084 const char *encoding;
1085 int ret;
1086
1087 if ((cur == NULL) || (filename == NULL))
1088 return(-1);
1089
1090 xmlInitParser();
1091
1092 encoding = (const char *) htmlGetMetaEncoding(cur);
1093
1094 if (encoding != NULL) {
1095 xmlCharEncoding enc;
1096
1098 if (enc != XML_CHAR_ENCODING_UTF8) {
1100 if (handler == NULL)
1102 }
1103 } else {
1104 /*
1105 * Fallback to HTML or ASCII when the encoding is unspecified
1106 */
1107 if (handler == NULL)
1109 if (handler == NULL)
1111 }
1112
1113 /*
1114 * save the content to a temp buffer.
1115 */
1116 buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
1117 if (buf == NULL) return(0);
1118
1119 htmlDocContentDumpOutput(buf, cur, NULL);
1120
1121 ret = xmlOutputBufferClose(buf);
1122 return(ret);
1123}
1124
1136int
1137htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
1138 const char *encoding, int format) {
1141 int ret;
1142
1143 if ((cur == NULL) || (filename == NULL))
1144 return(-1);
1145
1146 xmlInitParser();
1147
1148 if (encoding != NULL) {
1149 xmlCharEncoding enc;
1150
1152 if (enc != XML_CHAR_ENCODING_UTF8) {
1154 if (handler == NULL)
1156 }
1157 htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
1158 } else {
1159 htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
1160
1161 /*
1162 * Fallback to HTML or ASCII when the encoding is unspecified
1163 */
1164 if (handler == NULL)
1166 if (handler == NULL)
1168 }
1169
1170 /*
1171 * save the content to a temp buffer.
1172 */
1173 buf = xmlOutputBufferCreateFilename(filename, handler, 0);
1174 if (buf == NULL) return(0);
1175
1176 htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
1177
1178 ret = xmlOutputBufferClose(buf);
1179 return(ret);
1180}
1181
1193int
1194htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
1195 return(htmlSaveFileFormat(filename, cur, encoding, 1));
1196}
1197
1198#endif /* LIBXML_OUTPUT_ENABLED */
1199
1200#endif /* LIBXML_HTML_ENABLED */
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define msg(x)
Definition: auth_time.c:54
struct _root root
xmlBufPtr xmlBufFromBuffer(xmlBufferPtr buffer)
Definition: buf.c:977
int xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string)
Definition: buf.c:921
xmlBufferPtr xmlBufBackToBuffer(xmlBufPtr buf)
Definition: buf.c:1013
#define NULL
Definition: types.h:112
content
Definition: atl_ax.c:994
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7482
r parent
Definition: btrfs.c:3010
XMLPUBFUN xmlCharEncodingHandlerPtr XMLCALL xmlFindCharEncodingHandler(const char *name)
Definition: encoding.c:1678
xmlCharEncoding
Definition: encoding.h:56
@ XML_CHAR_ENCODING_UTF8
Definition: encoding.h:59
XMLPUBFUN xmlCharEncoding XMLCALL xmlParseCharEncoding(const char *name)
Definition: encoding.c:1170
XMLPUBFUN xmlChar *XMLCALL xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input)
FxCollectionEntry * cur
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ATTRIBUTE_UNUSED
Definition: i386-dis.c:36
@ extra
Definition: id3.c:95
#define INT_MAX
Definition: limits.h:40
const char * filename
Definition: ioapi.h:137
static const struct access_res create[16]
Definition: package.c:7644
static WCHAR http[]
Definition: url.c:30
XMLPUBVAR const xmlChar xmlStringTextNoenc[]
XMLPUBVAR const xmlChar xmlStringText[]
#define IS_BLANK_CH(c)
static FILE * out
Definition: regtests2xml.c:44
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN void XMLCALL xmlInitParser(void)
Definition: parser.c:14676
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChild(xmlNodePtr parent, xmlNodePtr cur)
XMLPUBFUN xmlNodePtr XMLCALL xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns, const xmlChar *name, const xmlChar *content)
xmlOutputBuffer * xmlOutputBufferPtr
Definition: tree.h:32
XMLPUBFUN size_t XMLCALL xmlBufUse(const xmlBufPtr buf)
Definition: buf.c:633
struct _xmlOutputBuffer xmlOutputBuffer
Definition: tree.h:31
xmlElementType
Definition: tree.h:159
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_HTML_DOCUMENT_NODE
Definition: tree.h:172
@ XML_ELEMENT_NODE
Definition: tree.h:160
XMLPUBFUN void XMLCALL xmlUnlinkNode(xmlNodePtr cur)
XMLPUBFUN void XMLCALL xmlFreeNode(xmlNodePtr cur)
XMLPUBFUN xmlChar *XMLCALL xmlBufContent(const xmlBuf *buf)
Definition: buf.c:553
XMLPUBFUN xmlChar *XMLCALL xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
#define memset(x, y, z)
Definition: compat.h:39
Definition: tree.h:434
Definition: buf.c:43
Definition: tree.h:551
struct _xmlDtd * intSubset
Definition: tree.h:570
Definition: tree.h:406
Definition: tree.h:489
Definition: tree.h:389
Definition: cookie.c:202
WCHAR * name
Definition: cookie.c:203
Definition: inflate.c:139
Definition: mem.c:156
Definition: name.c:39
Definition: dlist.c:348
Definition: pdh_main.c:94
XMLPUBFUN xmlChar *XMLCALL xmlURIEscapeStr(const xmlChar *str, const xmlChar *list)
Definition: uri.c:1679
int ret
#define snprintf
Definition: wintirpc.h:48
@ XML_FROM_OUTPUT
Definition: xmlerror.h:44
@ XML_SAVE_CHAR_INVALID
Definition: xmlerror.h:414
@ XML_SAVE_NOT_UTF8
Definition: xmlerror.h:413
@ XML_SAVE_NO_DOCTYPE
Definition: xmlerror.h:415
@ XML_SAVE_UNKNOWN_ENCODING
Definition: xmlerror.h:416
@ XML_ERR_NO_MEMORY
Definition: xmlerror.h:102
static char * encoding
Definition: xmllint.c:155
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
XMLPUBFUN int XMLCALL xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:275
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:345
XMLPUBFUN const xmlChar *XMLCALL xmlStrcasestr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:373
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlStrcmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:133
unsigned char xmlChar
Definition: xmlstring.h:28