📄 xmlsave.c
字号:
*/ if ((encoding != NULL) && (oldctxtenc == NULL) && ((ctxt->options & XML_SAVE_NO_DECL) == 0)) { if ((enc != XML_CHAR_ENCODING_UTF8) && (enc != XML_CHAR_ENCODING_NONE) && (enc != XML_CHAR_ENCODING_ASCII)) { xmlOutputBufferFlush(buf); xmlCharEncCloseFunc(buf->encoder); xmlBufferFree(buf->conv); buf->encoder = NULL; buf->conv = NULL; } ctxt->escape = oldescape; ctxt->escapeAttr = oldescapeAttr; } return(0);}#ifdef LIBXML_HTML_ENABLED/************************************************************************ * * * Functions specific to XHTML serialization * * * ************************************************************************//** * xhtmlIsEmpty: * @node: the node * * Check if a node is an empty xhtml node * * Returns 1 if the node is an empty node, 0 if not and -1 in case of error */static intxhtmlIsEmpty(xmlNodePtr node) { if (node == NULL) return(-1); if (node->type != XML_ELEMENT_NODE) return(0); if ((node->ns != NULL) && (!xmlStrEqual(node->ns->href, XHTML_NS_NAME))) return(0); if (node->children != NULL) return(0); switch (node->name[0]) { case 'a': if (xmlStrEqual(node->name, BAD_CAST "area")) return(1); return(0); case 'b': if (xmlStrEqual(node->name, BAD_CAST "br")) return(1); if (xmlStrEqual(node->name, BAD_CAST "base")) return(1); if (xmlStrEqual(node->name, BAD_CAST "basefont")) return(1); return(0); case 'c': if (xmlStrEqual(node->name, BAD_CAST "col")) return(1); return(0); case 'f': if (xmlStrEqual(node->name, BAD_CAST "frame")) return(1); return(0); case 'h': if (xmlStrEqual(node->name, BAD_CAST "hr")) return(1); return(0); case 'i': if (xmlStrEqual(node->name, BAD_CAST "img")) return(1); if (xmlStrEqual(node->name, BAD_CAST "input")) return(1); if (xmlStrEqual(node->name, BAD_CAST "isindex")) return(1); return(0); case 'l': if (xmlStrEqual(node->name, BAD_CAST "link")) return(1); return(0); case 'm': if (xmlStrEqual(node->name, BAD_CAST "meta")) return(1); return(0); case 'p': if (xmlStrEqual(node->name, BAD_CAST "param")) return(1); return(0); } return(0);}/** * xhtmlAttrListDumpOutput: * @cur: the first attribute pointer * * Dump a list of XML attributes */static voidxhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { xmlAttrPtr xml_lang = NULL; xmlAttrPtr lang = NULL; xmlAttrPtr name = NULL; xmlAttrPtr id = NULL; xmlNodePtr parent; xmlOutputBufferPtr buf; if (cur == NULL) return; buf = ctxt->buf; parent = cur->parent; while (cur != NULL) { if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "id"))) id = cur; else if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "name"))) name = cur; else if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang"))) lang = cur; else if ((cur->ns != NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")) && (xmlStrEqual(cur->ns->prefix, BAD_CAST "xml"))) xml_lang = cur; else if ((cur->ns == NULL) && ((cur->children == NULL) || (cur->children->content == NULL) || (cur->children->content[0] == 0)) && (htmlIsBooleanAttr(cur->name))) { if (cur->children != NULL) xmlFreeNode(cur->children); cur->children = xmlNewText(cur->name); if (cur->children != NULL) cur->children->parent = (xmlNodePtr) cur; } xmlAttrDumpOutput(ctxt, cur); cur = cur->next; } /* * C.8 */ if ((name != NULL) && (id == NULL)) { if ((parent != NULL) && (parent->name != NULL) && ((xmlStrEqual(parent->name, BAD_CAST "a")) || (xmlStrEqual(parent->name, BAD_CAST "p")) || (xmlStrEqual(parent->name, BAD_CAST "div")) || (xmlStrEqual(parent->name, BAD_CAST "img")) || (xmlStrEqual(parent->name, BAD_CAST "map")) || (xmlStrEqual(parent->name, BAD_CAST "applet")) || (xmlStrEqual(parent->name, BAD_CAST "form")) || (xmlStrEqual(parent->name, BAD_CAST "frame")) || (xmlStrEqual(parent->name, BAD_CAST "iframe")))) { xmlOutputBufferWrite(buf, 5, " id=\""); xmlAttrSerializeContent(buf, name); xmlOutputBufferWrite(buf, 1, "\""); } } /* * C.7. */ if ((lang != NULL) && (xml_lang == NULL)) { xmlOutputBufferWrite(buf, 11, " xml:lang=\""); xmlAttrSerializeContent(buf, lang); xmlOutputBufferWrite(buf, 1, "\""); } else if ((xml_lang != NULL) && (lang == NULL)) { xmlOutputBufferWrite(buf, 7, " lang=\""); xmlAttrSerializeContent(buf, xml_lang); xmlOutputBufferWrite(buf, 1, "\""); }}/** * xhtmlNodeListDumpOutput: * @buf: the XML buffer output * @doc: the XHTML document * @cur: the first node * @level: the imbrication level for indenting * @format: is formatting allowed * @encoding: an optional encoding string * * Dump an XML node list, recursive behaviour, children are printed too. * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1 * or xmlKeepBlanksDefault(0) was called */static voidxhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { xmlOutputBufferPtr buf; if (cur == NULL) return; buf = ctxt->buf; while (cur != NULL) { if ((ctxt->format) && (xmlIndentTreeOutput) && (cur->type == XML_ELEMENT_NODE)) xmlOutputBufferWrite(buf, ctxt->indent_size * (ctxt->level > ctxt->indent_nr ? ctxt->indent_nr : ctxt->level), ctxt->indent); xhtmlNodeDumpOutput(ctxt, cur); if (ctxt->format) { xmlOutputBufferWrite(buf, 1, "\n"); } cur = cur->next; }}/** * xhtmlNodeDumpOutput: * @buf: the XML buffer output * @doc: the XHTML document * @cur: the current node * @level: the imbrication level for indenting * @format: is formatting allowed * @encoding: an optional encoding string * * Dump an XHTML node, recursive behaviour, children are printed too. */static voidxhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { int format, addmeta = 0; xmlNodePtr tmp; xmlChar *start, *end; xmlOutputBufferPtr buf; if (cur == NULL) return; if ((cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_HTML_DOCUMENT_NODE)) { xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); return; } if (cur->type == XML_XINCLUDE_START) return; if (cur->type == XML_XINCLUDE_END) return; if (cur->type == XML_DTD_NODE) { xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); return; } if (cur->type == XML_DOCUMENT_FRAG_NODE) { xhtmlNodeListDumpOutput(ctxt, cur->children); return; } buf = ctxt->buf; if (cur->type == XML_ELEMENT_DECL) { xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur); return; } if (cur->type == XML_ATTRIBUTE_DECL) { xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur); return; } if (cur->type == XML_ENTITY_DECL) { xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur); return; } if (cur->type == XML_TEXT_NODE) { if (cur->content != NULL) { if ((cur->name == xmlStringText) || (cur->name != xmlStringTextNoenc)) { xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); } else { /* * Disable escaping, needed for XSLT */ xmlOutputBufferWriteString(buf, (const char *) cur->content); } } return; } if (cur->type == XML_PI_NODE) { if (cur->content != NULL) { xmlOutputBufferWrite(buf, 2, "<?"); xmlOutputBufferWriteString(buf, (const char *)cur->name); if (cur->content != NULL) { xmlOutputBufferWrite(buf, 1, " "); xmlOutputBufferWriteString(buf, (const char *)cur->content); } xmlOutputBufferWrite(buf, 2, "?>"); } else { xmlOutputBufferWrite(buf, 2, "<?"); xmlOutputBufferWriteString(buf, (const char *)cur->name); xmlOutputBufferWrite(buf, 2, "?>"); } return; } if (cur->type == XML_COMMENT_NODE) { if (cur->content != NULL) { xmlOutputBufferWrite(buf, 4, "<!--"); xmlOutputBufferWriteString(buf, (const char *)cur->content); xmlOutputBufferWrite(buf, 3, "-->"); } return; } if (cur->type == XML_ENTITY_REF_NODE) { xmlOutputBufferWrite(buf, 1, "&"); xmlOutputBufferWriteString(buf, (const char *)cur->name); xmlOutputBufferWrite(buf, 1, ";"); return; } if (cur->type == XML_CDATA_SECTION_NODE) { start = end = cur->content; while (*end != '\0') { if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') { end = end + 2; xmlOutputBufferWrite(buf, 9, "<![CDATA["); xmlOutputBufferWrite(buf, end - start, (const char *)start); xmlOutputBufferWrite(buf, 3, "]]>"); start = end; } end++; } if (start != end) { xmlOutputBufferWrite(buf, 9, "<![CDATA["); xmlOutputBufferWriteString(buf, (const char *)start); xmlOutputBufferWrite(buf, 3, "]]>"); } return; } format = ctxt->format; if (format == 1) { tmp = cur->children; while (tmp != NULL) { if ((tmp->type == XML_TEXT_NODE) || (tmp->type == XML_ENTITY_REF_NODE)) { format = 0; break; } tmp = tmp->next; } } xmlOutputBufferWrite(buf, 1, "<"); if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); xmlOutputBufferWrite(buf, 1, ":"); } xmlOutputBufferWriteString(buf, (const char *)cur->name); if (cur->nsDef) xmlNsListDumpOutput(buf, cur->nsDef); if ((xmlStrEqual(cur->name, BAD_CAST "html") && (cur->ns == NULL) && (cur->nsDef == NULL))) { /* * 3.1.1. Strictly Conforming Documents A.3.1.1 3/ */ xmlOutputBufferWriteString(buf, " xmlns=\"http://www.w3.org/1999/xhtml\""); } if (cur->properties != NULL) xhtmlAttrListDumpOutput(ctxt, cur->properties); if ((cur->type == XML_ELEMENT_NODE) && (cur->parent != NULL) && (cur->parent->parent == (xmlNodePtr) cur->doc) && xmlStrEqual(cur->name, BAD_CAST"head") && xmlStrEqual(cur->parent->name, BAD_CAST"html")) { tmp = cur->children; while (tmp != NULL) { if (xmlStrEqual(tmp->name, BAD_CAST"meta")) { xmlChar *httpequiv; httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv"); if (httpequiv != NULL) { if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) { xmlFree(httpequiv); break; } xmlFree(httpequiv); } } tmp = tmp->next; } if (tmp == NULL) addmeta = 1; } if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) { if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) && ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) { /* * C.2. Empty Elements */ xmlOutputBufferWrite(buf, 3, " />"); } else { if (addmeta == 1) { xmlOutputBufferWrite(buf, 1, ">"); if (ctxt->format) { xmlOutputBufferWrite(buf, 1, "\n"); if (xmlIndentTreeOutput) xmlOutputBufferWrite(buf, ctxt->indent_size * (ctxt->level + 1 > ctxt->indent_nr ? ctxt->indent_nr : ctxt->level + 1), ctxt->indent); } xmlOutputBufferWriteString(buf, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset="); if (ctxt->encoding) { xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding); } else { xmlOutputBufferWrite(buf, 5, "UTF-8"); } xmlOutputBufferWrite(buf, 4, "\" />"); if (ctxt->format) xmlOutputBufferWrite(buf, 1, "\n"); } else { xmlOutputBufferWrite(buf, 1, ">"); } /* * C.3. Element Minimization and Empty Element Content */ xmlOutputBufferWrite(buf, 2, "</"); if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); xmlOutputBufferWrite(buf, 1, ":"); } xmlOutputBufferWriteString(buf, (const char *)cur->name); xmlOutputBufferWrite(buf, 1, ">"); } return; } xmlOutputBufferWrite(buf, 1, ">"); if (addmeta == 1) { if (ctxt->format) { xmlOutputBufferWrite(buf, 1, "\n"); if (xmlIndentTreeOutput) xmlOutputBufferWrite(buf, ctxt->indent_size * (ctxt->level + 1 > ctxt->indent_nr ? ctxt->indent_nr : ctxt->level + 1), ctxt->indent); } xmlOutputBufferWriteString(buf, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset="); if (ctxt->encoding) { xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding); } else { xmlOutputBufferWrite(buf, 5, "UTF-8"); } xmlOutputBufferWrite(buf, 4, "\" />"); } if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); }#if 0 /* * This was removed due to problems with HTML processors. * See bug #345147. */ /* * 4.8. Script and Style elements */ if ((cur->type == XML_ELEMENT_NODE) && ((xmlStrEqual(cur->name, BAD_CAST "script")) || (xmlStrEqual(cur->name, BAD_CAST "style"))) && ((cur->ns == NULL) || (xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) { xmlNodePtr child = cur->children; while (child != NULL) { if (child->type == XML_TEXT_NODE) { if ((xmlStrchr(child->content, '<') == NULL) && (xmlStrchr(child->content, '&') == NULL) && (xmlStrstr(child->content, BAD_CAST "]]>") == NULL)) { /* Nothing to escape, so just output as is... */ /* FIXME: Should we do something about "--" also? */ int level = ctxt->level; int indent = ctxt->format; ctxt->level = 0; ctxt->format = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -