📄 xmlsave.c
字号:
************************************************************************/#ifdef LIBXML_HTML_ENABLEDstatic voidxhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);#endifstatic void xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);static void xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);/** * xmlNsDumpOutput: * @buf: the XML buffer output * @cur: a namespace * * Dump a local Namespace definition. * Should be called in the context of attributes dumps. */static voidxmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) { if ((cur == NULL) || (buf == NULL)) return; if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) { if (xmlStrEqual(cur->prefix, BAD_CAST "xml")) return; /* Within the context of an element attributes */ if (cur->prefix != NULL) { xmlOutputBufferWrite(buf, 7, " xmlns:"); xmlOutputBufferWriteString(buf, (const char *)cur->prefix); } else xmlOutputBufferWrite(buf, 6, " xmlns"); xmlOutputBufferWrite(buf, 1, "="); xmlBufferWriteQuotedString(buf->buffer, cur->href); }}/** * xmlNsListDumpOutput: * @buf: the XML buffer output * @cur: the first namespace * * Dump a list of local Namespace definitions. * Should be called in the context of attributes dumps. */voidxmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) { while (cur != NULL) { xmlNsDumpOutput(buf, cur); cur = cur->next; }}/** * xmlDtdDumpOutput: * @buf: the XML buffer output * @dtd: the pointer to the DTD * * Dump the XML document DTD, if any. */static voidxmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) { xmlOutputBufferPtr buf; int format, level; xmlDocPtr doc; if (dtd == NULL) return; if ((ctxt == NULL) || (ctxt->buf == NULL)) return; buf = ctxt->buf; xmlOutputBufferWrite(buf, 10, "<!DOCTYPE "); xmlOutputBufferWriteString(buf, (const char *)dtd->name); if (dtd->ExternalID != NULL) { xmlOutputBufferWrite(buf, 8, " PUBLIC "); xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID); xmlOutputBufferWrite(buf, 1, " "); xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID); } else if (dtd->SystemID != NULL) { xmlOutputBufferWrite(buf, 8, " SYSTEM "); xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID); } if ((dtd->entities == NULL) && (dtd->elements == NULL) && (dtd->attributes == NULL) && (dtd->notations == NULL) && (dtd->pentities == NULL)) { xmlOutputBufferWrite(buf, 1, ">"); return; } xmlOutputBufferWrite(buf, 3, " [\n"); /* * Dump the notations first they are not in the DTD children list * Do this only on a standalone DTD or on the internal subset though. */ if ((dtd->notations != NULL) && ((dtd->doc == NULL) || (dtd->doc->intSubset == dtd))) { xmlDumpNotationTable(buf->buffer, (xmlNotationTablePtr) dtd->notations); } format = ctxt->format; level = ctxt->level; doc = ctxt->doc; ctxt->format = 0; ctxt->level = -1; ctxt->doc = dtd->doc; xmlNodeListDumpOutput(ctxt, dtd->children); ctxt->format = format; ctxt->level = level; ctxt->doc = doc; xmlOutputBufferWrite(buf, 2, "]>");}/** * xmlAttrDumpOutput: * @buf: the XML buffer output * @cur: the attribute pointer * * Dump an XML attribute */static voidxmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { xmlOutputBufferPtr buf; if (cur == NULL) return; buf = ctxt->buf; if (buf == NULL) return; 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); xmlOutputBufferWrite(buf, 2, "=\""); xmlAttrSerializeContent(buf, cur); xmlOutputBufferWrite(buf, 1, "\"");}/** * xmlAttrListDumpOutput: * @buf: the XML buffer output * @doc: the document * @cur: the first attribute pointer * @encoding: an optional encoding string * * Dump a list of XML attributes */static voidxmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { if (cur == NULL) return; while (cur != NULL) { xmlAttrDumpOutput(ctxt, cur); cur = cur->next; }}/** * xmlNodeListDumpOutput: * @cur: the first node * * Dump an XML node list, recursive behaviour, children are printed too. */static voidxmlNodeListDumpOutput(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); xmlNodeDumpOutputInternal(ctxt, cur); if (ctxt->format) { xmlOutputBufferWrite(buf, 1, "\n"); } cur = cur->next; }}/** * xmlNodeDumpOutputInternal: * @cur: the current node * * Dump an XML node, recursive behaviour, children are printed too. */static voidxmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { int format; xmlNodePtr tmp; xmlChar *start, *end; xmlOutputBufferPtr buf; if (cur == NULL) return; buf = ctxt->buf; if (cur->type == XML_XINCLUDE_START) return; if (cur->type == XML_XINCLUDE_END) return; if ((cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_HTML_DOCUMENT_NODE)) { xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); return; } if (cur->type == XML_DTD_NODE) { xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); return; } if (cur->type == XML_DOCUMENT_FRAG_NODE) { xmlNodeListDumpOutput(ctxt, cur->children); return; } 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 != 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; } if (cur->type == XML_ATTRIBUTE_NODE) { xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur); return; } if (cur->type == XML_NAMESPACE_DECL) { xmlNsDumpOutput(buf, (xmlNsPtr) cur); return; } format = ctxt->format; if (format == 1) { tmp = cur->children; while (tmp != NULL) { if ((tmp->type == XML_TEXT_NODE) || (tmp->type == XML_CDATA_SECTION_NODE) || (tmp->type == XML_ENTITY_REF_NODE)) { ctxt->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 (cur->properties != NULL) xmlAttrListDumpOutput(ctxt, cur->properties); if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) && (cur->children == NULL) && (!xmlSaveNoEmptyTags)) { xmlOutputBufferWrite(buf, 2, "/>"); ctxt->format = format; return; } xmlOutputBufferWrite(buf, 1, ">"); if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); } if (cur->children != NULL) { if (ctxt->format) xmlOutputBufferWrite(buf, 1, "\n"); if (ctxt->level >= 0) ctxt->level++; xmlNodeListDumpOutput(ctxt, cur->children); if (ctxt->level > 0) ctxt->level--; if ((xmlIndentTreeOutput) && (ctxt->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, ">"); ctxt->format = format;}/** * xmlDocContentDumpOutput: * @cur: the document * * Dump an XML document. */static voidxmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {#ifdef LIBXML_HTML_ENABLED xmlDtdPtr dtd; int is_xhtml = 0;#endif const xmlChar *oldenc = cur->encoding; const xmlChar *encoding = ctxt->encoding; xmlOutputBufferPtr buf; xmlInitParser(); if (ctxt->encoding != NULL) cur->encoding = BAD_CAST ctxt->encoding; buf = ctxt->buf; xmlOutputBufferWrite(buf, 14, "<?xml version="); if (cur->version != NULL) xmlBufferWriteQuotedString(buf->buffer, cur->version); else xmlOutputBufferWrite(buf, 5, "\"1.0\""); if (ctxt->encoding == NULL) { if (cur->encoding != NULL) encoding = cur->encoding; else if (cur->charset != XML_CHAR_ENCODING_UTF8) encoding = (const xmlChar *) xmlGetCharEncodingName((xmlCharEncoding) cur->charset); } if (encoding != NULL) { xmlOutputBufferWrite(buf, 10, " encoding="); xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding); } switch (cur->standalone) { case 0: xmlOutputBufferWrite(buf, 16, " standalone=\"no\""); break; case 1: xmlOutputBufferWrite(buf, 17, " standalone=\"yes\""); break; } xmlOutputBufferWrite(buf, 3, "?>\n");#ifdef LIBXML_HTML_ENABLED dtd = xmlGetIntSubset(cur); if (dtd != NULL) { is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID); if (is_xhtml < 0) is_xhtml = 0; } if (is_xhtml) { if (encoding != NULL) htmlSetMetaEncoding(cur, (const xmlChar *) ctxt->encoding); else htmlSetMetaEncoding(cur, BAD_CAST "UTF-8"); }#endif if (cur->children != NULL) { xmlNodePtr child = cur->children; while (child != NULL) { ctxt->level = 0;#ifdef LIBXML_HTML_ENABLED if (is_xhtml) xhtmlNodeDumpOutput(ctxt, child); else#endif xmlNodeDumpOutputInternal(ctxt, child); xmlOutputBufferWrite(buf, 1, "\n"); child = child->next; } } if (ctxt->encoding != NULL) cur->encoding = oldenc;}#ifdef LIBXML_HTML_ENABLED/************************************************************************ * * * Functions specific to XHTML serialization * * * ************************************************************************//** * xhtmlIsEmpty: * @node: the node * * Check if a node is an empty xhtml node *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -