📄 xmlsave.c
字号:
* 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; xmlNodePtr tmp; xmlChar *start, *end; xmlOutputBufferPtr buf; if (cur == NULL) 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; } 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->children == NULL)) { if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) && (xhtmlIsEmpty(cur) == 1)) { /* * C.2. Empty Elements */ xmlOutputBufferWrite(buf, 3, " />"); } else { /* * C.3. Element Minimization and Empty Element Content */ xmlOutputBufferWrite(buf, 3, "></"); 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 ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); } /* * 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) || (child->type == XML_CDATA_SECTION_NODE)) { /* * Apparently CDATA escaping for style just break on IE, * mozilla and galeon, so ... */ if (xmlStrEqual(cur->name, BAD_CAST "style") && (xmlStrchr(child->content, '<') == NULL) && (xmlStrchr(child->content, '>') == NULL) && (xmlStrchr(child->content, '&') == NULL)) { int level = ctxt->level; int indent = ctxt->format; ctxt->level = 0; ctxt->format = 0; xhtmlNodeDumpOutput(ctxt, child); ctxt->level = level; ctxt->format = indent; } else { start = end = child->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["); xmlOutputBufferWrite(buf, end - start, (const char *)start); xmlOutputBufferWrite(buf, 3, "]]>"); } } } else { int level = ctxt->level; int indent = ctxt->format; ctxt->level = 0; ctxt->format = 0; xhtmlNodeDumpOutput(ctxt, child); ctxt->level = level; ctxt->format = indent; } child = child->next; } } else if (cur->children != NULL) { int indent = ctxt->format; if (format) xmlOutputBufferWrite(buf, 1, "\n"); if (ctxt->level >= 0) ctxt->level++; ctxt->format = format; xhtmlNodeListDumpOutput(ctxt, cur->children); if (ctxt->level > 0) ctxt->level--; ctxt->format = indent; if ((xmlIndentTreeOutput) && (format)) xmlOutputBufferWrite(buf, ctxt->indent_size * (ctxt->level > ctxt->indent_nr ? ctxt->indent_nr : ctxt->level), ctxt->indent); } 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, ">");}#endif/************************************************************************ * * * Public entry points * * * ************************************************************************//** * xmlSaveToFd: * @fd: a file descriptor number * @encoding: the encoding name to use or NULL * @options: a set of xmlSaveOptions * * Create a document saving context serializing to a file descriptor * with the encoding and the options given. * * Returns a new serialization context or NULL in case of error. */xmlSaveCtxtPtrxmlSaveToFd(int fd, const char *encoding, int options){ xmlSaveCtxtPtr ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -