📄 xmlsave.c
字号:
* @cur: the current node
* @level: the imbrication level for indenting
* @format: is formatting allowed
* @encoding: an optional encoding string
*
* 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
*/
void
xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
int level, int format, const char *encoding)
{
xmlSaveCtxt ctxt;
#ifdef LIBXML_HTML_ENABLED
xmlDtdPtr dtd;
int is_xhtml = 0;
#endif
xmlInitParser();
if ((buf == NULL) || (cur == NULL)) return;
if (encoding == NULL)
encoding = "UTF-8";
memset(&ctxt, 0, sizeof(ctxt));
ctxt.doc = doc;
ctxt.buf = buf;
ctxt.level = level;
ctxt.format = format;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
#ifdef LIBXML_HTML_ENABLED
dtd = xmlGetIntSubset(doc);
if (dtd != NULL) {
is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
if (is_xhtml < 0)
is_xhtml = 0;
if ((is_xhtml) && (cur->parent == (xmlNodePtr) doc) &&
(cur->type == XML_ELEMENT_NODE) &&
(xmlStrEqual(cur->name, BAD_CAST "html"))) {
if (encoding != NULL)
htmlSetMetaEncoding((htmlDocPtr) doc,
(const xmlChar *) encoding);
else
htmlSetMetaEncoding((htmlDocPtr) doc, BAD_CAST "UTF-8");
}
}
if (is_xhtml)
xhtmlNodeDumpOutput(&ctxt, cur);
else
#endif
xmlNodeDumpOutputInternal(&ctxt, cur);
}
/**
* xmlDocDumpFormatMemoryEnc:
* @out_doc: Document to generate XML text from
* @doc_txt_ptr: Memory pointer for allocated XML text
* @doc_txt_len: Length of the generated XML text
* @txt_encoding: Character encoding to use when generating XML text
* @format: should formatting spaces been added
*
* Dump the current DOM tree into memory using the character encoding specified
* by the caller. Note it is up to the caller of this function to free the
* allocated memory with xmlFree().
* Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
void
xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
int * doc_txt_len, const char * txt_encoding,
int format) {
xmlSaveCtxt ctxt;
int dummy = 0;
xmlOutputBufferPtr out_buff = NULL;
xmlCharEncodingHandlerPtr conv_hdlr = NULL;
if (doc_txt_len == NULL) {
doc_txt_len = &dummy; /* Continue, caller just won't get length */
}
if (doc_txt_ptr == NULL) {
*doc_txt_len = 0;
return;
}
*doc_txt_ptr = NULL;
*doc_txt_len = 0;
if (out_doc == NULL) {
/* No document, no output */
return;
}
/*
* Validate the encoding value, if provided.
* This logic is copied from xmlSaveFileEnc.
*/
if (txt_encoding == NULL)
txt_encoding = (const char *) out_doc->encoding;
if (txt_encoding != NULL) {
conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
if ( conv_hdlr == NULL ) {
xmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, (xmlNodePtr) out_doc,
txt_encoding);
return;
}
}
if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
xmlSaveErrMemory("creating buffer");
return;
}
memset(&ctxt, 0, sizeof(ctxt));
ctxt.doc = out_doc;
ctxt.buf = out_buff;
ctxt.level = 0;
ctxt.format = format;
ctxt.encoding = (const xmlChar *) txt_encoding;
xmlSaveCtxtInit(&ctxt);
xmlDocContentDumpOutput(&ctxt, out_doc);
xmlOutputBufferFlush(out_buff);
if (out_buff->conv != NULL) {
*doc_txt_len = out_buff->conv->use;
*doc_txt_ptr = xmlStrndup(out_buff->conv->content, *doc_txt_len);
} else {
*doc_txt_len = out_buff->buffer->use;
*doc_txt_ptr = xmlStrndup(out_buff->buffer->content, *doc_txt_len);
}
(void)xmlOutputBufferClose(out_buff);
if ((*doc_txt_ptr == NULL) && (*doc_txt_len > 0)) {
*doc_txt_len = 0;
xmlSaveErrMemory("creating output");
}
return;
}
/**
* xmlDocDumpMemory:
* @cur: the document
* @mem: OUT: the memory pointer
* @size: OUT: the memory length
*
* Dump an XML document in memory and return the #xmlChar * and it's size
* in bytes. It's up to the caller to free the memory with xmlFree().
* The resulting byte array is zero terminated, though the last 0 is not
* included in the returned size.
*/
void
xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
}
/**
* xmlDocDumpFormatMemory:
* @cur: the document
* @mem: OUT: the memory pointer
* @size: OUT: the memory length
* @format: should formatting spaces been added
*
*
* Dump an XML document in memory and return the #xmlChar * and it's size.
* It's up to the caller to free the memory with xmlFree().
* Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
void
xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
}
/**
* xmlDocDumpMemoryEnc:
* @out_doc: Document to generate XML text from
* @doc_txt_ptr: Memory pointer for allocated XML text
* @doc_txt_len: Length of the generated XML text
* @txt_encoding: Character encoding to use when generating XML text
*
* Dump the current DOM tree into memory using the character encoding specified
* by the caller. Note it is up to the caller of this function to free the
* allocated memory with xmlFree().
*/
void
xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
int * doc_txt_len, const char * txt_encoding) {
xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
txt_encoding, 0);
}
/**
* xmlDocFormatDump:
* @f: the FILE*
* @cur: the document
* @format: should formatting spaces been added
*
* Dump an XML document to an open FILE.
*
* returns: the number of bytes written or -1 in case of failure.
* Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
int
xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
xmlSaveCtxt ctxt;
xmlOutputBufferPtr buf;
const char * encoding;
xmlCharEncodingHandlerPtr handler = NULL;
int ret;
if (cur == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlDocDump : document == NULL\n");
#endif
return(-1);
}
encoding = (const char *) cur->encoding;
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL) {
xmlFree((char *) cur->encoding);
cur->encoding = NULL;
}
}
buf = xmlOutputBufferCreateFile(f, handler);
if (buf == NULL) return(-1);
memset(&ctxt, 0, sizeof(ctxt));
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
ctxt.format = format;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
xmlDocContentDumpOutput(&ctxt, cur);
ret = xmlOutputBufferClose(buf);
return(ret);
}
/**
* xmlDocDump:
* @f: the FILE*
* @cur: the document
*
* Dump an XML document to an open FILE.
*
* returns: the number of bytes written or -1 in case of failure.
*/
int
xmlDocDump(FILE *f, xmlDocPtr cur) {
return(xmlDocFormatDump (f, cur, 0));
}
/**
* xmlSaveFileTo:
* @buf: an output I/O buffer
* @cur: the document
* @encoding: the encoding if any assuming the I/O layer handles the trancoding
*
* Dump an XML document to an I/O buffer.
* Warning ! This call xmlOutputBufferClose() on buf which is not available
* after this call.
*
* returns: the number of bytes written or -1 in case of failure.
*/
int
xmlSaveFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
xmlSaveCtxt ctxt;
int ret;
if (buf == NULL) return(-1);
if (cur == NULL) {
xmlOutputBufferClose(buf);
return(-1);
}
memset(&ctxt, 0, sizeof(ctxt));
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
ctxt.format = 0;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
xmlDocContentDumpOutput(&ctxt, cur);
ret = xmlOutputBufferClose(buf);
return(ret);
}
/**
* xmlSaveFormatFileTo:
* @buf: an output I/O buffer
* @cur: the document
* @encoding: the encoding if any assuming the I/O layer handles the trancoding
* @format: should formatting spaces been added
*
* Dump an XML document to an I/O buffer.
* Warning ! This call xmlOutputBufferClose() on buf which is not available
* after this call.
*
* returns: the number of bytes written or -1 in case of failure.
*/
int
xmlSaveFormatFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur,
const char *encoding, int format)
{
xmlSaveCtxt ctxt;
int ret;
if (buf == NULL) return(-1);
if ((cur == NULL) ||
((cur->type != XML_DOCUMENT_NODE) &&
(cur->type != XML_HTML_DOCUMENT_NODE))) {
xmlOutputBufferClose(buf);
return(-1);
}
memset(&ctxt, 0, sizeof(ctxt));
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
ctxt.format = format;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
xmlDocContentDumpOutput(&ctxt, cur);
ret = xmlOutputBufferClose(buf);
return (ret);
}
/**
* xmlSaveFormatFileEnc:
* @filename: the filename or URL to output
* @cur: the document being saved
* @encoding: the name of the encoding to use or NULL.
* @format: should formatting spaces be added.
*
* Dump an XML document to a file or an URL.
*
* Returns the number of bytes written or -1 in case of error.
* Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*/
int
xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur,
const char * encoding, int format ) {
xmlSaveCtxt ctxt;
xmlOutputBufferPtr buf;
xmlCharEncodingHandlerPtr handler = NULL;
int ret;
if (cur == NULL)
return(-1);
if (encoding == NULL)
encoding = (const char *) cur->encoding;
if (encoding != NULL) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL)
return(-1);
}
#ifdef HAVE_ZLIB_H
if (cur->compression < 0) cur->compression = xmlGetCompressMode();
#endif
/*
* save the content to a temp buffer.
*/
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
if (buf == NULL) return(-1);
memset(&ctxt, 0, sizeof(ctxt));
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
ctxt.format = format;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
xmlDocContentDumpOutput(&ctxt, cur);
ret = xmlOutputBufferClose(buf);
return(ret);
}
/**
* xmlSaveFileEnc:
* @filename: the filename (or URL)
* @cur: the document
* @encoding: the name of an encoding (or NULL)
*
* Dump an XML document, converting it to the given encoding
*
* returns: the number of bytes written or -1 in case of failure.
*/
int
xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
return ( xmlSaveFormatFileEnc( filename, cur, encoding, 0 ) );
}
/**
* xmlSaveFormatFile:
* @filename: the filename (or URL)
* @cur: the document
* @format: should formatting spaces been added
*
* Dump an XML document to a file. Will use compression if
* compiled in and enabled. If @filename is "-" the stdout file is
* used. If @format is set then the document will be indented on output.
* Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
* or xmlKeepBlanksDefault(0) was called
*
* returns: the number of bytes written or -1 in case of failure.
*/
int
xmlSaveFormatFile(const char *filename, xmlDocPtr cur, int format) {
return ( xmlSaveFormatFileEnc( filename, cur, NULL, format ) );
}
/**
* xmlSaveFile:
* @filename: the filename (or URL)
* @cur: the document
*
* Dump an XML document to a file. Will use compression if
* compiled in and enabled. If @filename is "-" the stdout file is
* used.
* returns: the number of bytes written or -1 in case of failure.
*/
int
xmlSaveFile(const char *filename, xmlDocPtr cur) {
return(xmlSaveFormatFileEnc(filename, cur, NULL, 0));
}
#endif /* LIBXML_OUTPUT_ENABLED */
#define bottom_xmlsave
#include "elfgcchack.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -