2004-03-04 13:40:59 +00:00
/*
* xmlsave . c : Implemetation of the document serializer
*
* See Copyright for the status of this software .
*
* daniel @ veillard . com
*/
# define IN_LIBXML
# include "libxml.h"
# include <string.h>
# include <libxml/xmlmemory.h>
# include <libxml/parserInternals.h>
# include <libxml/tree.h>
# include <libxml/xmlsave.h>
2004-03-28 16:12:44 +00:00
# define MAX_INDENT 60
2004-04-30 23:11:45 +00:00
# include <libxml/HTMLtree.h>
2012-07-16 14:52:00 +08:00
# include "buf.h"
# include "enc.h"
# include "save.h"
2004-03-04 13:40:59 +00:00
/************************************************************************
* *
* XHTML detection *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define XHTML_STRICT_PUBLIC_ID BAD_CAST \
" -//W3C//DTD XHTML 1.0 Strict//EN "
# define XHTML_STRICT_SYSTEM_ID BAD_CAST \
" http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd "
# define XHTML_FRAME_PUBLIC_ID BAD_CAST \
" -//W3C//DTD XHTML 1.0 Frameset//EN "
# define XHTML_FRAME_SYSTEM_ID BAD_CAST \
" http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd "
# define XHTML_TRANS_PUBLIC_ID BAD_CAST \
" -//W3C//DTD XHTML 1.0 Transitional//EN "
# define XHTML_TRANS_SYSTEM_ID BAD_CAST \
" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd "
# define XHTML_NS_NAME BAD_CAST "http: //www.w3.org/1999/xhtml"
/**
* xmlIsXHTML :
* @ systemID : the system identifier
* @ publicID : the public identifier
*
* Try to find if the document correspond to an XHTML DTD
*
* Returns 1 if true , 0 if not and - 1 in case of error
*/
int
xmlIsXHTML ( const xmlChar * systemID , const xmlChar * publicID ) {
if ( ( systemID = = NULL ) & & ( publicID = = NULL ) )
return ( - 1 ) ;
if ( publicID ! = NULL ) {
if ( xmlStrEqual ( publicID , XHTML_STRICT_PUBLIC_ID ) ) return ( 1 ) ;
if ( xmlStrEqual ( publicID , XHTML_FRAME_PUBLIC_ID ) ) return ( 1 ) ;
if ( xmlStrEqual ( publicID , XHTML_TRANS_PUBLIC_ID ) ) return ( 1 ) ;
}
if ( systemID ! = NULL ) {
if ( xmlStrEqual ( systemID , XHTML_STRICT_SYSTEM_ID ) ) return ( 1 ) ;
if ( xmlStrEqual ( systemID , XHTML_FRAME_SYSTEM_ID ) ) return ( 1 ) ;
if ( xmlStrEqual ( systemID , XHTML_TRANS_SYSTEM_ID ) ) return ( 1 ) ;
}
return ( 0 ) ;
}
# ifdef LIBXML_OUTPUT_ENABLED
2012-09-11 13:26:36 +08:00
# define TODO \
2004-03-04 13:40:59 +00:00
xmlGenericError ( xmlGenericErrorContext , \
" Unimplemented block at %s:%d \n " , \
__FILE__ , __LINE__ ) ;
struct _xmlSaveCtxt {
void * _private ;
int type ;
int fd ;
const xmlChar * filename ;
const xmlChar * encoding ;
xmlCharEncodingHandlerPtr handler ;
2004-03-15 13:46:37 +00:00
xmlOutputBufferPtr buf ;
xmlDocPtr doc ;
2004-03-04 13:40:59 +00:00
int options ;
int level ;
2004-03-15 13:46:37 +00:00
int format ;
2004-05-15 18:57:31 +00:00
char indent [ MAX_INDENT + 1 ] ; /* array for indenting output */
2004-03-28 16:12:44 +00:00
int indent_nr ;
int indent_size ;
2004-05-15 18:57:31 +00:00
xmlCharEncodingOutputFunc escape ; /* used for element content */
xmlCharEncodingOutputFunc escapeAttr ; /* used for attribute content */
2004-03-04 13:40:59 +00:00
} ;
/************************************************************************
* *
2012-09-11 13:26:36 +08:00
* Output error handlers *
2004-03-04 13:40:59 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSaveErrMemory :
* @ extra : extra informations
*
* Handle an out of memory condition
*/
static void
xmlSaveErrMemory ( const char * extra )
{
__xmlSimpleError ( XML_FROM_OUTPUT , XML_ERR_NO_MEMORY , NULL , NULL , extra ) ;
}
/**
* xmlSaveErr :
* @ code : the error number
* @ node : the location of the error .
* @ extra : extra informations
*
* Handle an out of memory condition
*/
static void
xmlSaveErr ( int code , xmlNodePtr node , const char * extra )
{
const char * msg = NULL ;
switch ( code ) {
case XML_SAVE_NOT_UTF8 :
2006-08-15 23:14:24 +00:00
msg = " string is not in UTF-8 \n " ;
2004-03-04 13:40:59 +00:00
break ;
case XML_SAVE_CHAR_INVALID :
2006-08-15 23:14:24 +00:00
msg = " invalid character value \n " ;
2004-03-04 13:40:59 +00:00
break ;
case XML_SAVE_UNKNOWN_ENCODING :
2006-08-15 23:14:24 +00:00
msg = " unknown encoding %s \n " ;
2004-03-04 13:40:59 +00:00
break ;
case XML_SAVE_NO_DOCTYPE :
2006-08-15 23:14:24 +00:00
msg = " document has no DOCTYPE \n " ;
2004-03-04 13:40:59 +00:00
break ;
default :
2006-08-15 23:14:24 +00:00
msg = " unexpected error number \n " ;
2004-03-04 13:40:59 +00:00
}
__xmlSimpleError ( XML_FROM_OUTPUT , code , node , msg , extra ) ;
}
2004-05-14 21:50:42 +00:00
/************************************************************************
* *
* Special escaping routines *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-05-15 16:37:50 +00:00
static unsigned char *
xmlSerializeHexCharRef ( unsigned char * out , int val ) {
unsigned char * ptr ;
* out + + = ' & ' ;
* out + + = ' # ' ;
* out + + = ' x ' ;
if ( val < 0x10 ) ptr = out ;
else if ( val < 0x100 ) ptr = out + 1 ;
else if ( val < 0x1000 ) ptr = out + 2 ;
else if ( val < 0x10000 ) ptr = out + 3 ;
else if ( val < 0x100000 ) ptr = out + 4 ;
else ptr = out + 5 ;
out = ptr + 1 ;
while ( val > 0 ) {
switch ( val & 0xF ) {
case 0 : * ptr - - = ' 0 ' ; break ;
case 1 : * ptr - - = ' 1 ' ; break ;
case 2 : * ptr - - = ' 2 ' ; break ;
case 3 : * ptr - - = ' 3 ' ; break ;
case 4 : * ptr - - = ' 4 ' ; break ;
case 5 : * ptr - - = ' 5 ' ; break ;
case 6 : * ptr - - = ' 6 ' ; break ;
case 7 : * ptr - - = ' 7 ' ; break ;
case 8 : * ptr - - = ' 8 ' ; break ;
case 9 : * ptr - - = ' 9 ' ; break ;
case 0xA : * ptr - - = ' A ' ; break ;
case 0xB : * ptr - - = ' B ' ; break ;
case 0xC : * ptr - - = ' C ' ; break ;
case 0xD : * ptr - - = ' D ' ; break ;
case 0xE : * ptr - - = ' E ' ; break ;
case 0xF : * ptr - - = ' F ' ; break ;
default : * ptr - - = ' 0 ' ; break ;
}
val > > = 4 ;
}
* out + + = ' ; ' ;
* out = 0 ;
return ( out ) ;
}
2004-05-14 21:50:42 +00:00
/**
* xmlEscapeEntities :
* @ out : a pointer to an array of bytes to store the result
* @ outlen : the length of @ out
* @ in : a pointer to an array of unescaped UTF - 8 bytes
* @ inlen : the length of @ in
*
* Take a block of UTF - 8 chars in and escape them . Used when there is no
* encoding specified .
*
* Returns 0 if success , or - 1 otherwise
* The value of @ inlen after return is the number of octets consumed
* if the return value is positive , else unpredictable .
* The value of @ outlen after return is the number of octets consumed .
*/
static int
xmlEscapeEntities ( unsigned char * out , int * outlen ,
const xmlChar * in , int * inlen ) {
unsigned char * outstart = out ;
const unsigned char * base = in ;
unsigned char * outend = out + * outlen ;
const unsigned char * inend ;
int val ;
inend = in + ( * inlen ) ;
2012-09-11 13:26:36 +08:00
2004-05-14 21:50:42 +00:00
while ( ( in < inend ) & & ( out < outend ) ) {
2012-09-11 13:26:36 +08:00
if ( * in = = ' < ' ) {
2004-05-14 21:50:42 +00:00
if ( outend - out < 4 ) break ;
* out + + = ' & ' ;
* out + + = ' l ' ;
* out + + = ' t ' ;
* out + + = ' ; ' ;
in + + ;
continue ;
} else if ( * in = = ' > ' ) {
if ( outend - out < 4 ) break ;
* out + + = ' & ' ;
* out + + = ' g ' ;
* out + + = ' t ' ;
* out + + = ' ; ' ;
in + + ;
continue ;
} else if ( * in = = ' & ' ) {
if ( outend - out < 5 ) break ;
* out + + = ' & ' ;
* out + + = ' a ' ;
* out + + = ' m ' ;
* out + + = ' p ' ;
* out + + = ' ; ' ;
in + + ;
continue ;
} else if ( ( ( * in > = 0x20 ) & & ( * in < 0x80 ) ) | |
( * in = = ' \n ' ) | | ( * in = = ' \t ' ) ) {
/*
* default case , just copy !
*/
* out + + = * in + + ;
continue ;
} else if ( * in > = 0x80 ) {
/*
* We assume we have UTF - 8 input .
*/
2012-01-22 17:42:35 +08:00
if ( outend - out < 11 ) break ;
2004-05-14 21:50:42 +00:00
if ( * in < 0xC0 ) {
2004-05-15 16:37:50 +00:00
xmlSaveErr ( XML_SAVE_NOT_UTF8 , NULL , NULL ) ;
2004-05-14 21:50:42 +00:00
in + + ;
goto error ;
} else if ( * in < 0xE0 ) {
if ( inend - in < 2 ) break ;
val = ( in [ 0 ] ) & 0x1F ;
val < < = 6 ;
val | = ( in [ 1 ] ) & 0x3F ;
in + = 2 ;
} else if ( * in < 0xF0 ) {
if ( inend - in < 3 ) break ;
val = ( in [ 0 ] ) & 0x0F ;
val < < = 6 ;
val | = ( in [ 1 ] ) & 0x3F ;
val < < = 6 ;
val | = ( in [ 2 ] ) & 0x3F ;
in + = 3 ;
} else if ( * in < 0xF8 ) {
if ( inend - in < 4 ) break ;
val = ( in [ 0 ] ) & 0x07 ;
val < < = 6 ;
val | = ( in [ 1 ] ) & 0x3F ;
val < < = 6 ;
val | = ( in [ 2 ] ) & 0x3F ;
val < < = 6 ;
val | = ( in [ 3 ] ) & 0x3F ;
in + = 4 ;
} else {
2004-05-15 16:37:50 +00:00
xmlSaveErr ( XML_SAVE_CHAR_INVALID , NULL , NULL ) ;
2004-05-14 21:50:42 +00:00
in + + ;
goto error ;
}
if ( ! IS_CHAR ( val ) ) {
2004-05-15 16:37:50 +00:00
xmlSaveErr ( XML_SAVE_CHAR_INVALID , NULL , NULL ) ;
2004-05-14 21:50:42 +00:00
in + + ;
goto error ;
}
/*
* We could do multiple things here . Just save as a char ref
*/
2004-05-15 16:37:50 +00:00
out = xmlSerializeHexCharRef ( out , val ) ;
2004-05-14 21:50:42 +00:00
} else if ( IS_BYTE_CHAR ( * in ) ) {
if ( outend - out < 6 ) break ;
2004-05-15 16:37:50 +00:00
out = xmlSerializeHexCharRef ( out , * in + + ) ;
2004-05-14 21:50:42 +00:00
} else {
xmlGenericError ( xmlGenericErrorContext ,
" xmlEscapeEntities : char out of range \n " ) ;
in + + ;
goto error ;
}
}
* outlen = out - outstart ;
* inlen = in - base ;
return ( 0 ) ;
error :
* outlen = out - outstart ;
* inlen = in - base ;
return ( - 1 ) ;
}
2004-03-04 13:40:59 +00:00
/************************************************************************
* *
* Allocation and deallocation *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-03-28 16:12:44 +00:00
/**
* xmlSaveCtxtInit :
* @ ctxt : the saving context
*
* Initialize a saving context
*/
static void
xmlSaveCtxtInit ( xmlSaveCtxtPtr ctxt )
{
int i ;
2005-02-21 13:54:07 +00:00
int len ;
2004-03-28 16:12:44 +00:00
if ( ctxt = = NULL ) return ;
2004-05-15 18:57:31 +00:00
if ( ( ctxt - > encoding = = NULL ) & & ( ctxt - > escape = = NULL ) )
ctxt - > escape = xmlEscapeEntities ;
2005-02-21 13:54:07 +00:00
len = xmlStrlen ( ( xmlChar * ) xmlTreeIndentString ) ;
if ( ( xmlTreeIndentString = = NULL ) | | ( len = = 0 ) ) {
2004-03-28 16:12:44 +00:00
memset ( & ctxt - > indent [ 0 ] , 0 , MAX_INDENT + 1 ) ;
} else {
2005-02-21 13:54:07 +00:00
ctxt - > indent_size = len ;
2004-03-28 16:12:44 +00:00
ctxt - > indent_nr = MAX_INDENT / ctxt - > indent_size ;
for ( i = 0 ; i < ctxt - > indent_nr ; i + + )
memcpy ( & ctxt - > indent [ i * ctxt - > indent_size ] , xmlTreeIndentString ,
ctxt - > indent_size ) ;
ctxt - > indent [ ctxt - > indent_nr * ctxt - > indent_size ] = 0 ;
}
2005-09-12 12:16:35 +00:00
2005-11-09 08:56:26 +00:00
if ( xmlSaveNoEmptyTags ) {
ctxt - > options | = XML_SAVE_NO_EMPTY ;
}
2004-03-28 16:12:44 +00:00
}
2004-03-04 13:40:59 +00:00
/**
* xmlFreeSaveCtxt :
*
* Free a saving context , destroying the ouptut in any remaining buffer
*/
static void
xmlFreeSaveCtxt ( xmlSaveCtxtPtr ctxt )
{
if ( ctxt = = NULL ) return ;
if ( ctxt - > encoding ! = NULL )
xmlFree ( ( char * ) ctxt - > encoding ) ;
2004-04-29 17:14:25 +00:00
if ( ctxt - > buf ! = NULL )
xmlOutputBufferClose ( ctxt - > buf ) ;
2004-03-04 13:40:59 +00:00
xmlFree ( ctxt ) ;
}
/**
* xmlNewSaveCtxt :
*
* Create a new saving context
*
* Returns the new structure or NULL in case of error
*/
static xmlSaveCtxtPtr
xmlNewSaveCtxt ( const char * encoding , int options )
{
xmlSaveCtxtPtr ret ;
ret = ( xmlSaveCtxtPtr ) xmlMalloc ( sizeof ( xmlSaveCtxt ) ) ;
if ( ret = = NULL ) {
xmlSaveErrMemory ( " creating saving context " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSaveCtxt ) ) ;
2005-01-16 00:05:58 +00:00
2004-03-04 13:40:59 +00:00
if ( encoding ! = NULL ) {
ret - > handler = xmlFindCharEncodingHandler ( encoding ) ;
if ( ret - > handler = = NULL ) {
xmlSaveErr ( XML_SAVE_UNKNOWN_ENCODING , NULL , encoding ) ;
xmlFreeSaveCtxt ( ret ) ;
return ( NULL ) ;
}
ret - > encoding = xmlStrdup ( ( const xmlChar * ) encoding ) ;
2006-10-16 23:22:10 +00:00
ret - > escape = NULL ;
2004-03-04 13:40:59 +00:00
}
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( ret ) ;
2005-09-12 12:16:35 +00:00
/*
* Use the options
*/
2005-11-09 08:56:26 +00:00
/* Re-check this option as it may already have been set */
if ( ( ret - > options & XML_SAVE_NO_EMPTY ) & & ! ( options & XML_SAVE_NO_EMPTY ) ) {
options | = XML_SAVE_NO_EMPTY ;
}
2005-09-12 12:16:35 +00:00
ret - > options = options ;
if ( options & XML_SAVE_FORMAT )
ret - > format = 1 ;
2010-11-03 15:33:40 +01:00
else if ( options & XML_SAVE_WSNONSIG )
ret - > format = 2 ;
2005-09-12 12:16:35 +00:00
2004-03-04 13:40:59 +00:00
return ( ret ) ;
}
/************************************************************************
* *
2012-09-11 13:26:36 +08:00
* Dumping XML tree content to a simple buffer *
2004-03-04 13:40:59 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlAttrSerializeContent :
* @ buf : the XML buffer output
* @ doc : the document
* @ attr : the attribute pointer
*
* Serialize the attribute in the buffer
*/
static void
2004-05-15 16:37:50 +00:00
xmlAttrSerializeContent ( xmlOutputBufferPtr buf , xmlAttrPtr attr )
2004-03-04 13:40:59 +00:00
{
xmlNodePtr children ;
children = attr - > children ;
while ( children ! = NULL ) {
switch ( children - > type ) {
case XML_TEXT_NODE :
2012-07-16 14:52:00 +08:00
xmlBufAttrSerializeTxtContent ( buf - > buffer , attr - > doc ,
attr , children - > content ) ;
2004-03-04 13:40:59 +00:00
break ;
case XML_ENTITY_REF_NODE :
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf - > buffer , BAD_CAST " & " , 1 ) ;
xmlBufAdd ( buf - > buffer , children - > name ,
2004-03-04 13:40:59 +00:00
xmlStrlen ( children - > name ) ) ;
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf - > buffer , BAD_CAST " ; " , 1 ) ;
2004-03-04 13:40:59 +00:00
break ;
default :
/* should not happen unless we have a badly built tree */
break ;
}
children = children - > next ;
}
}
2012-07-16 14:52:00 +08:00
/**
* xmlBufDumpNotationTable :
* @ buf : an xmlBufPtr output
* @ table : A notation table
*
* This will dump the content of the notation table as an XML DTD definition
*/
void
xmlBufDumpNotationTable ( xmlBufPtr buf , xmlNotationTablePtr table ) {
xmlBufferPtr buffer ;
buffer = xmlBufferCreate ( ) ;
if ( buffer = = NULL ) {
/*
* TODO set the error in buf
*/
return ;
}
xmlDumpNotationTable ( buffer , table ) ;
xmlBufMergeBuffer ( buf , buffer ) ;
}
/**
* xmlBufDumpElementDecl :
* @ buf : an xmlBufPtr output
* @ elem : An element table
*
* This will dump the content of the element declaration as an XML
* DTD definition
*/
void
xmlBufDumpElementDecl ( xmlBufPtr buf , xmlElementPtr elem ) {
xmlBufferPtr buffer ;
buffer = xmlBufferCreate ( ) ;
if ( buffer = = NULL ) {
/*
* TODO set the error in buf
*/
return ;
}
xmlDumpElementDecl ( buffer , elem ) ;
xmlBufMergeBuffer ( buf , buffer ) ;
}
/**
* xmlBufDumpAttributeDecl :
* @ buf : an xmlBufPtr output
* @ attr : An attribute declaration
*
* This will dump the content of the attribute declaration as an XML
* DTD definition
*/
void
xmlBufDumpAttributeDecl ( xmlBufPtr buf , xmlAttributePtr attr ) {
xmlBufferPtr buffer ;
buffer = xmlBufferCreate ( ) ;
if ( buffer = = NULL ) {
/*
* TODO set the error in buf
*/
return ;
}
xmlDumpAttributeDecl ( buffer , attr ) ;
xmlBufMergeBuffer ( buf , buffer ) ;
}
/**
* xmlBufDumpEntityDecl :
* @ buf : an xmlBufPtr output
* @ ent : An entity table
*
* This will dump the content of the entity table as an XML DTD definition
*/
void
xmlBufDumpEntityDecl ( xmlBufPtr buf , xmlEntityPtr ent ) {
xmlBufferPtr buffer ;
buffer = xmlBufferCreate ( ) ;
if ( buffer = = NULL ) {
/*
* TODO set the error in buf
*/
return ;
}
xmlDumpEntityDecl ( buffer , ent ) ;
xmlBufMergeBuffer ( buf , buffer ) ;
}
2004-03-04 13:40:59 +00:00
/************************************************************************
* *
2012-09-11 13:26:36 +08:00
* Dumping XML tree content to an I / O output buffer *
2004-03-04 13:40:59 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-01 13:08:57 +00:00
static int xmlSaveSwitchEncoding ( xmlSaveCtxtPtr ctxt , const char * encoding ) {
xmlOutputBufferPtr buf = ctxt - > buf ;
if ( ( encoding ! = NULL ) & & ( buf - > encoder = = NULL ) & & ( buf - > conv = = NULL ) ) {
buf - > encoder = xmlFindCharEncodingHandler ( ( const char * ) encoding ) ;
if ( buf - > encoder = = NULL ) {
xmlSaveErr ( XML_SAVE_UNKNOWN_ENCODING , NULL ,
( const char * ) encoding ) ;
return ( - 1 ) ;
}
2012-07-16 14:52:00 +08:00
buf - > conv = xmlBufCreate ( ) ;
2008-09-01 13:08:57 +00:00
if ( buf - > conv = = NULL ) {
xmlCharEncCloseFunc ( buf - > encoder ) ;
xmlSaveErrMemory ( " creating encoding buffer " ) ;
return ( - 1 ) ;
}
/*
* initialize the state , e . g . if outputting a BOM
*/
2012-07-16 14:52:00 +08:00
xmlCharEncOutput ( buf , 1 ) ;
2008-09-01 13:08:57 +00:00
}
return ( 0 ) ;
}
static int xmlSaveClearEncoding ( xmlSaveCtxtPtr ctxt ) {
xmlOutputBufferPtr buf = ctxt - > buf ;
xmlOutputBufferFlush ( buf ) ;
xmlCharEncCloseFunc ( buf - > encoder ) ;
2012-07-16 14:52:00 +08:00
xmlBufFree ( buf - > conv ) ;
2008-09-01 13:08:57 +00:00
buf - > encoder = NULL ;
buf - > conv = NULL ;
return ( 0 ) ;
}
2004-03-04 13:40:59 +00:00
# ifdef LIBXML_HTML_ENABLED
static void
2004-03-15 13:46:37 +00:00
xhtmlNodeDumpOutput ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) ;
2004-03-04 13:40:59 +00:00
# endif
2004-03-15 13:46:37 +00:00
static void xmlNodeListDumpOutput ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) ;
static void xmlNodeDumpOutputInternal ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) ;
2004-03-04 13:40:59 +00:00
void xmlNsListDumpOutput ( xmlOutputBufferPtr buf , xmlNsPtr cur ) ;
2006-10-16 23:22:10 +00:00
static int xmlDocContentDumpOutput ( xmlSaveCtxtPtr ctxt , xmlDocPtr cur ) ;
2004-03-04 13:40:59 +00:00
2010-11-03 15:33:40 +01:00
/**
* xmlOutputBufferWriteWSNonSig :
* @ ctxt : The save context
* @ extra : Number of extra indents to apply to ctxt - > level
*
* Write out formatting for non - significant whitespace output .
*/
static void
xmlOutputBufferWriteWSNonSig ( xmlSaveCtxtPtr ctxt , int extra )
{
int i ;
if ( ( ctxt = = NULL ) | | ( ctxt - > buf = = NULL ) )
return ;
xmlOutputBufferWrite ( ctxt - > buf , 1 , " \n " ) ;
for ( i = 0 ; i < ( ctxt - > level + extra ) ; i + = ctxt - > indent_nr ) {
xmlOutputBufferWrite ( ctxt - > buf , ctxt - > indent_size *
( ( ctxt - > level + extra - i ) > ctxt - > indent_nr ?
ctxt - > indent_nr : ( ctxt - > level + extra - i ) ) ,
ctxt - > indent ) ;
}
}
2004-03-04 13:40:59 +00:00
/**
* xmlNsDumpOutput :
* @ buf : the XML buffer output
* @ cur : a namespace
2010-11-03 15:33:40 +01:00
* @ ctxt : the output save context . Optional .
2004-03-04 13:40:59 +00:00
*
* Dump a local Namespace definition .
* Should be called in the context of attributes dumps .
2010-11-03 15:33:40 +01:00
* If @ ctxt is supplied , @ buf should be its buffer .
2004-03-04 13:40:59 +00:00
*/
static void
2010-11-03 15:33:40 +01:00
xmlNsDumpOutput ( xmlOutputBufferPtr buf , xmlNsPtr cur , xmlSaveCtxtPtr ctxt ) {
2004-11-05 10:03:46 +00:00
if ( ( cur = = NULL ) | | ( buf = = NULL ) ) return ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > type = = XML_LOCAL_NAMESPACE ) & & ( cur - > href ! = NULL ) ) {
if ( xmlStrEqual ( cur - > prefix , BAD_CAST " xml " ) )
return ;
2010-11-03 15:33:40 +01:00
if ( ctxt ! = NULL & & ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 2 ) ;
else
xmlOutputBufferWrite ( buf , 1 , " " ) ;
2004-03-04 13:40:59 +00:00
/* Within the context of an element attributes */
if ( cur - > prefix ! = NULL ) {
2010-11-03 15:33:40 +01:00
xmlOutputBufferWrite ( buf , 6 , " xmlns: " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > prefix ) ;
} else
2010-11-03 15:33:40 +01:00
xmlOutputBufferWrite ( buf , 5 , " xmlns " ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " = " ) ;
2012-07-16 14:52:00 +08:00
xmlBufWriteQuotedString ( buf - > buffer , cur - > href ) ;
2004-03-04 13:40:59 +00:00
}
}
2010-11-03 15:33:40 +01:00
/**
* xmlNsDumpOutputCtxt
* @ ctxt : the save context
* @ cur : a namespace
*
* Dump a local Namespace definition to a save context .
* Should be called in the context of attribute dumps .
*/
static void
xmlNsDumpOutputCtxt ( xmlSaveCtxtPtr ctxt , xmlNsPtr cur ) {
xmlNsDumpOutput ( ctxt - > buf , cur , ctxt ) ;
}
/**
* xmlNsListDumpOutputCtxt
* @ ctxt : the save context
* @ cur : the first namespace
*
* Dump a list of local namespace definitions to a save context .
* Should be called in the context of attribute dumps .
*/
static void
xmlNsListDumpOutputCtxt ( xmlSaveCtxtPtr ctxt , xmlNsPtr cur ) {
while ( cur ! = NULL ) {
xmlNsDumpOutput ( ctxt - > buf , cur , ctxt ) ;
cur = cur - > next ;
}
}
2004-03-04 13:40:59 +00:00
/**
* 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 .
*/
void
xmlNsListDumpOutput ( xmlOutputBufferPtr buf , xmlNsPtr cur ) {
while ( cur ! = NULL ) {
2010-11-03 15:33:40 +01:00
xmlNsDumpOutput ( buf , cur , NULL ) ;
2004-03-04 13:40:59 +00:00
cur = cur - > next ;
}
}
/**
* xmlDtdDumpOutput :
* @ buf : the XML buffer output
2004-03-15 13:46:37 +00:00
* @ dtd : the pointer to the DTD
2012-09-11 13:26:36 +08:00
*
2004-03-04 13:40:59 +00:00
* Dump the XML document DTD , if any .
*/
static void
2004-03-15 13:46:37 +00:00
xmlDtdDumpOutput ( 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 ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 10 , " <!DOCTYPE " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) dtd - > name ) ;
if ( dtd - > ExternalID ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 8 , " PUBLIC " ) ;
2012-07-16 14:52:00 +08:00
xmlBufWriteQuotedString ( buf - > buffer , dtd - > ExternalID ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " " ) ;
2012-07-16 14:52:00 +08:00
xmlBufWriteQuotedString ( buf - > buffer , dtd - > SystemID ) ;
2004-03-04 13:40:59 +00:00
} else if ( dtd - > SystemID ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 8 , " SYSTEM " ) ;
2012-07-16 14:52:00 +08:00
xmlBufWriteQuotedString ( buf - > buffer , dtd - > SystemID ) ;
2004-03-04 13:40:59 +00:00
}
if ( ( dtd - > entities = = NULL ) & & ( dtd - > elements = = NULL ) & &
2004-09-08 20:55:38 +00:00
( dtd - > attributes = = NULL ) & & ( dtd - > notations = = NULL ) & &
( dtd - > pentities = = NULL ) ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2004-03-04 13:40:59 +00:00
return ;
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " [ \n " ) ;
2004-09-08 20:55:38 +00:00
/*
* 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 ) ) ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpNotationTable ( buf - > buffer ,
( xmlNotationTablePtr ) dtd - > notations ) ;
2004-08-14 11:15:13 +00:00
}
2004-03-15 13:46:37 +00:00
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 ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " ]> " ) ;
2004-03-04 13:40:59 +00:00
}
/**
* xmlAttrDumpOutput :
* @ buf : the XML buffer output
* @ cur : the attribute pointer
*
* Dump an XML attribute
*/
static void
2004-03-15 13:46:37 +00:00
xmlAttrDumpOutput ( xmlSaveCtxtPtr ctxt , xmlAttrPtr cur ) {
xmlOutputBufferPtr buf ;
2004-05-15 16:37:50 +00:00
2004-03-15 13:46:37 +00:00
if ( cur = = NULL ) return ;
buf = ctxt - > buf ;
2004-11-05 10:03:46 +00:00
if ( buf = = NULL ) return ;
2010-11-03 15:33:40 +01:00
if ( ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 2 ) ;
else
xmlOutputBufferWrite ( buf , 1 , " " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > ns - > prefix ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " : " ) ;
2004-03-04 13:40:59 +00:00
}
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " = \" " ) ;
xmlAttrSerializeContent ( buf , cur ) ;
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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 void
2004-03-15 13:46:37 +00:00
xmlAttrListDumpOutput ( xmlSaveCtxtPtr ctxt , xmlAttrPtr cur ) {
if ( cur = = NULL ) return ;
2004-03-04 13:40:59 +00:00
while ( cur ! = NULL ) {
2004-03-15 13:46:37 +00:00
xmlAttrDumpOutput ( ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
cur = cur - > next ;
}
}
/**
* xmlNodeListDumpOutput :
* @ cur : the first node
*
* Dump an XML node list , recursive behaviour , children are printed too .
*/
static void
2004-03-15 13:46:37 +00:00
xmlNodeListDumpOutput ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) {
xmlOutputBufferPtr buf ;
2004-03-04 13:40:59 +00:00
2004-03-15 13:46:37 +00:00
if ( cur = = NULL ) return ;
buf = ctxt - > buf ;
2004-03-04 13:40:59 +00:00
while ( cur ! = NULL ) {
2010-11-01 14:24:56 +01:00
if ( ( ctxt - > format = = 1 ) & & ( xmlIndentTreeOutput ) & &
2007-03-20 08:47:29 +00:00
( ( cur - > type = = XML_ELEMENT_NODE ) | |
( cur - > type = = XML_COMMENT_NODE ) | |
( cur - > type = = XML_PI_NODE ) ) )
2004-03-28 16:12:44 +00:00
xmlOutputBufferWrite ( buf , ctxt - > indent_size *
2012-09-11 13:26:36 +08:00
( ctxt - > level > ctxt - > indent_nr ?
2004-03-28 16:12:44 +00:00
ctxt - > indent_nr : ctxt - > level ) ,
ctxt - > indent ) ;
2004-03-15 13:46:37 +00:00
xmlNodeDumpOutputInternal ( ctxt , cur ) ;
2010-11-01 14:24:56 +01:00
if ( ctxt - > format = = 1 ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
2004-03-04 13:40:59 +00:00
}
cur = cur - > next ;
}
}
2008-09-01 13:08:57 +00:00
# ifdef LIBXML_HTML_ENABLED
/**
* xmlNodeDumpOutputInternal :
* @ cur : the current node
*
* Dump an HTML node , recursive behaviour , children are printed too .
*/
static int
htmlNodeDumpOutputInternal ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) {
const xmlChar * oldenc = NULL ;
const xmlChar * oldctxtenc = ctxt - > encoding ;
const xmlChar * encoding = ctxt - > encoding ;
xmlOutputBufferPtr buf = ctxt - > buf ;
int switched_encoding = 0 ;
xmlDocPtr doc ;
xmlInitParser ( ) ;
2009-09-02 14:58:13 +02:00
doc = cur - > doc ;
if ( doc ! = NULL ) {
2008-09-01 13:08:57 +00:00
oldenc = doc - > encoding ;
if ( ctxt - > encoding ! = NULL ) {
doc - > encoding = BAD_CAST ctxt - > encoding ;
} else if ( doc - > encoding ! = NULL ) {
encoding = doc - > encoding ;
}
}
if ( ( encoding ! = NULL ) & & ( doc ! = NULL ) )
htmlSetMetaEncoding ( doc , ( const xmlChar * ) encoding ) ;
if ( ( encoding = = NULL ) & & ( doc ! = NULL ) )
encoding = htmlGetMetaEncoding ( doc ) ;
if ( encoding = = NULL )
encoding = BAD_CAST " HTML " ;
if ( ( encoding ! = NULL ) & & ( oldctxtenc = = NULL ) & &
( buf - > encoder = = NULL ) & & ( buf - > conv = = NULL ) ) {
if ( xmlSaveSwitchEncoding ( ctxt , ( const char * ) encoding ) < 0 ) {
doc - > encoding = oldenc ;
return ( - 1 ) ;
}
switched_encoding = 1 ;
}
if ( ctxt - > options & XML_SAVE_FORMAT )
htmlNodeDumpFormatOutput ( buf , doc , cur ,
( const char * ) encoding , 1 ) ;
else
htmlNodeDumpFormatOutput ( buf , doc , cur ,
( const char * ) encoding , 0 ) ;
/*
* Restore the state of the saving context at the end of the document
*/
if ( ( switched_encoding ) & & ( oldctxtenc = = NULL ) ) {
xmlSaveClearEncoding ( ctxt ) ;
}
if ( doc ! = NULL )
doc - > encoding = oldenc ;
return ( 0 ) ;
}
# endif
2004-03-04 13:40:59 +00:00
/**
* xmlNodeDumpOutputInternal :
* @ cur : the current node
*
* Dump an XML node , recursive behaviour , children are printed too .
*/
static void
2004-03-15 13:46:37 +00:00
xmlNodeDumpOutputInternal ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) {
2004-03-28 16:12:44 +00:00
int format ;
2004-03-04 13:40:59 +00:00
xmlNodePtr tmp ;
xmlChar * start , * end ;
2004-03-15 13:46:37 +00:00
xmlOutputBufferPtr buf ;
2004-03-04 13:40:59 +00:00
2004-03-15 13:46:37 +00:00
if ( cur = = NULL ) return ;
buf = ctxt - > buf ;
2004-03-04 13:40:59 +00:00
if ( cur - > type = = XML_XINCLUDE_START )
return ;
if ( cur - > type = = XML_XINCLUDE_END )
return ;
2004-11-05 10:03:46 +00:00
if ( ( cur - > type = = XML_DOCUMENT_NODE ) | |
( cur - > type = = XML_HTML_DOCUMENT_NODE ) ) {
xmlDocContentDumpOutput ( ctxt , ( xmlDocPtr ) cur ) ;
return ;
}
2008-09-01 13:08:57 +00:00
# ifdef LIBXML_HTML_ENABLED
2008-09-25 14:31:40 +00:00
if ( ctxt - > options & XML_SAVE_XHTML ) {
xhtmlNodeDumpOutput ( ctxt , cur ) ;
return ;
}
if ( ( ( cur - > type ! = XML_NAMESPACE_DECL ) & & ( cur - > doc ! = NULL ) & &
( cur - > doc - > type = = XML_HTML_DOCUMENT_NODE ) & &
( ( ctxt - > options & XML_SAVE_AS_XML ) = = 0 ) ) | |
( ctxt - > options & XML_SAVE_AS_HTML ) ) {
2008-09-01 13:08:57 +00:00
htmlNodeDumpOutputInternal ( ctxt , cur ) ;
return ;
}
# endif
2004-03-04 13:40:59 +00:00
if ( cur - > type = = XML_DTD_NODE ) {
2004-03-15 13:46:37 +00:00
xmlDtdDumpOutput ( ctxt , ( xmlDtdPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_DOCUMENT_FRAG_NODE ) {
2004-03-15 13:46:37 +00:00
xmlNodeListDumpOutput ( ctxt , cur - > children ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_ELEMENT_DECL ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpElementDecl ( buf - > buffer , ( xmlElementPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_ATTRIBUTE_DECL ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpAttributeDecl ( buf - > buffer , ( xmlAttributePtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_ENTITY_DECL ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpEntityDecl ( buf - > buffer , ( xmlEntityPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_TEXT_NODE ) {
if ( cur - > content ! = NULL ) {
2005-02-11 10:58:55 +00:00
if ( cur - > name ! = xmlStringTextNoenc ) {
2004-05-15 18:57:31 +00:00
xmlOutputBufferWriteEscape ( buf , cur - > content , ctxt - > escape ) ;
2004-03-04 13:40:59 +00:00
} else {
/*
* Disable escaping , needed for XSLT
*/
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > content ) ;
}
}
return ;
}
if ( cur - > type = = XML_PI_NODE ) {
if ( cur - > content ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " <? " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
if ( cur - > content ! = NULL ) {
2010-11-03 15:33:40 +01:00
if ( ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 0 ) ;
else
xmlOutputBufferWrite ( buf , 1 , " " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > content ) ;
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " ?> " ) ;
2004-03-04 13:40:59 +00:00
} else {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " <? " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2010-11-03 15:33:40 +01:00
if ( ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 0 ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " ?> " ) ;
2004-03-04 13:40:59 +00:00
}
return ;
}
if ( cur - > type = = XML_COMMENT_NODE ) {
if ( cur - > content ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 4 , " <!-- " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > content ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " --> " ) ;
2004-03-04 13:40:59 +00:00
}
return ;
}
if ( cur - > type = = XML_ENTITY_REF_NODE ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " & " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " ; " ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_CDATA_SECTION_NODE ) {
2008-03-07 16:50:21 +00:00
if ( cur - > content = = NULL | | * cur - > content = = ' \0 ' ) {
xmlOutputBufferWrite ( buf , 12 , " <![CDATA[]]> " ) ;
2005-05-20 18:47:22 +00:00
} else {
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 ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 9 , " <![CDATA[ " ) ;
2005-05-20 18:47:22 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) start ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " ]]> " ) ;
2004-03-04 13:40:59 +00:00
}
}
return ;
}
if ( cur - > type = = XML_ATTRIBUTE_NODE ) {
2004-03-15 13:46:37 +00:00
xmlAttrDumpOutput ( ctxt , ( xmlAttrPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_NAMESPACE_DECL ) {
2010-11-03 15:33:40 +01:00
xmlNsDumpOutputCtxt ( ctxt , ( xmlNsPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
2004-03-15 13:46:37 +00:00
format = ctxt - > format ;
2004-03-04 13:40:59 +00:00
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 ) ) {
2004-03-15 13:46:37 +00:00
ctxt - > format = 0 ;
2004-03-04 13:40:59 +00:00
break ;
}
tmp = tmp - > next ;
}
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " < " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > ns - > prefix ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " : " ) ;
2004-03-04 13:40:59 +00:00
}
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
if ( cur - > nsDef )
2010-11-03 15:33:40 +01:00
xmlNsListDumpOutputCtxt ( ctxt , cur - > nsDef ) ;
2004-03-04 13:40:59 +00:00
if ( cur - > properties ! = NULL )
2004-03-15 13:46:37 +00:00
xmlAttrListDumpOutput ( ctxt , cur - > properties ) ;
2004-03-04 13:40:59 +00:00
if ( ( ( cur - > type = = XML_ELEMENT_NODE ) | | ( cur - > content = = NULL ) ) & &
2005-09-12 12:16:35 +00:00
( cur - > children = = NULL ) & & ( ( ctxt - > options & XML_SAVE_NO_EMPTY ) = = 0 ) ) {
2010-11-03 15:33:40 +01:00
if ( ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 0 ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " /> " ) ;
2004-03-15 13:46:37 +00:00
ctxt - > format = format ;
2004-03-04 13:40:59 +00:00
return ;
}
2010-11-03 15:33:40 +01:00
if ( ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 1 ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > type ! = XML_ELEMENT_NODE ) & & ( cur - > content ! = NULL ) ) {
2004-05-15 18:57:31 +00:00
xmlOutputBufferWriteEscape ( buf , cur - > content , ctxt - > escape ) ;
2004-03-04 13:40:59 +00:00
}
if ( cur - > children ! = NULL ) {
2010-11-01 14:24:56 +01:00
if ( ctxt - > format = = 1 ) xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
2004-03-15 13:46:37 +00:00
if ( ctxt - > level > = 0 ) ctxt - > level + + ;
xmlNodeListDumpOutput ( ctxt , cur - > children ) ;
if ( ctxt - > level > 0 ) ctxt - > level - - ;
2010-11-01 14:24:56 +01:00
if ( ( xmlIndentTreeOutput ) & & ( ctxt - > format = = 1 ) )
2004-03-28 16:12:44 +00:00
xmlOutputBufferWrite ( buf , ctxt - > indent_size *
2012-09-11 13:26:36 +08:00
( ctxt - > level > ctxt - > indent_nr ?
2004-03-28 16:12:44 +00:00
ctxt - > indent_nr : ctxt - > level ) ,
ctxt - > indent ) ;
2004-03-04 13:40:59 +00:00
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " </ " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > ns - > prefix ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " : " ) ;
2004-03-04 13:40:59 +00:00
}
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2010-11-03 15:33:40 +01:00
if ( ctxt - > format = = 2 )
xmlOutputBufferWriteWSNonSig ( ctxt , 0 ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2004-03-15 13:46:37 +00:00
ctxt - > format = format ;
2004-03-04 13:40:59 +00:00
}
/**
* xmlDocContentDumpOutput :
* @ cur : the document
*
* Dump an XML document .
*/
2006-10-16 23:22:10 +00:00
static int
2004-03-15 13:46:37 +00:00
xmlDocContentDumpOutput ( xmlSaveCtxtPtr ctxt , xmlDocPtr cur ) {
2004-03-04 13:40:59 +00:00
# ifdef LIBXML_HTML_ENABLED
xmlDtdPtr dtd ;
int is_xhtml = 0 ;
# endif
const xmlChar * oldenc = cur - > encoding ;
2006-10-16 23:22:10 +00:00
const xmlChar * oldctxtenc = ctxt - > encoding ;
2004-03-15 13:46:37 +00:00
const xmlChar * encoding = ctxt - > encoding ;
2006-10-16 23:22:10 +00:00
xmlCharEncodingOutputFunc oldescape = ctxt - > escape ;
xmlCharEncodingOutputFunc oldescapeAttr = ctxt - > escapeAttr ;
xmlOutputBufferPtr buf = ctxt - > buf ;
xmlCharEncoding enc ;
2008-09-01 13:08:57 +00:00
int switched_encoding = 0 ;
2004-03-04 13:40:59 +00:00
xmlInitParser ( ) ;
2008-09-01 13:08:57 +00:00
if ( ( cur - > type ! = XML_HTML_DOCUMENT_NODE ) & &
( cur - > type ! = XML_DOCUMENT_NODE ) )
return ( - 1 ) ;
2006-10-16 23:22:10 +00:00
if ( ctxt - > encoding ! = NULL ) {
2004-03-15 13:46:37 +00:00
cur - > encoding = BAD_CAST ctxt - > encoding ;
2006-10-16 23:22:10 +00:00
} else if ( cur - > encoding ! = NULL ) {
encoding = cur - > encoding ;
} else if ( cur - > charset ! = XML_CHAR_ENCODING_UTF8 ) {
encoding = ( const xmlChar * )
xmlGetCharEncodingName ( ( xmlCharEncoding ) cur - > charset ) ;
}
2004-03-04 13:40:59 +00:00
2008-09-25 14:31:40 +00:00
if ( ( ( cur - > type = = XML_HTML_DOCUMENT_NODE ) & &
( ( ctxt - > options & XML_SAVE_AS_XML ) = = 0 ) & &
( ( ctxt - > options & XML_SAVE_XHTML ) = = 0 ) ) | |
( ctxt - > options & XML_SAVE_AS_HTML ) ) {
2008-09-01 13:08:57 +00:00
# ifdef LIBXML_HTML_ENABLED
if ( encoding ! = NULL )
htmlSetMetaEncoding ( cur , ( const xmlChar * ) encoding ) ;
if ( encoding = = NULL )
encoding = htmlGetMetaEncoding ( cur ) ;
if ( encoding = = NULL )
encoding = BAD_CAST " HTML " ;
if ( ( encoding ! = NULL ) & & ( oldctxtenc = = NULL ) & &
( buf - > encoder = = NULL ) & & ( buf - > conv = = NULL ) ) {
if ( xmlSaveSwitchEncoding ( ctxt , ( const char * ) encoding ) < 0 ) {
cur - > encoding = oldenc ;
2006-10-16 23:22:10 +00:00
return ( - 1 ) ;
}
2008-09-01 13:08:57 +00:00
}
if ( ctxt - > options & XML_SAVE_FORMAT )
htmlDocContentDumpFormatOutput ( buf , cur ,
( const char * ) encoding , 1 ) ;
else
htmlDocContentDumpFormatOutput ( buf , cur ,
( const char * ) encoding , 0 ) ;
if ( ctxt - > encoding ! = NULL )
cur - > encoding = oldenc ;
return ( 0 ) ;
# else
return ( - 1 ) ;
# endif
2008-09-25 14:31:40 +00:00
} else if ( ( cur - > type = = XML_DOCUMENT_NODE ) | |
( ctxt - > options & XML_SAVE_AS_XML ) | |
( ctxt - > options & XML_SAVE_XHTML ) ) {
2008-09-01 13:08:57 +00:00
enc = xmlParseCharEncoding ( ( const char * ) encoding ) ;
if ( ( encoding ! = NULL ) & & ( oldctxtenc = = NULL ) & &
( buf - > encoder = = NULL ) & & ( buf - > conv = = NULL ) & &
( ( ctxt - > options & XML_SAVE_NO_DECL ) = = 0 ) ) {
if ( ( enc ! = XML_CHAR_ENCODING_UTF8 ) & &
( enc ! = XML_CHAR_ENCODING_NONE ) & &
( enc ! = XML_CHAR_ENCODING_ASCII ) ) {
/*
* we need to switch to this encoding but just for this
* document since we output the XMLDecl the conversion
* must be done to not generate not well formed documents .
*/
if ( xmlSaveSwitchEncoding ( ctxt , ( const char * ) encoding ) < 0 ) {
cur - > encoding = oldenc ;
return ( - 1 ) ;
}
switched_encoding = 1 ;
2006-10-16 23:22:10 +00:00
}
2008-09-01 13:08:57 +00:00
if ( ctxt - > escape = = xmlEscapeEntities )
ctxt - > escape = NULL ;
if ( ctxt - > escapeAttr = = xmlEscapeEntities )
ctxt - > escapeAttr = NULL ;
2006-10-16 23:22:10 +00:00
}
2008-09-01 13:08:57 +00:00
/*
* Save the XML declaration
*/
if ( ( ctxt - > options & XML_SAVE_NO_DECL ) = = 0 ) {
xmlOutputBufferWrite ( buf , 14 , " <?xml version= " ) ;
2012-09-11 13:26:36 +08:00
if ( cur - > version ! = NULL )
2012-07-16 14:52:00 +08:00
xmlBufWriteQuotedString ( buf - > buffer , cur - > version ) ;
2008-09-01 13:08:57 +00:00
else
xmlOutputBufferWrite ( buf , 5 , " \" 1.0 \" " ) ;
if ( encoding ! = NULL ) {
xmlOutputBufferWrite ( buf , 10 , " encoding= " ) ;
2012-07-16 14:52:00 +08:00
xmlBufWriteQuotedString ( buf - > buffer , ( xmlChar * ) encoding ) ;
2008-09-01 13:08:57 +00:00
}
switch ( cur - > standalone ) {
case 0 :
xmlOutputBufferWrite ( buf , 16 , " standalone= \" no \" " ) ;
break ;
case 1 :
xmlOutputBufferWrite ( buf , 17 , " standalone= \" yes \" " ) ;
break ;
}
xmlOutputBufferWrite ( buf , 3 , " ?> \n " ) ;
2005-08-08 14:44:11 +00:00
}
2004-03-04 13:40:59 +00:00
# ifdef LIBXML_HTML_ENABLED
2008-09-25 14:31:40 +00:00
if ( ctxt - > options & XML_SAVE_XHTML )
is_xhtml = 1 ;
2008-09-01 13:08:57 +00:00
if ( ( ctxt - > options & XML_SAVE_NO_XHTML ) = = 0 ) {
dtd = xmlGetIntSubset ( cur ) ;
if ( dtd ! = NULL ) {
is_xhtml = xmlIsXHTML ( dtd - > SystemID , dtd - > ExternalID ) ;
if ( is_xhtml < 0 ) is_xhtml = 0 ;
}
2005-09-12 21:43:20 +00:00
}
2004-03-04 13:40:59 +00:00
# endif
2008-09-01 13:08:57 +00:00
if ( cur - > children ! = NULL ) {
xmlNodePtr child = cur - > children ;
2004-03-04 13:40:59 +00:00
2008-09-01 13:08:57 +00:00
while ( child ! = NULL ) {
ctxt - > level = 0 ;
2004-03-04 13:40:59 +00:00
# ifdef LIBXML_HTML_ENABLED
2008-09-01 13:08:57 +00:00
if ( is_xhtml )
xhtmlNodeDumpOutput ( ctxt , child ) ;
else
2004-03-04 13:40:59 +00:00
# endif
2008-09-01 13:08:57 +00:00
xmlNodeDumpOutputInternal ( ctxt , child ) ;
xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
child = child - > next ;
}
2004-03-04 13:40:59 +00:00
}
}
2008-09-01 13:08:57 +00:00
2006-10-16 23:22:10 +00:00
/*
* Restore the state of the saving context at the end of the document
*/
2008-09-01 13:08:57 +00:00
if ( ( switched_encoding ) & & ( oldctxtenc = = NULL ) ) {
xmlSaveClearEncoding ( ctxt ) ;
2006-10-16 23:22:10 +00:00
ctxt - > escape = oldescape ;
ctxt - > escapeAttr = oldescapeAttr ;
}
2008-09-01 13:08:57 +00:00
cur - > encoding = oldenc ;
2006-10-16 23:22:10 +00:00
return ( 0 ) ;
2004-03-04 13:40:59 +00:00
}
# ifdef LIBXML_HTML_ENABLED
/************************************************************************
* *
* Functions specific to XHTML serialization *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xhtmlIsEmpty :
* @ node : the node
*
* Check if a node is an empty xhtml node
*
* Returns 1 if the node is an empty node , 0 if not and - 1 in case of error
*/
static int
xhtmlIsEmpty ( 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 void
2004-03-15 13:46:37 +00:00
xhtmlAttrListDumpOutput ( xmlSaveCtxtPtr ctxt , xmlAttrPtr cur ) {
2004-03-04 13:40:59 +00:00
xmlAttrPtr xml_lang = NULL ;
xmlAttrPtr lang = NULL ;
xmlAttrPtr name = NULL ;
xmlAttrPtr id = NULL ;
xmlNodePtr parent ;
2004-03-15 13:46:37 +00:00
xmlOutputBufferPtr buf ;
2004-03-04 13:40:59 +00:00
2004-03-15 13:46:37 +00:00
if ( cur = = NULL ) return ;
buf = ctxt - > buf ;
2004-03-04 13:40:59 +00:00
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 ;
2012-09-11 13:26:36 +08:00
else if ( ( cur - > ns = = NULL ) & &
2004-03-04 13:40:59 +00:00
( ( 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 ;
}
2004-03-15 13:46:37 +00:00
xmlAttrDumpOutput ( ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
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 " ) ) ) ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 5 , " id= \" " ) ;
xmlAttrSerializeContent ( buf , name ) ;
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
2004-03-04 13:40:59 +00:00
}
}
/*
* C .7 .
*/
if ( ( lang ! = NULL ) & & ( xml_lang = = NULL ) ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 11 , " xml:lang= \" " ) ;
xmlAttrSerializeContent ( buf , lang ) ;
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
2012-09-11 13:26:36 +08:00
} else
2004-03-04 13:40:59 +00:00
if ( ( xml_lang ! = NULL ) & & ( lang = = NULL ) ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 7 , " lang= \" " ) ;
xmlAttrSerializeContent ( buf , xml_lang ) ;
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
2004-03-04 13:40:59 +00:00
}
}
/**
* 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 void
2004-03-15 13:46:37 +00:00
xhtmlNodeListDumpOutput ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) {
xmlOutputBufferPtr buf ;
2004-03-04 13:40:59 +00:00
2004-03-15 13:46:37 +00:00
if ( cur = = NULL ) return ;
buf = ctxt - > buf ;
2004-03-04 13:40:59 +00:00
while ( cur ! = NULL ) {
2010-11-01 14:24:56 +01:00
if ( ( ctxt - > format = = 1 ) & & ( xmlIndentTreeOutput ) & &
2004-03-04 13:40:59 +00:00
( cur - > type = = XML_ELEMENT_NODE ) )
2004-03-28 16:12:44 +00:00
xmlOutputBufferWrite ( buf , ctxt - > indent_size *
2012-09-11 13:26:36 +08:00
( ctxt - > level > ctxt - > indent_nr ?
2004-03-28 16:12:44 +00:00
ctxt - > indent_nr : ctxt - > level ) ,
ctxt - > indent ) ;
2004-03-15 13:46:37 +00:00
xhtmlNodeDumpOutput ( ctxt , cur ) ;
2010-11-01 14:24:56 +01:00
if ( ctxt - > format = = 1 ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
2004-03-04 13:40:59 +00:00
}
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 void
2004-03-15 13:46:37 +00:00
xhtmlNodeDumpOutput ( xmlSaveCtxtPtr ctxt , xmlNodePtr cur ) {
2005-08-26 15:33:26 +00:00
int format , addmeta = 0 ;
2004-03-04 13:40:59 +00:00
xmlNodePtr tmp ;
xmlChar * start , * end ;
2004-03-15 13:46:37 +00:00
xmlOutputBufferPtr buf ;
2004-03-04 13:40:59 +00:00
2004-03-15 13:46:37 +00:00
if ( cur = = NULL ) return ;
2005-09-12 00:03:43 +00:00
if ( ( cur - > type = = XML_DOCUMENT_NODE ) | |
( cur - > type = = XML_HTML_DOCUMENT_NODE ) ) {
xmlDocContentDumpOutput ( ctxt , ( xmlDocPtr ) cur ) ;
return ;
}
2004-03-04 13:40:59 +00:00
if ( cur - > type = = XML_XINCLUDE_START )
return ;
if ( cur - > type = = XML_XINCLUDE_END )
return ;
2012-08-09 14:24:02 +08:00
if ( cur - > type = = XML_NAMESPACE_DECL ) {
xmlNsDumpOutputCtxt ( ctxt , ( xmlNsPtr ) cur ) ;
return ;
}
2004-03-04 13:40:59 +00:00
if ( cur - > type = = XML_DTD_NODE ) {
2004-03-15 13:46:37 +00:00
xmlDtdDumpOutput ( ctxt , ( xmlDtdPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
2005-10-21 14:45:16 +00:00
if ( cur - > type = = XML_DOCUMENT_FRAG_NODE ) {
xhtmlNodeListDumpOutput ( ctxt , cur - > children ) ;
return ;
}
2004-03-15 13:46:37 +00:00
buf = ctxt - > buf ;
2004-03-04 13:40:59 +00:00
if ( cur - > type = = XML_ELEMENT_DECL ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpElementDecl ( buf - > buffer , ( xmlElementPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_ATTRIBUTE_DECL ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpAttributeDecl ( buf - > buffer , ( xmlAttributePtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_ENTITY_DECL ) {
2012-07-16 14:52:00 +08:00
xmlBufDumpEntityDecl ( buf - > buffer , ( xmlEntityPtr ) cur ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_TEXT_NODE ) {
if ( cur - > content ! = NULL ) {
if ( ( cur - > name = = xmlStringText ) | |
( cur - > name ! = xmlStringTextNoenc ) ) {
2004-05-15 18:57:31 +00:00
xmlOutputBufferWriteEscape ( buf , cur - > content , ctxt - > escape ) ;
2004-03-04 13:40:59 +00:00
} else {
/*
* Disable escaping , needed for XSLT
*/
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > content ) ;
}
}
return ;
}
if ( cur - > type = = XML_PI_NODE ) {
if ( cur - > content ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " <? " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
if ( cur - > content ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > content ) ;
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " ?> " ) ;
2004-03-04 13:40:59 +00:00
} else {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " <? " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " ?> " ) ;
2004-03-04 13:40:59 +00:00
}
return ;
}
if ( cur - > type = = XML_COMMENT_NODE ) {
if ( cur - > content ! = NULL ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 4 , " <!-- " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > content ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " --> " ) ;
2004-03-04 13:40:59 +00:00
}
return ;
}
if ( cur - > type = = XML_ENTITY_REF_NODE ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " & " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " ; " ) ;
2004-03-04 13:40:59 +00:00
return ;
}
if ( cur - > type = = XML_CDATA_SECTION_NODE ) {
2008-03-07 16:50:21 +00:00
if ( cur - > content = = NULL | | * cur - > content = = ' \0 ' ) {
xmlOutputBufferWrite ( buf , 12 , " <![CDATA[]]> " ) ;
} else {
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 ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 9 , " <![CDATA[ " ) ;
2008-03-07 16:50:21 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) start ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " ]]> " ) ;
2004-03-04 13:40:59 +00:00
}
}
return ;
}
2007-10-10 08:28:18 +00:00
if ( cur - > type = = XML_ATTRIBUTE_NODE ) {
xmlAttrDumpOutput ( ctxt , ( xmlAttrPtr ) cur ) ;
return ;
}
2004-03-04 13:40:59 +00:00
2004-03-15 13:46:37 +00:00
format = ctxt - > format ;
2004-03-04 13:40:59 +00:00
if ( format = = 1 ) {
tmp = cur - > children ;
while ( tmp ! = NULL ) {
2012-09-11 13:26:36 +08:00
if ( ( tmp - > type = = XML_TEXT_NODE ) | |
2004-03-04 13:40:59 +00:00
( tmp - > type = = XML_ENTITY_REF_NODE ) ) {
format = 0 ;
break ;
}
tmp = tmp - > next ;
}
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " < " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > ns - > prefix ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " : " ) ;
2004-03-04 13:40:59 +00:00
}
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
if ( cur - > nsDef )
2010-11-03 15:33:40 +01:00
xmlNsListDumpOutputCtxt ( ctxt , cur - > nsDef ) ;
2004-03-04 13:40:59 +00:00
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 )
2004-03-15 13:46:37 +00:00
xhtmlAttrListDumpOutput ( ctxt , cur - > properties ) ;
2004-03-04 13:40:59 +00:00
2012-09-11 13:26:36 +08:00
if ( ( cur - > type = = XML_ELEMENT_NODE ) & &
( cur - > parent ! = NULL ) & &
( cur - > parent - > parent = = ( xmlNodePtr ) cur - > doc ) & &
xmlStrEqual ( cur - > name , BAD_CAST " head " ) & &
2005-08-26 15:33:26 +00:00
xmlStrEqual ( cur - > parent - > name , BAD_CAST " html " ) ) {
tmp = cur - > children ;
while ( tmp ! = NULL ) {
if ( xmlStrEqual ( tmp - > name , BAD_CAST " meta " ) ) {
xmlChar * httpequiv ;
httpequiv = xmlGetProp ( tmp , BAD_CAST " http-equiv " ) ;
2005-09-03 14:56:36 +00:00
if ( httpequiv ! = NULL ) {
if ( xmlStrcasecmp ( httpequiv , BAD_CAST " Content-Type " ) = = 0 ) {
xmlFree ( httpequiv ) ;
break ;
}
2005-08-26 15:33:26 +00:00
xmlFree ( httpequiv ) ;
}
}
tmp = tmp - > next ;
}
if ( tmp = = NULL )
addmeta = 1 ;
}
2004-03-04 13:40:59 +00:00
if ( ( cur - > type = = XML_ELEMENT_NODE ) & & ( cur - > children = = NULL ) ) {
if ( ( ( cur - > ns = = NULL ) | | ( cur - > ns - > prefix = = NULL ) ) & &
2005-08-26 15:33:26 +00:00
( ( xhtmlIsEmpty ( cur ) = = 1 ) & & ( addmeta = = 0 ) ) ) {
2004-03-04 13:40:59 +00:00
/*
* C .2 . Empty Elements
*/
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " /> " ) ;
2004-03-04 13:40:59 +00:00
} else {
2005-08-26 15:33:26 +00:00
if ( addmeta = = 1 ) {
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2010-11-01 14:24:56 +01:00
if ( ctxt - > format = = 1 ) {
2005-09-12 12:16:35 +00:00
xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
if ( xmlIndentTreeOutput )
xmlOutputBufferWrite ( buf , ctxt - > indent_size *
2012-09-11 13:26:36 +08:00
( ctxt - > level + 1 > ctxt - > indent_nr ?
2005-09-12 12:16:35 +00:00
ctxt - > indent_nr : ctxt - > level + 1 ) , ctxt - > indent ) ;
}
2005-08-26 15:33:26 +00:00
xmlOutputBufferWriteString ( buf ,
" <meta http-equiv= \" Content-Type \" content= \" text/html; charset= " ) ;
if ( ctxt - > encoding ) {
xmlOutputBufferWriteString ( buf , ( const char * ) ctxt - > encoding ) ;
} else {
xmlOutputBufferWrite ( buf , 5 , " UTF-8 " ) ;
}
2005-09-12 12:16:35 +00:00
xmlOutputBufferWrite ( buf , 4 , " \" /> " ) ;
2010-11-01 14:24:56 +01:00
if ( ctxt - > format = = 1 )
2005-09-12 12:16:35 +00:00
xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
} else {
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2005-08-26 15:33:26 +00:00
}
2004-03-04 13:40:59 +00:00
/*
* C .3 . Element Minimization and Empty Element Content
*/
2005-09-12 12:16:35 +00:00
xmlOutputBufferWrite ( buf , 2 , " </ " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > ns - > prefix ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " : " ) ;
2004-03-04 13:40:59 +00:00
}
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2004-03-04 13:40:59 +00:00
}
return ;
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2005-08-26 15:33:26 +00:00
if ( addmeta = = 1 ) {
2010-11-01 14:24:56 +01:00
if ( ctxt - > format = = 1 ) {
2005-09-12 12:16:35 +00:00
xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
if ( xmlIndentTreeOutput )
xmlOutputBufferWrite ( buf , ctxt - > indent_size *
2012-09-11 13:26:36 +08:00
( ctxt - > level + 1 > ctxt - > indent_nr ?
2005-09-12 12:16:35 +00:00
ctxt - > indent_nr : ctxt - > level + 1 ) , ctxt - > indent ) ;
}
2005-08-26 15:33:26 +00:00
xmlOutputBufferWriteString ( buf ,
" <meta http-equiv= \" Content-Type \" content= \" text/html; charset= " ) ;
if ( ctxt - > encoding ) {
xmlOutputBufferWriteString ( buf , ( const char * ) ctxt - > encoding ) ;
} else {
xmlOutputBufferWrite ( buf , 5 , " UTF-8 " ) ;
}
xmlOutputBufferWrite ( buf , 4 , " \" /> " ) ;
}
2004-03-04 13:40:59 +00:00
if ( ( cur - > type ! = XML_ELEMENT_NODE ) & & ( cur - > content ! = NULL ) ) {
2004-05-15 18:57:31 +00:00
xmlOutputBufferWriteEscape ( buf , cur - > content , ctxt - > escape ) ;
2004-03-04 13:40:59 +00:00
}
2006-07-13 13:07:11 +00:00
#if 0
/*
* This was removed due to problems with HTML processors .
* See bug # 345147.
2006-10-16 23:22:10 +00:00
*/
2004-03-04 13:40:59 +00:00
/*
* 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 ) {
2005-09-12 14:03:26 +00:00
if ( child - > type = = XML_TEXT_NODE ) {
if ( ( xmlStrchr ( child - > content , ' < ' ) = = NULL ) & &
( xmlStrchr ( child - > content , ' & ' ) = = NULL ) & &
( xmlStrstr ( child - > content , BAD_CAST " ]]> " ) = = NULL ) ) {
/* Nothing to escape, so just output as is... */
/* FIXME: Should we do something about "--" also? */
2004-03-15 13:46:37 +00:00
int level = ctxt - > level ;
int indent = ctxt - > format ;
ctxt - > level = 0 ;
ctxt - > format = 0 ;
2005-09-12 14:03:26 +00:00
xmlOutputBufferWriteString ( buf , ( const char * ) child - > content ) ;
/* (We cannot use xhtmlNodeDumpOutput() here because
* we wish to leave ' > ' unescaped ! ) */
2004-03-15 13:46:37 +00:00
ctxt - > level = level ;
ctxt - > format = indent ;
2004-03-04 13:40:59 +00:00
} else {
2005-09-12 14:03:26 +00:00
/* We must use a CDATA section. Unfortunately,
* this will break CSS and JavaScript when read by
* a browser in HTML4 - compliant mode . : - ( */
2004-03-04 13:40:59 +00:00
start = end = child - > content ;
while ( * end ! = ' \0 ' ) {
if ( * end = = ' ] ' & &
* ( end + 1 ) = = ' ] ' & &
* ( end + 2 ) = = ' > ' ) {
end = end + 2 ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 9 , " <![CDATA[ " ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferWrite ( buf , end - start ,
( const char * ) start ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 3 , " ]]> " ) ;
2004-03-04 13:40:59 +00:00
start = end ;
}
end + + ;
}
if ( start ! = end ) {
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 9 , " <![CDATA[ " ) ;
xmlOutputBufferWrite ( buf , end - start ,
( const char * ) start ) ;
xmlOutputBufferWrite ( buf , 3 , " ]]> " ) ;
2004-03-04 13:40:59 +00:00
}
}
} else {
2004-03-15 13:46:37 +00:00
int level = ctxt - > level ;
int indent = ctxt - > format ;
ctxt - > level = 0 ;
ctxt - > format = 0 ;
xhtmlNodeDumpOutput ( ctxt , child ) ;
ctxt - > level = level ;
ctxt - > format = indent ;
2004-03-04 13:40:59 +00:00
}
child = child - > next ;
}
2006-07-13 13:07:11 +00:00
}
# endif
if ( cur - > children ! = NULL ) {
2004-05-09 23:48:39 +00:00
int indent = ctxt - > format ;
2012-09-11 13:26:36 +08:00
2010-11-01 14:24:56 +01:00
if ( format = = 1 ) xmlOutputBufferWrite ( buf , 1 , " \n " ) ;
2004-03-15 13:46:37 +00:00
if ( ctxt - > level > = 0 ) ctxt - > level + + ;
2004-05-09 23:48:39 +00:00
ctxt - > format = format ;
2004-03-15 13:46:37 +00:00
xhtmlNodeListDumpOutput ( ctxt , cur - > children ) ;
if ( ctxt - > level > 0 ) ctxt - > level - - ;
2004-05-09 23:48:39 +00:00
ctxt - > format = indent ;
2010-11-01 14:24:56 +01:00
if ( ( xmlIndentTreeOutput ) & & ( format = = 1 ) )
2004-03-28 16:12:44 +00:00
xmlOutputBufferWrite ( buf , ctxt - > indent_size *
2012-09-11 13:26:36 +08:00
( ctxt - > level > ctxt - > indent_nr ?
2004-03-28 16:12:44 +00:00
ctxt - > indent_nr : ctxt - > level ) ,
ctxt - > indent ) ;
2004-03-04 13:40:59 +00:00
}
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 2 , " </ " ) ;
2004-03-04 13:40:59 +00:00
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > ns - > prefix ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " : " ) ;
2004-03-04 13:40:59 +00:00
}
xmlOutputBufferWriteString ( buf , ( const char * ) cur - > name ) ;
2004-05-15 16:37:50 +00:00
xmlOutputBufferWrite ( buf , 1 , " > " ) ;
2004-03-04 13:40:59 +00:00
}
# 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 .
*/
xmlSaveCtxtPtr
xmlSaveToFd ( int fd , const char * encoding , int options )
{
xmlSaveCtxtPtr ret ;
ret = xmlNewSaveCtxt ( encoding , options ) ;
if ( ret = = NULL ) return ( NULL ) ;
2004-03-15 13:46:37 +00:00
ret - > buf = xmlOutputBufferCreateFd ( fd , ret - > handler ) ;
if ( ret - > buf = = NULL ) {
2004-03-04 13:40:59 +00:00
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 .
*/
xmlSaveCtxtPtr
xmlSaveToFilename ( 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 ) ;
2004-03-15 13:46:37 +00:00
ret - > buf = xmlOutputBufferCreateFilename ( filename , ret - > handler ,
2004-03-04 13:40:59 +00:00
compression ) ;
2004-03-15 13:46:37 +00:00
if ( ret - > buf = = NULL ) {
2004-03-04 13:40:59 +00:00
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 .
2005-11-09 08:56:26 +00:00
*/
2004-03-04 13:40:59 +00:00
xmlSaveCtxtPtr
xmlSaveToBuffer ( xmlBufferPtr buffer , const char * encoding , int options )
{
2005-11-09 08:56:26 +00:00
xmlSaveCtxtPtr ret ;
xmlOutputBufferPtr out_buff ;
xmlCharEncodingHandlerPtr handler ;
ret = xmlNewSaveCtxt ( encoding , options ) ;
if ( ret = = NULL ) return ( NULL ) ;
if ( encoding ! = NULL ) {
handler = xmlFindCharEncodingHandler ( encoding ) ;
if ( handler = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
} else
handler = NULL ;
out_buff = xmlOutputBufferCreateBuffer ( buffer , handler ) ;
if ( out_buff = = NULL ) {
xmlFree ( ret ) ;
if ( handler ) xmlCharEncCloseFunc ( handler ) ;
return ( NULL ) ;
}
ret - > buf = out_buff ;
return ( ret ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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 .
*/
xmlSaveCtxtPtr
xmlSaveToIO ( xmlOutputWriteCallback iowrite ,
xmlOutputCloseCallback ioclose ,
void * ioctx , const char * encoding , int options )
{
xmlSaveCtxtPtr ret ;
ret = xmlNewSaveCtxt ( encoding , options ) ;
if ( ret = = NULL ) return ( NULL ) ;
2004-03-15 13:46:37 +00:00
ret - > buf = xmlOutputBufferCreateIO ( iowrite , ioclose , ioctx , ret - > handler ) ;
if ( ret - > buf = = NULL ) {
2004-03-04 13:40:59 +00:00
xmlFreeSaveCtxt ( ret ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlSaveDoc :
* @ ctxt : a document saving context
* @ doc : a document
*
* Save a full document to a saving context
2004-04-16 16:30:05 +00:00
* TODO : The function is not fully implemented yet as it does not return the
* byte count but 0 instead
2004-03-04 13:40:59 +00:00
*
* Returns the number of byte written or - 1 in case of error
*/
long
xmlSaveDoc ( xmlSaveCtxtPtr ctxt , xmlDocPtr doc )
{
2004-03-15 13:46:37 +00:00
long ret = 0 ;
2004-11-05 17:22:25 +00:00
if ( ( ctxt = = NULL ) | | ( doc = = NULL ) ) return ( - 1 ) ;
2006-10-16 23:22:10 +00:00
if ( xmlDocContentDumpOutput ( ctxt , doc ) < 0 )
return ( - 1 ) ;
2004-03-15 13:46:37 +00:00
return ( ret ) ;
2004-03-04 13:40:59 +00:00
}
/**
* xmlSaveTree :
* @ ctxt : a document saving context
2006-09-29 09:16:00 +00:00
* @ node : the top node of the subtree to save
2004-03-04 13:40:59 +00:00
*
* Save a subtree starting at the node parameter to a saving context
2004-04-16 16:30:05 +00:00
* TODO : The function is not fully implemented yet as it does not return the
* byte count but 0 instead
2004-03-04 13:40:59 +00:00
*
* Returns the number of byte written or - 1 in case of error
*/
long
xmlSaveTree ( xmlSaveCtxtPtr ctxt , xmlNodePtr node )
{
2004-03-15 13:46:37 +00:00
long ret = 0 ;
2004-11-05 17:22:25 +00:00
if ( ( ctxt = = NULL ) | | ( node = = NULL ) ) return ( - 1 ) ;
2004-03-15 13:46:37 +00:00
xmlNodeDumpOutputInternal ( ctxt , node ) ;
return ( ret ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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 .
*/
int
xmlSaveFlush ( xmlSaveCtxtPtr ctxt )
{
if ( ctxt = = NULL ) return ( - 1 ) ;
2004-03-15 13:46:37 +00:00
if ( ctxt - > buf = = NULL ) return ( - 1 ) ;
return ( xmlOutputBufferFlush ( ctxt - > buf ) ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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 .
*/
int
xmlSaveClose ( xmlSaveCtxtPtr ctxt )
{
int ret ;
if ( ctxt = = NULL ) return ( - 1 ) ;
ret = xmlSaveFlush ( ctxt ) ;
xmlFreeSaveCtxt ( ctxt ) ;
return ( ret ) ;
}
2004-05-15 18:57:31 +00:00
/**
* 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 .
*/
int
xmlSaveSetEscape ( 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 .
*/
int
xmlSaveSetAttrEscape ( xmlSaveCtxtPtr ctxt , xmlCharEncodingOutputFunc escape )
{
if ( ctxt = = NULL ) return ( - 1 ) ;
ctxt - > escapeAttr = escape ;
return ( 0 ) ;
}
2004-03-04 13:40:59 +00:00
/************************************************************************
* *
* Public entry points based on buffers *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-07-16 14:52:00 +08:00
2004-03-04 13:40:59 +00:00
/**
2012-07-16 14:52:00 +08:00
* xmlBufAttrSerializeTxtContent :
* @ buf : and xmlBufPtr output
2004-03-04 13:40:59 +00:00
* @ doc : the document
* @ attr : the attribute node
* @ string : the text content
*
2012-07-16 14:52:00 +08:00
* Serialize text attribute values to an xmlBufPtr
2004-03-04 13:40:59 +00:00
*/
void
2012-07-16 14:52:00 +08:00
xmlBufAttrSerializeTxtContent ( xmlBufPtr buf , xmlDocPtr doc ,
xmlAttrPtr attr , const xmlChar * string )
2004-05-15 16:37:50 +00:00
{
2004-03-04 13:40:59 +00:00
xmlChar * base , * cur ;
2004-05-15 16:37:50 +00:00
if ( string = = NULL )
return ;
base = cur = ( xmlChar * ) string ;
2004-03-04 13:40:59 +00:00
while ( * cur ! = 0 ) {
if ( * cur = = ' \n ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " " , 5 ) ;
2004-03-04 13:40:59 +00:00
cur + + ;
base = cur ;
2004-05-15 16:37:50 +00:00
} else if ( * cur = = ' \r ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " " , 5 ) ;
2004-05-15 16:37:50 +00:00
cur + + ;
base = cur ;
} else if ( * cur = = ' \t ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " 	 " , 4 ) ;
2004-05-15 16:37:50 +00:00
cur + + ;
base = cur ;
} else if ( * cur = = ' " ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " " " , 6 ) ;
2004-05-15 16:37:50 +00:00
cur + + ;
base = cur ;
} else if ( * cur = = ' < ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " < " , 4 ) ;
2004-05-15 16:37:50 +00:00
cur + + ;
base = cur ;
} else if ( * cur = = ' > ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " > " , 4 ) ;
2004-05-15 16:37:50 +00:00
cur + + ;
base = cur ;
} else if ( * cur = = ' & ' ) {
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
xmlBufAdd ( buf , BAD_CAST " & " , 5 ) ;
2004-05-15 16:37:50 +00:00
cur + + ;
base = cur ;
} else if ( ( * cur > = 0x80 ) & & ( ( doc = = NULL ) | |
( doc - > encoding = = NULL ) ) ) {
/*
* We assume we have UTF - 8 content .
*/
2012-01-22 17:42:35 +08:00
unsigned char tmp [ 12 ] ;
2004-05-15 16:37:50 +00:00
int val = 0 , l = 1 ;
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
2004-05-15 16:37:50 +00:00
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 ) ;
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , ( xmlChar * ) tmp , - 1 ) ;
2004-03-04 13:40:59 +00:00
cur + + ;
base = cur ;
2004-05-15 16:37:50 +00:00
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 " ) ;
2012-07-16 14:52:00 +08:00
2004-05-15 16:37:50 +00:00
xmlSerializeHexCharRef ( tmp , * cur ) ;
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , ( xmlChar * ) tmp , - 1 ) ;
2004-03-04 13:40:59 +00:00
cur + + ;
2004-05-15 16:37:50 +00:00
base = cur ;
continue ;
2004-03-04 13:40:59 +00:00
}
2004-05-15 16:37:50 +00:00
/*
* We could do multiple things here . Just save
* as a char ref
*/
xmlSerializeHexCharRef ( tmp , val ) ;
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , ( xmlChar * ) tmp , - 1 ) ;
2004-05-15 16:37:50 +00:00
cur + = l ;
base = cur ;
} else {
cur + + ;
2004-03-04 13:40:59 +00:00
}
2004-05-15 16:37:50 +00:00
}
if ( base ! = cur )
2012-07-16 14:52:00 +08:00
xmlBufAdd ( buf , base , cur - base ) ;
}
/**
* 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
*/
void
xmlAttrSerializeTxtContent ( xmlBufferPtr buf , xmlDocPtr doc ,
xmlAttrPtr attr , const xmlChar * string )
{
xmlBufPtr buffer ;
if ( ( buf = = NULL ) | | ( string = = NULL ) )
return ;
buffer = xmlBufFromBuffer ( buf ) ;
if ( buffer = = NULL )
return ;
xmlBufAttrSerializeTxtContent ( buffer , doc , attr , string ) ;
xmlBufBackToBuffer ( buffer ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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
2012-07-16 14:52:00 +08:00
* Since this is using xmlBuffer structures it is limited to 2 GB and somehow
* deprecated , use xmlBufNodeDump ( ) instead .
2004-03-04 13:40:59 +00:00
*
* Returns the number of bytes written to the buffer or - 1 in case of error
*/
int
xmlNodeDump ( xmlBufferPtr buf , xmlDocPtr doc , xmlNodePtr cur , int level ,
int format )
{
2012-07-16 14:52:00 +08:00
xmlBufPtr buffer ;
int ret ;
if ( ( buf = = NULL ) | | ( cur = = NULL ) )
return ( - 1 ) ;
buffer = xmlBufFromBuffer ( buf ) ;
if ( buffer = = NULL )
return ( - 1 ) ;
ret = xmlBufNodeDump ( buffer , doc , cur , level , format ) ;
xmlBufBackToBuffer ( buffer ) ;
if ( ret > INT_MAX )
return ( - 1 ) ;
return ( ( int ) ret ) ;
}
/**
* xmlBufNodeDump :
* @ 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 , in case of error 0
* is returned or @ buf stores the error
*/
size_t
xmlBufNodeDump ( xmlBufPtr buf , xmlDocPtr doc , xmlNodePtr cur , int level ,
int format )
{
size_t use ;
2004-03-04 13:40:59 +00:00
int ret ;
xmlOutputBufferPtr outbuf ;
2013-02-11 11:52:44 +08:00
int oldalloc ;
2004-03-04 13:40:59 +00:00
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 ;
2012-07-16 14:52:00 +08:00
use = xmlBufUse ( buf ) ;
2013-02-11 11:52:44 +08:00
oldalloc = xmlBufGetAllocationScheme ( buf ) ;
xmlBufSetAllocationScheme ( buf , XML_BUFFER_ALLOC_DOUBLEIT ) ;
2004-03-04 13:40:59 +00:00
xmlNodeDumpOutput ( outbuf , doc , cur , level , format , NULL ) ;
2013-02-11 11:52:44 +08:00
xmlBufSetAllocationScheme ( buf , oldalloc ) ;
2004-03-04 13:40:59 +00:00
xmlFree ( outbuf ) ;
2012-07-16 14:52:00 +08:00
ret = xmlBufUse ( buf ) - use ;
2004-03-04 13:40:59 +00:00
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 .
*/
void
xmlElemDump ( 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
* @ 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 )
{
2004-03-15 13:46:37 +00:00
xmlSaveCtxt ctxt ;
2004-03-04 13:40:59 +00:00
# ifdef LIBXML_HTML_ENABLED
xmlDtdPtr dtd ;
int is_xhtml = 0 ;
# endif
xmlInitParser ( ) ;
2004-11-05 10:03:46 +00:00
if ( ( buf = = NULL ) | | ( cur = = NULL ) ) return ;
2005-03-31 15:22:56 +00:00
if ( encoding = = NULL )
encoding = " UTF-8 " ;
2004-03-15 13:46:37 +00:00
memset ( & ctxt , 0 , sizeof ( ctxt ) ) ;
ctxt . doc = doc ;
ctxt . buf = buf ;
ctxt . level = level ;
2010-11-01 14:24:56 +01:00
ctxt . format = format ? 1 : 0 ;
2004-03-15 13:46:37 +00:00
ctxt . encoding = ( const xmlChar * ) encoding ;
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( & ctxt ) ;
2008-09-25 14:31:40 +00:00
ctxt . options | = XML_SAVE_AS_XML ;
2004-03-15 13:46:37 +00:00
2004-03-04 13:40:59 +00:00
# ifdef LIBXML_HTML_ENABLED
dtd = xmlGetIntSubset ( doc ) ;
if ( dtd ! = NULL ) {
2005-09-12 21:43:20 +00:00
is_xhtml = xmlIsXHTML ( dtd - > SystemID , dtd - > ExternalID ) ;
if ( is_xhtml < 0 )
is_xhtml = 0 ;
2004-03-04 13:40:59 +00:00
}
if ( is_xhtml )
2004-03-15 13:46:37 +00:00
xhtmlNodeDumpOutput ( & ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
else
# endif
2004-03-15 13:46:37 +00:00
xmlNodeDumpOutputInternal ( & ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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 ) {
2004-03-15 13:46:37 +00:00
xmlSaveCtxt ctxt ;
2004-03-04 13:40:59 +00:00
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 ;
}
2004-03-15 13:46:37 +00:00
memset ( & ctxt , 0 , sizeof ( ctxt ) ) ;
ctxt . doc = out_doc ;
ctxt . buf = out_buff ;
ctxt . level = 0 ;
2010-11-01 14:24:56 +01:00
ctxt . format = format ? 1 : 0 ;
2004-03-15 13:46:37 +00:00
ctxt . encoding = ( const xmlChar * ) txt_encoding ;
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( & ctxt ) ;
2008-09-25 14:31:40 +00:00
ctxt . options | = XML_SAVE_AS_XML ;
2004-03-15 13:46:37 +00:00
xmlDocContentDumpOutput ( & ctxt , out_doc ) ;
2004-03-04 13:40:59 +00:00
xmlOutputBufferFlush ( out_buff ) ;
if ( out_buff - > conv ! = NULL ) {
2012-07-16 14:52:00 +08:00
* doc_txt_len = xmlBufUse ( out_buff - > conv ) ;
* doc_txt_ptr = xmlStrndup ( xmlBufContent ( out_buff - > conv ) , * doc_txt_len ) ;
2004-03-04 13:40:59 +00:00
} else {
2012-07-16 14:52:00 +08:00
* doc_txt_len = xmlBufUse ( out_buff - > buffer ) ;
* doc_txt_ptr = xmlStrndup ( xmlBufContent ( out_buff - > buffer ) , * doc_txt_len ) ;
2004-03-04 13:40:59 +00:00
}
( 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 ) {
2004-03-15 13:46:37 +00:00
xmlSaveCtxt ctxt ;
2004-03-04 13:40:59 +00:00
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 ) {
2007-07-26 11:41:46 +00:00
handler = xmlFindCharEncodingHandler ( encoding ) ;
if ( handler = = NULL ) {
xmlFree ( ( char * ) cur - > encoding ) ;
cur - > encoding = NULL ;
encoding = NULL ;
2004-03-04 13:40:59 +00:00
}
2007-07-26 11:41:46 +00:00
}
2004-03-04 13:40:59 +00:00
buf = xmlOutputBufferCreateFile ( f , handler ) ;
if ( buf = = NULL ) return ( - 1 ) ;
2004-03-15 13:46:37 +00:00
memset ( & ctxt , 0 , sizeof ( ctxt ) ) ;
ctxt . doc = cur ;
ctxt . buf = buf ;
ctxt . level = 0 ;
2010-11-01 14:24:56 +01:00
ctxt . format = format ? 1 : 0 ;
2004-03-15 13:46:37 +00:00
ctxt . encoding = ( const xmlChar * ) encoding ;
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( & ctxt ) ;
2008-09-25 14:31:40 +00:00
ctxt . options | = XML_SAVE_AS_XML ;
2004-03-15 13:46:37 +00:00
xmlDocContentDumpOutput ( & ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
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 .
2004-11-04 10:49:00 +00:00
* Warning ! This call xmlOutputBufferClose ( ) on buf which is not available
* after this call .
2004-03-04 13:40:59 +00:00
*
* returns : the number of bytes written or - 1 in case of failure .
*/
int
xmlSaveFileTo ( xmlOutputBufferPtr buf , xmlDocPtr cur , const char * encoding ) {
2004-03-15 13:46:37 +00:00
xmlSaveCtxt ctxt ;
2004-03-04 13:40:59 +00:00
int ret ;
2004-11-04 10:49:00 +00:00
if ( buf = = NULL ) return ( - 1 ) ;
if ( cur = = NULL ) {
xmlOutputBufferClose ( buf ) ;
return ( - 1 ) ;
}
2004-03-15 13:46:37 +00:00
memset ( & ctxt , 0 , sizeof ( ctxt ) ) ;
ctxt . doc = cur ;
ctxt . buf = buf ;
ctxt . level = 0 ;
ctxt . format = 0 ;
ctxt . encoding = ( const xmlChar * ) encoding ;
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( & ctxt ) ;
2008-09-25 14:31:40 +00:00
ctxt . options | = XML_SAVE_AS_XML ;
2004-03-15 13:46:37 +00:00
xmlDocContentDumpOutput ( & ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
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 .
2004-11-04 10:49:00 +00:00
* Warning ! This call xmlOutputBufferClose ( ) on buf which is not available
* after this call .
2004-03-04 13:40:59 +00:00
*
* returns : the number of bytes written or - 1 in case of failure .
*/
int
2004-03-15 13:46:37 +00:00
xmlSaveFormatFileTo ( xmlOutputBufferPtr buf , xmlDocPtr cur ,
const char * encoding , int format )
{
xmlSaveCtxt ctxt ;
int ret ;
2004-03-04 13:40:59 +00:00
2004-11-04 10:49:00 +00:00
if ( buf = = NULL ) return ( - 1 ) ;
2004-11-05 10:03:46 +00:00
if ( ( cur = = NULL ) | |
( ( cur - > type ! = XML_DOCUMENT_NODE ) & &
( cur - > type ! = XML_HTML_DOCUMENT_NODE ) ) ) {
2004-11-04 10:49:00 +00:00
xmlOutputBufferClose ( buf ) ;
return ( - 1 ) ;
}
2004-03-15 13:46:37 +00:00
memset ( & ctxt , 0 , sizeof ( ctxt ) ) ;
ctxt . doc = cur ;
ctxt . buf = buf ;
ctxt . level = 0 ;
2010-11-01 14:24:56 +01:00
ctxt . format = format ? 1 : 0 ;
2004-03-15 13:46:37 +00:00
ctxt . encoding = ( const xmlChar * ) encoding ;
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( & ctxt ) ;
2008-09-25 14:31:40 +00:00
ctxt . options | = XML_SAVE_AS_XML ;
2004-03-15 13:46:37 +00:00
xmlDocContentDumpOutput ( & ctxt , cur ) ;
ret = xmlOutputBufferClose ( buf ) ;
return ( ret ) ;
2004-03-04 13:40:59 +00:00
}
/**
* 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 ) {
2004-03-15 13:46:37 +00:00
xmlSaveCtxt ctxt ;
2004-03-04 13:40:59 +00:00
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
2012-09-11 13:26:36 +08:00
/*
2004-03-04 13:40:59 +00:00
* save the content to a temp buffer .
*/
buf = xmlOutputBufferCreateFilename ( filename , handler , cur - > compression ) ;
if ( buf = = NULL ) return ( - 1 ) ;
2004-03-15 13:46:37 +00:00
memset ( & ctxt , 0 , sizeof ( ctxt ) ) ;
ctxt . doc = cur ;
ctxt . buf = buf ;
ctxt . level = 0 ;
2010-11-01 14:24:56 +01:00
ctxt . format = format ? 1 : 0 ;
2004-03-15 13:46:37 +00:00
ctxt . encoding = ( const xmlChar * ) encoding ;
2004-03-28 16:12:44 +00:00
xmlSaveCtxtInit ( & ctxt ) ;
2008-09-25 14:31:40 +00:00
ctxt . options | = XML_SAVE_AS_XML ;
2004-03-15 13:46:37 +00:00
xmlDocContentDumpOutput ( & ctxt , cur ) ;
2004-03-04 13:40:59 +00:00
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 */
2005-04-01 13:11:58 +00:00
# define bottom_xmlsave
# include "elfgcchack.h"