📄 xmlsave.c.svn-base
字号:
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; ret = xmlNewSaveCtxt(encoding, options); if (ret == NULL) return(NULL); ret->buf = xmlOutputBufferCreateFd(fd, ret->handler); if (ret->buf == NULL) { xmlFreeSaveCtxt(ret); return(NULL); } return(ret);}/** * xmlSaveToFilename: * @filename: a file name or an URL * @encoding: the encoding name to use or NULL * @options: a set of xmlSaveOptions * * Create a document saving context serializing to a filename or possibly * to an URL (but this is less reliable) with the encoding and the options * given. * * Returns a new serialization context or NULL in case of error. */xmlSaveCtxtPtrxmlSaveToFilename(const char *filename, const char *encoding, int options){ xmlSaveCtxtPtr ret; int compression = 0; /* TODO handle compression option */ ret = xmlNewSaveCtxt(encoding, options); if (ret == NULL) return(NULL); ret->buf = xmlOutputBufferCreateFilename(filename, ret->handler, compression); if (ret->buf == NULL) { xmlFreeSaveCtxt(ret); return(NULL); } return(ret);}#if 0/** * xmlSaveToBuffer: * @buffer: a buffer * @encoding: the encoding name to use or NULL * @options: a set of xmlSaveOptions * * Create a document saving context serializing to a buffer * with the encoding and the options given * * Returns a new serialization context or NULL in case of error. */xmlSaveCtxtPtrxmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options){ TODO return(NULL);}#endif/** * xmlSaveToIO: * @iowrite: an I/O write function * @ioclose: an I/O close function * @ioctx: an I/O handler * @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. */xmlSaveCtxtPtrxmlSaveToIO(xmlOutputWriteCallback iowrite, xmlOutputCloseCallback ioclose, void *ioctx, const char *encoding, int options){ xmlSaveCtxtPtr ret; ret = xmlNewSaveCtxt(encoding, options); if (ret == NULL) return(NULL); ret->buf = xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, ret->handler); if (ret->buf == NULL) { xmlFreeSaveCtxt(ret); return(NULL); } return(ret);}/** * xmlSaveDoc: * @ctxt: a document saving context * @doc: a document * * Save a full document to a saving context * TODO: The function is not fully implemented yet as it does not return the * byte count but 0 instead * * Returns the number of byte written or -1 in case of error */longxmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc){ long ret = 0; xmlDocContentDumpOutput(ctxt, doc); return(ret);}/** * xmlSaveTree: * @ctxt: a document saving context * @node: a document * * Save a subtree starting at the node parameter to a saving context * TODO: The function is not fully implemented yet as it does not return the * byte count but 0 instead * * Returns the number of byte written or -1 in case of error */longxmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node){ long ret = 0; xmlNodeDumpOutputInternal(ctxt, node); return(ret);}/** * xmlSaveFlush: * @ctxt: a document saving context * * Flush a document saving context, i.e. make sure that all bytes have * been output. * * Returns the number of byte written or -1 in case of error. */intxmlSaveFlush(xmlSaveCtxtPtr ctxt){ if (ctxt == NULL) return(-1); if (ctxt->buf == NULL) return(-1); return(xmlOutputBufferFlush(ctxt->buf));}/** * xmlSaveClose: * @ctxt: a document saving context * * Close a document saving context, i.e. make sure that all bytes have * been output and free the associated data. * * Returns the number of byte written or -1 in case of error. */intxmlSaveClose(xmlSaveCtxtPtr ctxt){ int ret; if (ctxt == NULL) return(-1); ret = xmlSaveFlush(ctxt); xmlFreeSaveCtxt(ctxt); return(ret);}/** * xmlSaveSetEscape: * @ctxt: a document saving context * @escape: the escaping function * * Set a custom escaping function to be used for text in element content * * Returns 0 if successful or -1 in case of error. */intxmlSaveSetEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape){ if (ctxt == NULL) return(-1); ctxt->escape = escape; return(0);}/** * xmlSaveSetAttrEscape: * @ctxt: a document saving context * @escape: the escaping function * * Set a custom escaping function to be used for text in attribute content * * Returns 0 if successful or -1 in case of error. */intxmlSaveSetAttrEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape){ if (ctxt == NULL) return(-1); ctxt->escapeAttr = escape; return(0);}/************************************************************************ * * * Public entry points based on buffers * * * ************************************************************************//** * xmlAttrSerializeTxtContent: * @buf: the XML buffer output * @doc: the document * @attr: the attribute node * @string: the text content * * Serialize text attribute values to an xml simple buffer */voidxmlAttrSerializeTxtContent(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr attr, const xmlChar * string){ xmlChar *base, *cur; if (string == NULL) return; base = cur = (xmlChar *) string; while (*cur != 0) { if (*cur == '\n') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST " ", 5); cur++; base = cur; } else if (*cur == '\r') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST " ", 5); cur++; base = cur; } else if (*cur == '\t') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST "	", 4); cur++; base = cur; } else if (*cur == '"') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST """, 6); cur++; base = cur; } else if (*cur == '<') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST "<", 4); cur++; base = cur; } else if (*cur == '>') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST ">", 4); cur++; base = cur; } else if (*cur == '&') { if (base != cur) xmlBufferAdd(buf, base, cur - base); xmlBufferAdd(buf, BAD_CAST "&", 5); cur++; base = cur; } else if ((*cur >= 0x80) && ((doc == NULL) || (doc->encoding == NULL))) { /* * We assume we have UTF-8 content. */ unsigned char tmp[10]; int val = 0, l = 1; if (base != cur) xmlBufferAdd(buf, base, cur - base); if (*cur < 0xC0) { xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, NULL); if (doc != NULL) doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); xmlSerializeHexCharRef(tmp, *cur); xmlBufferAdd(buf, (xmlChar *) tmp, -1); cur++; base = cur; continue; } else if (*cur < 0xE0) { val = (cur[0]) & 0x1F; val <<= 6; val |= (cur[1]) & 0x3F; l = 2; } else if (*cur < 0xF0) { val = (cur[0]) & 0x0F; val <<= 6; val |= (cur[1]) & 0x3F; val <<= 6; val |= (cur[2]) & 0x3F; l = 3; } else if (*cur < 0xF8) { val = (cur[0]) & 0x07; val <<= 6; val |= (cur[1]) & 0x3F; val <<= 6; val |= (cur[2]) & 0x3F; val <<= 6; val |= (cur[3]) & 0x3F; l = 4; } if ((l == 1) || (!IS_CHAR(val))) { xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, NULL); if (doc != NULL) doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); xmlSerializeHexCharRef(tmp, *cur); xmlBufferAdd(buf, (xmlChar *) tmp, -1); cur++; base = cur; continue; } /* * We could do multiple things here. Just save * as a char ref */ xmlSerializeHexCharRef(tmp, val); xmlBufferAdd(buf, (xmlChar *) tmp, -1); cur += l; base = cur; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -