📄 xmlsave.c
字号:
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);}/** * 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);} *//** * 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; if ((ctxt == NULL) || (doc == NULL)) return(-1); 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; if ((ctxt == NULL) || (node == NULL)) return(-1); 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 { cur++; } } if (base != cur) xmlBufferAdd(buf, base, cur - base);}/** * xmlNodeDump: * @buf: the XML buffer output * @doc: the document * @cur: the current node * @level: the imbrication level for indenting * @format: is formatting allowed * * Dump an XML node, recursive behaviour,children are printed too. * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1 * or xmlKeepBlanksDefault(0) was called * * Returns the number of bytes written to the buffer or -1 in case of error */intxmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level, int format){ unsigned int use; int ret; xmlOutputBufferPtr outbuf; xmlInitParser(); if (cur == NULL) {#ifdef DEBUG_TREE xmlGenericError(xmlGenericErrorContext, "xmlNodeDump : node == NULL\n");#endif return (-1); } if (buf == NULL) {#ifdef DEBUG_TREE xmlGenericError(xmlGenericErrorContext, "xmlNodeDump : buf == NULL\n");#endif return (-1); } outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer)); if (outbuf == NULL) { xmlSaveErrMemory("creating buffer"); return (-1); } memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer)); outbuf->buffer = buf; outbuf->encoder = NULL; outbuf->writecallback = NULL; outbuf->closecallback = NULL; outbuf->context = NULL; outbuf->written = 0; use = buf->use; xmlNodeDumpOutput(outbuf, doc, cur, level, format, NULL); xmlFree(outbuf); ret = buf->use - use; return (ret);}/** * xmlElemDump: * @f: the FILE * for the output * @doc: the document * @cur: the current node * * Dump an XML/HTML node, recursive behaviour, children are printed too. */voidxmlElemDump(FILE * f, xmlDocPtr doc, xmlNodePtr cur){ xmlOutputBufferPtr outbuf; xmlInitParser(); if (cur == NULL) {#ifdef DEBUG_TREE xmlGenericError(xmlGenericErrorContext, "xmlElemDump : cur == NULL\n");#endif return; }#ifdef DEBUG_TREE if (doc == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlElemDump : doc == NULL\n"); }#endif outbuf = xmlOutputBufferCreateFile(f, NULL); if (outbuf == NULL) return; if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {#ifdef LIBXML_HTML_ENABLED htmlNodeDumpOutput(outbuf, doc, cur, NULL);#else xmlSaveErr(XML_ERR_INTERNAL_ERROR, cur, "HTML support not compiled in\n");#endif /* LIBXML_HTML_ENABLED */ } else xmlNodeDumpOutput(outbuf, doc, cur, 0, 1, NULL); xmlOutputBufferClose(outbuf);}/************************************************************************ * * * Saving functions front-ends * * * ************************************************************************//** * xmlNodeDumpOutput: * @buf: the XML buffer output * @doc: the document * @cur: the current node
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -