1998-08-13 07:39:55 +04:00
/*
* tree . c : implemetation of access function for an XML tree .
*
* See Copyright for the status of this software .
*
* $ Id $
*
* TODO Cleanup the Dump mechanism .
*/
1998-09-23 04:49:46 +04:00
# include "config.h"
1998-08-13 07:39:55 +04:00
# include <stdio.h>
# include <ctype.h>
1998-10-02 00:51:15 +04:00
# include <stdlib.h>
1998-08-13 07:39:55 +04:00
# include <string.h> /* for memset() only ! */
1998-09-23 04:49:46 +04:00
# ifdef HAVE_ZLIB_H
# include <zlib.h>
# endif
1998-08-13 07:39:55 +04:00
# include "tree.h"
# include "entities.h"
static CHAR xmlStringText [ ] = { ' t ' , ' e ' , ' x ' , ' t ' , 0 } ;
int oldXMLWDcompatibility = 0 ;
int xmlIndentTreeOutput = 1 ;
1998-09-24 23:15:06 +04:00
static int xmlCompressMode = 0 ;
1998-08-13 07:39:55 +04:00
/************************************************************************
* *
* Allocation and deallocation of basic structures *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-20 10:14:16 +04:00
/**
* xmlUpgradeOldNs :
* @ doc : a document pointer
*
* Upgrade old style Namespaces ( PI ) and move them to the root of the document .
1998-08-13 07:39:55 +04:00
*/
void xmlUpgradeOldNs ( xmlDocPtr doc ) {
xmlNsPtr cur ;
if ( ( doc = = NULL ) | | ( doc - > oldNs = = NULL ) ) return ;
if ( doc - > root = = NULL ) {
fprintf ( stderr , " xmlUpgradeOldNs: failed no root ! \n " ) ;
return ;
}
cur = doc - > oldNs ;
while ( cur - > next ! = NULL ) {
cur - > type = XML_LOCAL_NAMESPACE ;
cur = cur - > next ;
}
cur - > type = XML_LOCAL_NAMESPACE ;
cur - > next = doc - > root - > nsDef ;
doc - > root - > nsDef = doc - > oldNs ;
doc - > oldNs = NULL ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewNs :
* @ node : the element carrying the namespace
* @ href : the URI associated
* @ prefix : the prefix for the namespace
*
1998-08-13 07:39:55 +04:00
* Creation of a new Namespace .
1998-10-20 10:14:16 +04:00
* return values : returns a new namespace pointer
1998-08-13 07:39:55 +04:00
*/
xmlNsPtr xmlNewNs ( xmlNodePtr node , const CHAR * href , const CHAR * prefix ) {
xmlNsPtr cur ;
if ( href = = NULL ) {
fprintf ( stderr , " xmlNewNs: href == NULL ! \n " ) ;
return ( NULL ) ;
}
/*
* Allocate a new DTD and fill the fields .
*/
cur = ( xmlNsPtr ) malloc ( sizeof ( xmlNs ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewNs : malloc failed \n " ) ;
return ( NULL ) ;
}
cur - > type = XML_LOCAL_NAMESPACE ;
if ( href ! = NULL )
cur - > href = xmlStrdup ( href ) ;
else
cur - > href = NULL ;
if ( prefix ! = NULL )
cur - > prefix = xmlStrdup ( prefix ) ;
else
cur - > prefix = NULL ;
/*
* Add it at the end to preserve parsing order . . .
*/
cur - > next = NULL ;
if ( node ! = NULL ) {
if ( node - > nsDef = = NULL ) {
node - > nsDef = cur ;
} else {
xmlNsPtr prev = node - > nsDef ;
while ( prev - > next ! = NULL ) prev = prev - > next ;
prev - > next = cur ;
}
}
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewGlobalNs :
* @ doc : the document carrying the namespace
* @ href : the URI associated
* @ prefix : the prefix for the namespace
*
* Creation of a Namespace , the old way using PI and without scoping , to AVOID .
* return values : returns a new namespace pointer
1998-08-13 07:39:55 +04:00
*/
xmlNsPtr xmlNewGlobalNs ( xmlDocPtr doc , const CHAR * href , const CHAR * prefix ) {
xmlNsPtr cur ;
/*
* Allocate a new DTD and fill the fields .
*/
cur = ( xmlNsPtr ) malloc ( sizeof ( xmlNs ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewNs : malloc failed \n " ) ;
return ( NULL ) ;
}
cur - > type = XML_GLOBAL_NAMESPACE ;
if ( href ! = NULL )
cur - > href = xmlStrdup ( href ) ;
else
cur - > href = NULL ;
if ( prefix ! = NULL )
cur - > prefix = xmlStrdup ( prefix ) ;
else
cur - > prefix = NULL ;
/*
* Add it at the end to preserve parsing order . . .
*/
cur - > next = NULL ;
if ( doc ! = NULL ) {
if ( doc - > oldNs = = NULL ) {
doc - > oldNs = cur ;
} else {
xmlNsPtr prev = doc - > oldNs ;
while ( prev - > next ! = NULL ) prev = prev - > next ;
prev - > next = cur ;
}
}
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlSetNs :
* @ node : a node in the document
* @ ns : a namespace pointer
*
* Associate a namespace to a node , a posteriori .
1998-08-13 07:39:55 +04:00
*/
void xmlSetNs ( xmlNodePtr node , xmlNsPtr ns ) {
if ( node = = NULL ) {
fprintf ( stderr , " xmlSetNs: node == NULL \n " ) ;
return ;
}
node - > ns = ns ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeNs :
* @ cur : the namespace pointer
*
* Free up the structures associated to a namespace
1998-08-13 07:39:55 +04:00
*/
void xmlFreeNs ( xmlNsPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeNs : ns == NULL \n " ) ;
return ;
}
if ( cur - > href ! = NULL ) free ( ( char * ) cur - > href ) ;
if ( cur - > prefix ! = NULL ) free ( ( char * ) cur - > prefix ) ;
memset ( cur , - 1 , sizeof ( xmlNs ) ) ;
free ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeNsList :
* @ cur : the first namespace pointer
*
* Free up all the structures associated to the chained namespaces .
1998-08-13 07:39:55 +04:00
*/
void xmlFreeNsList ( xmlNsPtr cur ) {
xmlNsPtr next ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeNsList : ns == NULL \n " ) ;
return ;
}
while ( cur ! = NULL ) {
next = cur - > next ;
xmlFreeNs ( cur ) ;
cur = next ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewDtd :
* @ doc : the document pointer
* @ name : the DTD name
* @ ExternalID : the external ID
* @ SystemID : the system ID
*
1998-08-13 07:39:55 +04:00
* Creation of a new DTD .
1998-10-20 10:14:16 +04:00
* return values : a pointer to the new DTD structure
1998-08-13 07:39:55 +04:00
*/
xmlDtdPtr xmlNewDtd ( xmlDocPtr doc , const CHAR * name ,
const CHAR * ExternalID , const CHAR * SystemID ) {
xmlDtdPtr cur ;
if ( doc - > dtd ! = NULL ) {
fprintf ( stderr , " xmlNewDtd(%s): document %s already have a DTD %s \n " ,
/* !!! */ ( char * ) name , doc - > name , /* !!! */ ( char * ) doc - > dtd - > name ) ;
}
/*
* Allocate a new DTD and fill the fields .
*/
cur = ( xmlDtdPtr ) malloc ( sizeof ( xmlDtd ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewNs : malloc failed \n " ) ;
return ( NULL ) ;
}
if ( name ! = NULL )
cur - > name = xmlStrdup ( name ) ;
else
cur - > name = NULL ;
if ( ExternalID ! = NULL )
cur - > ExternalID = xmlStrdup ( ExternalID ) ;
else
cur - > ExternalID = NULL ;
if ( SystemID ! = NULL )
cur - > SystemID = xmlStrdup ( SystemID ) ;
else
cur - > SystemID = NULL ;
cur - > elements = NULL ;
cur - > entities = NULL ;
doc - > dtd = cur ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeDtd :
* @ cur : the DTD structure to free up
*
* Free a DTD structure .
1998-08-13 07:39:55 +04:00
*/
void xmlFreeDtd ( xmlDtdPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeDtd : DTD == NULL \n " ) ;
return ;
}
if ( cur - > name ! = NULL ) free ( ( char * ) cur - > name ) ;
if ( cur - > SystemID ! = NULL ) free ( ( char * ) cur - > SystemID ) ;
if ( cur - > ExternalID ! = NULL ) free ( ( char * ) cur - > ExternalID ) ;
if ( cur - > elements ! = NULL )
fprintf ( stderr , " xmlFreeDtd: cur->elements != NULL !!! \n " ) ;
if ( cur - > entities ! = NULL )
xmlFreeEntitiesTable ( ( xmlEntitiesTablePtr ) cur - > entities ) ;
memset ( cur , - 1 , sizeof ( xmlDtd ) ) ;
free ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewDoc :
* @ version : CHAR string giving the version of XML " 1.0 "
*
* Create a new document
1998-08-13 07:39:55 +04:00
*/
xmlDocPtr xmlNewDoc ( const CHAR * version ) {
xmlDocPtr cur ;
if ( version = = NULL ) {
fprintf ( stderr , " xmlNewDoc : version == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Allocate a new document and fill the fields .
*/
cur = ( xmlDocPtr ) malloc ( sizeof ( xmlDoc ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewDoc : malloc failed \n " ) ;
return ( NULL ) ;
}
1998-10-18 23:12:41 +04:00
cur - > type = XML_DOCUMENT_NODE ;
1998-08-13 07:39:55 +04:00
cur - > version = xmlStrdup ( version ) ;
cur - > name = NULL ;
cur - > root = NULL ;
cur - > dtd = NULL ;
cur - > oldNs = NULL ;
cur - > encoding = NULL ;
cur - > entities = NULL ;
cur - > standalone = - 1 ;
1998-09-24 23:15:06 +04:00
cur - > compression = xmlCompressMode ;
1998-10-17 10:47:46 +04:00
# ifndef WITHOUT_CORBA
cur - > _private = NULL ;
cur - > vepv = NULL ;
# endif
1998-08-13 07:39:55 +04:00
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeDoc :
* @ cur : pointer to the document
* @ :
*
* Free up all the structures used by a document , tree included .
1998-08-13 07:39:55 +04:00
*/
void xmlFreeDoc ( xmlDocPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeDoc : document == NULL \n " ) ;
return ;
}
free ( ( char * ) cur - > version ) ;
if ( cur - > name ! = NULL ) free ( ( char * ) cur - > name ) ;
if ( cur - > encoding ! = NULL ) free ( ( char * ) cur - > encoding ) ;
if ( cur - > root ! = NULL ) xmlFreeNode ( cur - > root ) ;
if ( cur - > dtd ! = NULL ) xmlFreeDtd ( cur - > dtd ) ;
if ( cur - > entities ! = NULL )
xmlFreeEntitiesTable ( ( xmlEntitiesTablePtr ) cur - > entities ) ;
memset ( cur , - 1 , sizeof ( xmlDoc ) ) ;
free ( cur ) ;
}
1998-10-27 09:21:04 +03:00
/**
* xmlStringGetNodeList :
* @ doc : the document
* @ value : the value of the attribute
*
* Parse the value string and build the node list associated . Should
* produce a flat tree with only TEXTs and ENTITY_REFs .
* return values : a pointer to the first child
*/
xmlNodePtr xmlStringGetNodeList ( xmlDocPtr doc , const CHAR * value ) {
xmlNodePtr ret = NULL , last = NULL ;
xmlNodePtr node ;
CHAR * val ;
const CHAR * cur = value ;
const CHAR * q ;
if ( value = = NULL ) return ( NULL ) ;
q = cur ;
while ( * cur ! = 0 ) {
if ( * cur = = ' & ' ) {
if ( cur ! = q ) {
node = xmlNewTextLen ( q , cur - q ) ;
if ( node = = NULL ) return ( ret ) ;
if ( last = = NULL )
last = ret = node ;
else {
last - > next = node ;
last = node ;
}
}
cur + + ;
q = cur ;
while ( ( * cur ! = 0 ) & & ( * cur ! = ' ; ' ) ) cur + + ;
if ( * cur = = 0 ) {
fprintf ( stderr ,
" xmlStringGetNodeList: unterminated entity %30s \n " , q ) ;
return ( ret ) ;
}
if ( cur ! = q ) {
val = xmlStrndup ( q , cur - q ) ;
node = xmlNewReference ( doc , val ) ;
if ( node = = NULL ) return ( ret ) ;
if ( last = = NULL )
last = ret = node ;
else {
last - > next = node ;
last = node ;
}
free ( val ) ;
}
cur + + ;
q = cur ;
} else
cur + + ;
}
if ( cur ! = q ) {
node = xmlNewTextLen ( q , cur - q ) ;
if ( node = = NULL ) return ( ret ) ;
if ( last = = NULL )
last = ret = node ;
else {
last - > next = node ;
last = node ;
}
}
return ( ret ) ;
}
/**
* xmlNodeListGetString :
* @ doc : the document
* @ list : a Node list
* @ inLine : should we replace entity contents or show their external form
*
* Returns the string equivalent to the text contained in the Node list
* made of TEXTs and ENTITY_REFs
* return values : a pointer to the string copy , the calller must free it .
*/
CHAR * xmlNodeListGetString ( xmlDocPtr doc , xmlNodePtr list , int inLine ) {
xmlNodePtr node = list ;
CHAR * ret = NULL ;
xmlEntityPtr ent ;
if ( list = = NULL ) return ( NULL ) ;
while ( node ! = NULL ) {
if ( node - > type = = XML_TEXT_NODE ) {
if ( inLine )
ret = xmlStrcat ( ret , node - > content ) ;
else
ret = xmlStrcat ( ret , xmlEncodeEntities ( doc , node - > content ) ) ;
} else if ( node - > type = = XML_ENTITY_REF_NODE ) {
if ( inLine ) {
ent = xmlGetDocEntity ( doc , node - > name ) ;
if ( ent ! = NULL )
ret = xmlStrcat ( ret , ent - > content ) ;
else
ret = xmlStrcat ( ret , node - > content ) ;
} else {
CHAR buf [ 2 ] ;
buf [ 0 ] = ' & ' ; buf [ 1 ] = 0 ;
ret = xmlStrncat ( ret , buf , 1 ) ;
ret = xmlStrcat ( ret , node - > name ) ;
buf [ 0 ] = ' ; ' ; buf [ 1 ] = 0 ;
ret = xmlStrncat ( ret , buf , 1 ) ;
}
}
#if 0
else {
fprintf ( stderr , " xmlGetNodeListString : invalide node type %d \n " ,
node - > type ) ;
}
# endif
node = node - > next ;
}
return ( ret ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewProp :
* @ node : the holding node
* @ name : the name of the attribute
* @ value : the value of the attribute
*
* Create a new property carried by a node .
* return values : a pointer to the attribute
1998-08-13 07:39:55 +04:00
*/
xmlAttrPtr xmlNewProp ( xmlNodePtr node , const CHAR * name , const CHAR * value ) {
xmlAttrPtr cur ;
if ( name = = NULL ) {
fprintf ( stderr , " xmlNewProp : name == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Allocate a new property and fill the fields .
*/
cur = ( xmlAttrPtr ) malloc ( sizeof ( xmlAttr ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewProp : malloc failed \n " ) ;
return ( NULL ) ;
}
1998-10-18 23:12:41 +04:00
cur - > type = XML_ATTRIBUTE_NODE ;
1998-08-13 07:39:55 +04:00
cur - > node = node ;
cur - > name = xmlStrdup ( name ) ;
if ( value ! = NULL )
1998-10-27 09:21:04 +03:00
cur - > val = xmlStringGetNodeList ( node - > doc , value ) ;
1998-08-13 07:39:55 +04:00
else
1998-10-27 09:21:04 +03:00
cur - > val = NULL ;
1998-10-17 10:47:46 +04:00
# ifndef WITHOUT_CORBA
cur - > _private = NULL ;
cur - > vepv = NULL ;
# endif
1998-08-13 07:39:55 +04:00
/*
* Add it at the end to preserve parsing order . . .
*/
cur - > next = NULL ;
if ( node ! = NULL ) {
if ( node - > properties = = NULL ) {
node - > properties = cur ;
} else {
xmlAttrPtr prev = node - > properties ;
while ( prev - > next ! = NULL ) prev = prev - > next ;
prev - > next = cur ;
}
}
return ( cur ) ;
}
1998-10-27 09:21:04 +03:00
/**
* xmlNewDocProp :
* @ doc : the document
* @ name : the name of the attribute
* @ value : the value of the attribute
*
* Create a new property carried by a document .
* return values : a pointer to the attribute
*/
xmlAttrPtr xmlNewDocProp ( xmlDocPtr doc , const CHAR * name , const CHAR * value ) {
xmlAttrPtr cur ;
if ( name = = NULL ) {
fprintf ( stderr , " xmlNewProp : name == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Allocate a new property and fill the fields .
*/
cur = ( xmlAttrPtr ) malloc ( sizeof ( xmlAttr ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewProp : malloc failed \n " ) ;
return ( NULL ) ;
}
cur - > type = XML_ATTRIBUTE_NODE ;
cur - > node = NULL ;
cur - > name = xmlStrdup ( name ) ;
if ( value ! = NULL )
cur - > val = xmlStringGetNodeList ( doc , value ) ;
else
cur - > val = NULL ;
# ifndef WITHOUT_CORBA
cur - > _private = NULL ;
cur - > vepv = NULL ;
# endif
cur - > next = NULL ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreePropList :
* @ cur : the first property in the list
*
* Free a property and all its siblings , all the childs are freed too .
1998-08-13 07:39:55 +04:00
*/
void xmlFreePropList ( xmlAttrPtr cur ) {
xmlAttrPtr next ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreePropList : property == NULL \n " ) ;
return ;
}
while ( cur ! = NULL ) {
next = cur - > next ;
xmlFreeProp ( cur ) ;
cur = next ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeProp :
* @ cur : the first property in the list
*
* Free one property , all the childs are freed too .
1998-08-13 07:39:55 +04:00
*/
void xmlFreeProp ( xmlAttrPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeProp : property == NULL \n " ) ;
return ;
}
if ( cur - > name ! = NULL ) free ( ( char * ) cur - > name ) ;
1998-10-27 09:21:04 +03:00
if ( cur - > val ! = NULL ) xmlFreeNodeList ( cur - > val ) ;
1998-08-13 07:39:55 +04:00
memset ( cur , - 1 , sizeof ( xmlAttr ) ) ;
free ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewNode :
* @ ns : namespace if any
* @ name : the node name
* @ content : the text content if any
*
* Creation of a new node element . @ ns and @ content are optionnal ( NULL ) .
1998-10-27 09:21:04 +03:00
* If content is non NULL , a child list containing the TEXTs and
* ENTITY_REFs node will be created .
1998-10-20 10:14:16 +04:00
* return values : a pointer to the new node object .
1998-08-13 07:39:55 +04:00
*/
1998-10-27 09:21:04 +03:00
xmlNodePtr xmlNewNode ( xmlNsPtr ns , const CHAR * name ) {
1998-08-13 07:39:55 +04:00
xmlNodePtr cur ;
if ( name = = NULL ) {
fprintf ( stderr , " xmlNewNode : name == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Allocate a new node and fill the fields .
*/
cur = ( xmlNodePtr ) malloc ( sizeof ( xmlNode ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewNode : malloc failed \n " ) ;
return ( NULL ) ;
}
1998-10-18 23:12:41 +04:00
cur - > type = XML_ELEMENT_NODE ;
1998-10-14 06:36:47 +04:00
cur - > doc = NULL ;
1998-08-13 07:39:55 +04:00
cur - > parent = NULL ;
1998-10-14 06:36:47 +04:00
cur - > next = NULL ;
cur - > prev = NULL ;
cur - > childs = NULL ;
cur - > properties = NULL ;
1998-08-13 07:39:55 +04:00
cur - > type = 0 ;
cur - > name = xmlStrdup ( name ) ;
cur - > ns = ns ;
cur - > nsDef = NULL ;
1998-10-27 09:21:04 +03:00
cur - > content = NULL ;
1998-10-17 10:47:46 +04:00
# ifndef WITHOUT_CORBA
cur - > _private = NULL ;
cur - > vepv = NULL ;
# endif
1998-08-13 07:39:55 +04:00
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewDocNode :
* @ doc : the document
* @ ns : namespace if any
* @ name : the node name
* @ content : the text content if any
*
* Creation of a new node element within a document . @ ns and @ content
* are optionnal ( NULL ) .
* return values : a pointer to the new node object .
*/
1998-10-14 06:36:47 +04:00
xmlNodePtr xmlNewDocNode ( xmlDocPtr doc , xmlNsPtr ns ,
const CHAR * name , CHAR * content ) {
xmlNodePtr cur ;
1998-10-27 09:21:04 +03:00
cur = xmlNewNode ( ns , name ) ;
if ( cur ! = NULL ) {
cur - > doc = doc ;
if ( content ! = NULL )
cur - > childs = xmlStringGetNodeList ( doc , content ) ;
}
1998-10-14 06:36:47 +04:00
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewText :
* @ content : the text content
*
* Creation of a new text node .
* return values : a pointer to the new node object .
1998-08-13 07:39:55 +04:00
*/
xmlNodePtr xmlNewText ( const CHAR * content ) {
xmlNodePtr cur ;
/*
* Allocate a new node and fill the fields .
*/
cur = ( xmlNodePtr ) malloc ( sizeof ( xmlNode ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewText : malloc failed \n " ) ;
return ( NULL ) ;
}
1998-10-18 23:12:41 +04:00
cur - > type = XML_TEXT_NODE ;
1998-10-14 06:36:47 +04:00
cur - > doc = NULL ;
1998-08-13 07:39:55 +04:00
cur - > parent = NULL ;
cur - > next = NULL ;
1998-10-14 06:36:47 +04:00
cur - > prev = NULL ;
1998-08-13 07:39:55 +04:00
cur - > childs = NULL ;
cur - > properties = NULL ;
1998-10-14 06:36:47 +04:00
cur - > type = XML_TEXT_NODE ;
1998-08-13 07:39:55 +04:00
cur - > name = xmlStrdup ( xmlStringText ) ;
cur - > ns = NULL ;
cur - > nsDef = NULL ;
if ( content ! = NULL )
cur - > content = xmlStrdup ( content ) ;
else
cur - > content = NULL ;
return ( cur ) ;
}
1998-10-27 09:21:04 +03:00
/**
* xmlNewReference :
* @ doc : the document
* @ name : the reference name , or the reference string with & and ;
*
* Creation of a new reference node .
* return values : a pointer to the new node object .
*/
xmlNodePtr xmlNewReference ( xmlDocPtr doc , const CHAR * name ) {
xmlNodePtr cur ;
xmlEntityPtr ent ;
/*
* Allocate a new node and fill the fields .
*/
cur = ( xmlNodePtr ) malloc ( sizeof ( xmlNode ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewText : malloc failed \n " ) ;
return ( NULL ) ;
}
cur - > type = XML_ENTITY_REF_NODE ;
cur - > doc = NULL ;
cur - > parent = NULL ;
cur - > next = NULL ;
cur - > prev = NULL ;
cur - > childs = NULL ;
cur - > properties = NULL ;
if ( name [ 0 ] = = ' & ' ) {
int len ;
name + + ;
len = xmlStrlen ( name ) ;
if ( name [ len - 1 ] = = ' ; ' )
cur - > name = xmlStrndup ( name , len - 1 ) ;
else
cur - > name = xmlStrndup ( name , len ) ;
} else
cur - > name = xmlStrdup ( name ) ;
cur - > ns = NULL ;
cur - > nsDef = NULL ;
ent = xmlGetDocEntity ( doc , cur - > name ) ;
if ( ent ! = NULL )
cur - > content = ent - > content ;
else
cur - > content = NULL ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewDocText :
* @ doc : the document
* @ content : the text content
*
* Creation of a new text node within a document .
* return values : a pointer to the new node object .
*/
1998-10-14 06:36:47 +04:00
xmlNodePtr xmlNewDocText ( xmlDocPtr doc , const CHAR * content ) {
xmlNodePtr cur ;
cur = xmlNewText ( content ) ;
if ( cur ! = NULL ) cur - > doc = doc ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
1998-10-27 09:21:04 +03:00
* xmlNewTextLen :
1998-10-20 10:14:16 +04:00
* @ content : the text content
* @ len : the text len .
*
* Creation of a new text node with an extra parameter for the content ' s lenght
* return values : a pointer to the new node object .
1998-08-13 07:39:55 +04:00
*/
xmlNodePtr xmlNewTextLen ( const CHAR * content , int len ) {
xmlNodePtr cur ;
/*
* Allocate a new node and fill the fields .
*/
cur = ( xmlNodePtr ) malloc ( sizeof ( xmlNode ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewText : malloc failed \n " ) ;
return ( NULL ) ;
}
1998-10-18 23:12:41 +04:00
cur - > type = XML_TEXT_NODE ;
1998-10-14 06:36:47 +04:00
cur - > doc = NULL ;
1998-08-13 07:39:55 +04:00
cur - > parent = NULL ;
1998-10-14 06:36:47 +04:00
cur - > prev = NULL ;
1998-08-13 07:39:55 +04:00
cur - > next = NULL ;
cur - > childs = NULL ;
cur - > properties = NULL ;
1998-10-14 06:36:47 +04:00
cur - > type = XML_TEXT_NODE ;
1998-08-13 07:39:55 +04:00
cur - > name = xmlStrdup ( xmlStringText ) ;
cur - > ns = NULL ;
cur - > nsDef = NULL ;
if ( content ! = NULL )
cur - > content = xmlStrndup ( content , len ) ;
else
cur - > content = NULL ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewDocTextLen :
* @ doc : the document
* @ content : the text content
* @ len : the text len .
*
* Creation of a new text node with an extra content lenght parameter . The
* text node pertain to a given document .
* return values : a pointer to the new node object .
*/
1998-10-14 06:36:47 +04:00
xmlNodePtr xmlNewDocTextLen ( xmlDocPtr doc , const CHAR * content , int len ) {
xmlNodePtr cur ;
cur = xmlNewTextLen ( content , len ) ;
if ( cur ! = NULL ) cur - > doc = doc ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewComment :
* @ content : the comment content
*
* Creation of a new node containing a comment .
* return values : a pointer to the new node object .
1998-08-13 07:39:55 +04:00
*/
xmlNodePtr xmlNewComment ( CHAR * content ) {
xmlNodePtr cur ;
/*
* Allocate a new node and fill the fields .
*/
cur = ( xmlNodePtr ) malloc ( sizeof ( xmlNode ) ) ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNewComment : malloc failed \n " ) ;
return ( NULL ) ;
}
1998-10-18 23:12:41 +04:00
cur - > type = XML_COMMENT_NODE ;
1998-10-14 06:36:47 +04:00
cur - > doc = NULL ;
1998-08-13 07:39:55 +04:00
cur - > parent = NULL ;
1998-10-14 06:36:47 +04:00
cur - > prev = NULL ;
1998-08-13 07:39:55 +04:00
cur - > next = NULL ;
cur - > childs = NULL ;
cur - > properties = NULL ;
1998-10-14 06:36:47 +04:00
cur - > type = XML_COMMENT_NODE ;
1998-08-13 07:39:55 +04:00
cur - > name = xmlStrdup ( xmlStringText ) ;
cur - > ns = NULL ;
cur - > nsDef = NULL ;
if ( content ! = NULL )
cur - > content = xmlStrdup ( content ) ;
else
cur - > content = NULL ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewComment :
* @ doc : the document
* @ content : the comment content
*
* Creation of a new node containing a commentwithin a document .
* return values : a pointer to the new node object .
*/
1998-10-14 06:36:47 +04:00
xmlNodePtr xmlNewDocComment ( xmlDocPtr doc , CHAR * content ) {
xmlNodePtr cur ;
cur = xmlNewComment ( content ) ;
if ( cur ! = NULL ) cur - > doc = doc ;
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNewChild :
* @ parent : the parent node
* @ ns : a namespace if any
* @ name : the name of the child
* @ content : the content of the child if any .
*
*
* Creation of a new child element , added at the end of @ parent childs list .
1998-10-27 09:21:04 +03:00
* @ ns and @ content parameters are optionnal ( NULL ) . If content is non NULL ,
* a child list containing the TEXTs and ENTITY_REFs node will be created .
1998-10-20 10:14:16 +04:00
* return values : a pointer to the new node object .
1998-08-13 07:39:55 +04:00
*/
xmlNodePtr xmlNewChild ( xmlNodePtr parent , xmlNsPtr ns ,
const CHAR * name , CHAR * content ) {
xmlNodePtr cur , prev ;
if ( parent = = NULL ) {
fprintf ( stderr , " xmlNewChild : parent == NULL \n " ) ;
return ( NULL ) ;
}
if ( name = = NULL ) {
fprintf ( stderr , " xmlNewChild : name == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Allocate a new node
*/
if ( ns = = NULL )
1998-10-27 09:21:04 +03:00
cur = xmlNewDocNode ( parent - > doc , parent - > ns , name , content ) ;
1998-08-13 07:39:55 +04:00
else
1998-10-27 09:21:04 +03:00
cur = xmlNewDocNode ( parent - > doc , ns , name , content ) ;
1998-08-13 07:39:55 +04:00
if ( cur = = NULL ) return ( NULL ) ;
/*
* add the new element at the end of the childs list .
*/
1998-10-27 09:21:04 +03:00
cur - > type = XML_ELEMENT_NODE ;
1998-08-13 07:39:55 +04:00
cur - > parent = parent ;
1998-10-14 06:36:47 +04:00
cur - > doc = parent - > doc ;
1998-08-13 07:39:55 +04:00
if ( parent - > childs = = NULL ) {
parent - > childs = cur ;
} else {
prev = parent - > childs ;
while ( prev - > next ! = NULL ) prev = prev - > next ;
prev - > next = cur ;
1998-10-14 06:36:47 +04:00
cur - > prev = prev ;
1998-08-13 07:39:55 +04:00
}
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlAddChild :
* @ parent : the parent node
* @ cur : the child node
*
* Add a new child element , to @ parent , at the end of the child list .
* return values : the child or NULL in case of error .
1998-08-13 07:39:55 +04:00
*/
xmlNodePtr xmlAddChild ( xmlNodePtr parent , xmlNodePtr cur ) {
xmlNodePtr prev ;
if ( parent = = NULL ) {
fprintf ( stderr , " xmladdChild : parent == NULL \n " ) ;
return ( NULL ) ;
}
if ( cur = = NULL ) {
fprintf ( stderr , " xmladdChild : child == NULL \n " ) ;
return ( NULL ) ;
}
1998-10-14 06:36:47 +04:00
if ( ( cur - > doc ! = NULL ) & & ( parent - > doc ! = NULL ) & &
( cur - > doc ! = parent - > doc ) ) {
fprintf ( stderr , " Elements moved to a different document \n " ) ;
}
1998-08-13 07:39:55 +04:00
/*
* add the new element at the end of the childs list .
*/
cur - > parent = parent ;
1998-10-14 06:36:47 +04:00
cur - > doc = parent - > doc ; /* the parent may not be linked to a doc ! */
1998-10-27 09:21:04 +03:00
/*
* Handle the case where parent - > content ! = NULL , in that case it will
* create a intermediate TEXT node .
*/
if ( parent - > content ! = NULL ) {
xmlNodePtr text ;
text = xmlNewDocText ( parent - > doc , parent - > content ) ;
if ( text ! = NULL ) {
text - > next = parent - > childs ;
if ( text - > next ! = NULL )
text - > next - > prev = text ;
parent - > childs = text ;
free ( parent - > content ) ;
parent - > content = NULL ;
}
}
1998-08-13 07:39:55 +04:00
if ( parent - > childs = = NULL ) {
parent - > childs = cur ;
} else {
prev = parent - > childs ;
while ( prev - > next ! = NULL ) prev = prev - > next ;
prev - > next = cur ;
1998-10-14 06:36:47 +04:00
cur - > prev = prev ;
1998-08-13 07:39:55 +04:00
}
return ( cur ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlGetLastChild :
* @ parent : the parent node
*
* Search the last child of a node .
* return values : the last child or NULL if none .
1998-08-13 07:39:55 +04:00
*/
xmlNodePtr xmlGetLastChild ( xmlNodePtr parent ) {
xmlNodePtr last ;
if ( parent = = NULL ) {
fprintf ( stderr , " xmlGetLastChild : parent == NULL \n " ) ;
return ( NULL ) ;
}
/*
* add the new element at the end of the childs list .
*/
if ( parent - > childs = = NULL ) {
return ( NULL ) ;
} else {
last = parent - > childs ;
while ( last - > next ! = NULL ) last = last - > next ;
}
return ( last ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeNodeList :
* @ cur : the first node in the list
*
* Free a node and all its siblings , this is a recursive behaviour , all
* the childs are freed too .
1998-08-13 07:39:55 +04:00
*/
void xmlFreeNodeList ( xmlNodePtr cur ) {
xmlNodePtr next ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeNodeList : node == NULL \n " ) ;
return ;
}
while ( cur ! = NULL ) {
next = cur - > next ;
xmlFreeNode ( cur ) ;
cur = next ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlFreeNode :
* @ cur : the node
*
* Free a node , this is a recursive behaviour , all the childs are freed too .
1998-08-13 07:39:55 +04:00
*/
void xmlFreeNode ( xmlNodePtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlFreeNode : node == NULL \n " ) ;
return ;
}
1998-10-27 09:21:04 +03:00
cur - > doc = NULL ;
cur - > parent = NULL ;
cur - > next = NULL ;
cur - > prev = NULL ;
1998-08-13 07:39:55 +04:00
if ( cur - > childs ! = NULL ) xmlFreeNodeList ( cur - > childs ) ;
1998-10-27 09:21:04 +03:00
if ( cur - > properties ! = NULL ) xmlFreePropList ( cur - > properties ) ;
if ( cur - > type ! = XML_ENTITY_REF_NODE )
if ( cur - > content ! = NULL ) free ( cur - > content ) ;
1998-08-13 07:39:55 +04:00
if ( cur - > name ! = NULL ) free ( ( char * ) cur - > name ) ;
if ( cur - > nsDef ! = NULL ) xmlFreeNsList ( cur - > nsDef ) ;
memset ( cur , - 1 , sizeof ( xmlNode ) ) ;
free ( cur ) ;
}
/************************************************************************
* *
* Content access functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-20 10:14:16 +04:00
/**
* xmlNodeSetContent :
* @ cur : the node being modified
* @ content : the new value of the content
*
* Replace the content of a node .
1998-08-13 07:39:55 +04:00
*/
void xmlNodeSetContent ( xmlNodePtr cur , const CHAR * content ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNodeSetContent : node == NULL \n " ) ;
return ;
}
if ( cur - > content ! = NULL ) free ( cur - > content ) ;
if ( content ! = NULL )
cur - > content = xmlStrdup ( content ) ;
else
cur - > content = NULL ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNodeSetContentLen :
* @ cur : the node being modified
* @ content : the new value of the content
* @ len : the size of @ content
*
* Replace the content of a node .
1998-08-13 07:39:55 +04:00
*/
void xmlNodeSetContentLen ( xmlNodePtr cur , const CHAR * content , int len ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNodeSetContent : node == NULL \n " ) ;
return ;
}
if ( cur - > content ! = NULL ) free ( cur - > content ) ;
if ( content ! = NULL )
cur - > content = xmlStrndup ( content , len ) ;
else
cur - > content = NULL ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNodeAddContent :
* @ cur : the node being modified
* @ content : extra content
*
* Append the extra substring to the node content .
1998-08-13 07:39:55 +04:00
*/
void xmlNodeAddContent ( xmlNodePtr cur , const CHAR * content ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNodeAddContent : node == NULL \n " ) ;
return ;
}
cur - > content = xmlStrcat ( cur - > content , content ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNodeAddContentLen :
* @ cur : the node being modified
* @ content : extra content
* @ len : the size of @ content
*
* Append the extra substring to the node content .
1998-08-13 07:39:55 +04:00
*/
void xmlNodeAddContentLen ( xmlNodePtr cur , const CHAR * content , int len ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNodeAddContent : node == NULL \n " ) ;
return ;
}
cur - > content = xmlStrncat ( cur - > content , content , len ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlSearchNs :
* @ doc : the document
* @ node : the current node
* @ nameSpace : the namespace string
1998-08-13 07:39:55 +04:00
*
1998-10-20 10:14:16 +04:00
* Search a Ns registered under a given name space for a document .
* recurse on the parents until it finds the defined namespace
* or return NULL otherwise .
* @ nameSpace can be NULL , this is a search for the default namespace .
* return values : the namespace pointer or NULL .
1998-08-13 07:39:55 +04:00
*/
xmlNsPtr xmlSearchNs ( xmlDocPtr doc , xmlNodePtr node , const CHAR * nameSpace ) {
xmlNsPtr cur ;
while ( node ! = NULL ) {
cur = node - > nsDef ;
while ( cur ! = NULL ) {
if ( ( cur - > prefix = = NULL ) & & ( nameSpace = = NULL ) )
return ( cur ) ;
if ( ( cur - > prefix ! = NULL ) & & ( nameSpace ! = NULL ) & &
( ! xmlStrcmp ( cur - > prefix , nameSpace ) ) )
return ( cur ) ;
cur = cur - > next ;
}
node = node - > parent ;
}
if ( doc ! = NULL ) {
cur = doc - > oldNs ;
while ( cur ! = NULL ) {
if ( ( cur - > prefix ! = NULL ) & & ( nameSpace ! = NULL ) & &
( ! xmlStrcmp ( cur - > prefix , nameSpace ) ) )
return ( cur ) ;
cur = cur - > next ;
}
}
return ( NULL ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlSearchNsByHref :
* @ doc : the document
* @ node : the current node
* @ href : the namespace value
*
* Search a Ns aliasing a given URI . Recurse on the parents until it finds
* the defined namespace or return NULL otherwise .
* return values : the namespace pointer or NULL .
1998-08-13 07:39:55 +04:00
*/
xmlNsPtr xmlSearchNsByHref ( xmlDocPtr doc , xmlNodePtr node , const CHAR * href ) {
xmlNsPtr cur ;
while ( node ! = NULL ) {
cur = node - > nsDef ;
while ( cur ! = NULL ) {
if ( ( cur - > href ! = NULL ) & & ( href ! = NULL ) & &
( ! xmlStrcmp ( cur - > href , href ) ) )
return ( cur ) ;
cur = cur - > next ;
}
node = node - > parent ;
}
if ( doc ! = NULL ) {
cur = doc - > oldNs ;
while ( cur ! = NULL ) {
if ( ( cur - > href ! = NULL ) & & ( href ! = NULL ) & &
( ! xmlStrcmp ( cur - > href , href ) ) )
return ( cur ) ;
cur = cur - > next ;
}
}
return ( NULL ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlGetProp :
* @ node : the node
* @ name : the attribute name
*
* Search and get the value of an attribute associated to a node
1998-10-27 09:21:04 +03:00
* This does the entity substitution .
1998-10-20 10:14:16 +04:00
* return values : the attribute value or NULL if not found .
1998-08-13 07:39:55 +04:00
*/
const CHAR * xmlGetProp ( xmlNodePtr node , const CHAR * name ) {
xmlAttrPtr prop = node - > properties ;
while ( prop ! = NULL ) {
1998-10-27 09:21:04 +03:00
if ( ! xmlStrcmp ( prop - > name , name ) )
return ( xmlNodeListGetString ( node - > doc , prop - > val , 1 ) ) ;
1998-08-13 07:39:55 +04:00
prop = prop - > next ;
}
return ( NULL ) ;
}
1998-10-20 10:14:16 +04:00
/**
1998-10-27 09:21:04 +03:00
* xmlSetProp :
1998-10-20 10:14:16 +04:00
* @ node : the node
* @ name : the attribute name
* @ value : the attribute value
*
* Set ( or reset ) an attribute carried by a node .
* return values : the attribute pointer .
1998-08-13 07:39:55 +04:00
*/
xmlAttrPtr xmlSetProp ( xmlNodePtr node , const CHAR * name , const CHAR * value ) {
xmlAttrPtr prop = node - > properties ;
while ( prop ! = NULL ) {
if ( ! xmlStrcmp ( prop - > name , name ) ) {
1998-10-27 09:21:04 +03:00
if ( prop - > val ! = NULL )
xmlFreeNode ( prop - > val ) ;
prop - > val = NULL ;
1998-08-13 07:39:55 +04:00
if ( value ! = NULL )
1998-10-27 09:21:04 +03:00
prop - > val = xmlStringGetNodeList ( node - > doc , value ) ;
1998-08-13 07:39:55 +04:00
return ( prop ) ;
}
prop = prop - > next ;
}
prop = xmlNewProp ( node , name , value ) ;
return ( prop ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNodeIsText :
* @ node : the node
*
* Is this node a Text node ?
* return values : 1 yes , 0 no
1998-08-13 07:39:55 +04:00
*/
int xmlNodeIsText ( xmlNodePtr node ) {
if ( node = = NULL ) return ( 0 ) ;
1998-10-14 06:36:47 +04:00
if ( node - > type = = XML_TEXT_NODE ) return ( 1 ) ;
1998-08-13 07:39:55 +04:00
return ( 0 ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlNodeIsText :
* @ node : the node
* @ content : the content
* @ len : @ content lenght
*
* Concat the given string at the end of the existing node content
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
1998-08-13 07:39:55 +04:00
void xmlTextConcat ( xmlNodePtr node , const CHAR * content , int len ) {
if ( node = = NULL ) return ;
1998-10-14 06:36:47 +04:00
if ( node - > type ! = XML_TEXT_NODE ) {
1998-08-13 07:39:55 +04:00
fprintf ( stderr , " xmlTextConcat: node is not text \n " ) ;
return ;
}
node - > content = xmlStrncat ( node - > content , content , len ) ;
}
/************************************************************************
* *
* Output : to a FILE or in memory *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static CHAR * buffer = NULL ;
static int buffer_index = 0 ;
static int buffer_size = 0 ;
1998-10-20 10:14:16 +04:00
/**
* xmlBufferWriteCHAR :
* @ string : the string to add
*
* routine which manage and grows an output buffer . This one add
* CHARs at the end of the array .
*/
1998-08-13 07:39:55 +04:00
void xmlBufferWriteCHAR ( const CHAR * string ) {
const CHAR * cur ;
if ( buffer = = NULL ) {
buffer_size = 50000 ;
buffer = ( CHAR * ) malloc ( buffer_size * sizeof ( CHAR ) ) ;
if ( buffer = = NULL ) {
fprintf ( stderr , " xmlBufferWrite : out of memory! \n " ) ;
exit ( 1 ) ;
}
}
if ( string = = NULL ) return ;
for ( cur = string ; * cur ! = 0 ; cur + + ) {
if ( buffer_index + 10 > = buffer_size ) {
buffer_size * = 2 ;
buffer = ( CHAR * ) realloc ( buffer , buffer_size * sizeof ( CHAR ) ) ;
if ( buffer = = NULL ) {
fprintf ( stderr , " xmlBufferWrite : out of memory! \n " ) ;
exit ( 1 ) ;
}
}
buffer [ buffer_index + + ] = * cur ;
}
buffer [ buffer_index ] = 0 ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlBufferWriteChar :
* @ string : the string to add
*
* routine which manage and grows an output buffer . This one add
* C chars at the end of the array .
*/
1998-08-13 07:39:55 +04:00
void xmlBufferWriteChar ( const char * string ) {
const char * cur ;
if ( buffer = = NULL ) {
buffer_size = 50000 ;
buffer = ( CHAR * ) malloc ( buffer_size * sizeof ( CHAR ) ) ;
if ( buffer = = NULL ) {
fprintf ( stderr , " xmlBufferWrite : out of memory! \n " ) ;
exit ( 1 ) ;
}
}
if ( string = = NULL ) return ;
for ( cur = string ; * cur ! = 0 ; cur + + ) {
if ( buffer_index + 10 > = buffer_size ) {
buffer_size * = 2 ;
buffer = ( CHAR * ) realloc ( buffer , buffer_size * sizeof ( CHAR ) ) ;
if ( buffer = = NULL ) {
fprintf ( stderr , " xmlBufferWrite : out of memory! \n " ) ;
exit ( 1 ) ;
}
}
buffer [ buffer_index + + ] = * cur ;
}
buffer [ buffer_index ] = 0 ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlGlobalNsDump :
* @ cur : a namespace
*
* Dump a global Namespace , this is the old version based on PIs .
1998-08-13 07:39:55 +04:00
*/
static void xmlGlobalNsDump ( xmlNsPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlGlobalNsDump : Ns == NULL \n " ) ;
return ;
}
if ( cur - > type = = XML_GLOBAL_NAMESPACE ) {
xmlBufferWriteChar ( " <?namespace " ) ;
if ( cur - > href ! = NULL ) {
xmlBufferWriteChar ( " href= \" " ) ;
xmlBufferWriteCHAR ( cur - > href ) ;
xmlBufferWriteChar ( " \" " ) ;
}
if ( cur - > prefix ! = NULL ) {
xmlBufferWriteChar ( " AS= \" " ) ;
xmlBufferWriteCHAR ( cur - > prefix ) ;
xmlBufferWriteChar ( " \" " ) ;
}
xmlBufferWriteChar ( " ?> \n " ) ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlGlobalNsListDump :
* @ cur : the first namespace
*
* Dump a list of global Namespace , this is the old version based on PIs .
1998-08-13 07:39:55 +04:00
*/
static void xmlGlobalNsListDump ( xmlNsPtr cur ) {
while ( cur ! = NULL ) {
xmlGlobalNsDump ( cur ) ;
cur = cur - > next ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlNsDump :
* @ cur : a namespace
*
1998-08-13 07:39:55 +04:00
* Dump a local Namespace definition .
1998-10-20 10:14:16 +04:00
* Should be called in the context of attributes dumps .
1998-08-13 07:39:55 +04:00
*/
static void xmlNsDump ( xmlNsPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNsDump : Ns == NULL \n " ) ;
return ;
}
if ( cur - > type = = XML_LOCAL_NAMESPACE ) {
/* Within the context of an element attributes */
if ( cur - > prefix ! = NULL ) {
xmlBufferWriteChar ( " xmlns: " ) ;
xmlBufferWriteCHAR ( cur - > prefix ) ;
} else
xmlBufferWriteChar ( " xmlns " ) ;
xmlBufferWriteChar ( " = \" " ) ;
xmlBufferWriteCHAR ( cur - > href ) ;
xmlBufferWriteChar ( " \" " ) ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlNsListDump :
* @ cur : the first namespace
*
* Dump a list of local Namespace definitions .
* Should be called in the context of attributes dumps .
1998-08-13 07:39:55 +04:00
*/
static void xmlNsListDump ( xmlNsPtr cur ) {
while ( cur ! = NULL ) {
xmlNsDump ( cur ) ;
cur = cur - > next ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlDtdDump :
* @ doc : the document
*
* Dump the XML document DTD , if any .
1998-08-13 07:39:55 +04:00
*/
static void xmlDtdDump ( xmlDocPtr doc ) {
xmlDtdPtr cur = doc - > dtd ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlDtdDump : DTD == NULL \n " ) ;
return ;
}
xmlBufferWriteChar ( " <!DOCTYPE " ) ;
xmlBufferWriteCHAR ( cur - > name ) ;
if ( cur - > ExternalID ! = NULL ) {
xmlBufferWriteChar ( " PUBLIC \" " ) ;
xmlBufferWriteCHAR ( cur - > ExternalID ) ;
xmlBufferWriteChar ( " \" \" " ) ;
xmlBufferWriteCHAR ( cur - > SystemID ) ;
xmlBufferWriteChar ( " \" " ) ;
} else if ( cur - > SystemID ! = NULL ) {
xmlBufferWriteChar ( " SYSTEM \" " ) ;
xmlBufferWriteCHAR ( cur - > SystemID ) ;
xmlBufferWriteChar ( " \" " ) ;
}
if ( ( cur - > entities = = NULL ) & & ( doc - > entities = = NULL ) ) {
xmlBufferWriteChar ( " > \n " ) ;
return ;
}
xmlBufferWriteChar ( " [ \n " ) ;
if ( cur - > entities ! = NULL )
xmlDumpEntitiesTable ( ( xmlEntitiesTablePtr ) cur - > entities ) ;
if ( doc - > entities ! = NULL )
xmlDumpEntitiesTable ( ( xmlEntitiesTablePtr ) doc - > entities ) ;
xmlBufferWriteChar ( " ] " ) ;
/* TODO !!! a lot more things to dump ... */
xmlBufferWriteChar ( " > \n " ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlAttrDump :
* @ doc : the document
* @ cur : the attribute pointer
*
* Dump an XML attribute
1998-08-13 07:39:55 +04:00
*/
static void xmlAttrDump ( xmlDocPtr doc , xmlAttrPtr cur ) {
1998-10-27 09:21:04 +03:00
CHAR * value ;
1998-08-13 07:39:55 +04:00
if ( cur = = NULL ) {
fprintf ( stderr , " xmlAttrDump : property == NULL \n " ) ;
return ;
}
xmlBufferWriteChar ( " " ) ;
xmlBufferWriteCHAR ( cur - > name ) ;
1998-10-27 09:21:04 +03:00
value = xmlNodeListGetString ( doc , cur - > val , 0 ) ;
if ( value ) {
1998-08-13 07:39:55 +04:00
xmlBufferWriteChar ( " = \" " ) ;
1998-10-27 09:21:04 +03:00
xmlBufferWriteCHAR ( value ) ;
1998-08-13 07:39:55 +04:00
xmlBufferWriteChar ( " \" " ) ;
1998-10-27 09:21:04 +03:00
free ( value ) ;
1998-08-13 07:39:55 +04:00
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlAttrListDump :
* @ doc : the document
* @ cur : the first attribute pointer
*
* Dump a list of XML attributes
1998-08-13 07:39:55 +04:00
*/
static void xmlAttrListDump ( xmlDocPtr doc , xmlAttrPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlAttrListDump : property == NULL \n " ) ;
return ;
}
while ( cur ! = NULL ) {
xmlAttrDump ( doc , cur ) ;
cur = cur - > next ;
}
}
static void xmlNodeDump ( xmlDocPtr doc , xmlNodePtr cur , int level ) ;
1998-10-20 10:14:16 +04:00
/**
* xmlNodeListDump :
* @ doc : the document
* @ cur : the first node
* @ level : the imbrication level for indenting
*
* Dump an XML node list , recursive behaviour , children are printed too .
*/
1998-08-13 07:39:55 +04:00
static void xmlNodeListDump ( xmlDocPtr doc , xmlNodePtr cur , int level ) {
1998-10-27 09:21:04 +03:00
int needIndent = 0 , i ;
1998-08-13 07:39:55 +04:00
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNodeListDump : node == NULL \n " ) ;
return ;
}
while ( cur ! = NULL ) {
1998-10-27 09:21:04 +03:00
if ( ( cur - > type ! = XML_TEXT_NODE ) & &
( cur - > type ! = XML_ENTITY_REF_NODE ) ) {
if ( ! needIndent ) {
needIndent = 1 ;
xmlBufferWriteChar ( " \n " ) ;
}
}
1998-08-13 07:39:55 +04:00
xmlNodeDump ( doc , cur , level ) ;
cur = cur - > next ;
}
1998-10-27 09:21:04 +03:00
if ( ( xmlIndentTreeOutput ) & & ( needIndent ) )
for ( i = 1 ; i < level ; i + + )
xmlBufferWriteChar ( " " ) ;
1998-08-13 07:39:55 +04:00
}
1998-10-20 10:14:16 +04:00
/**
1998-10-27 09:21:04 +03:00
* xmlNodeDump :
1998-10-20 10:14:16 +04:00
* @ doc : the document
* @ cur : the current node
* @ level : the imbrication level for indenting
*
* Dump an XML node , recursive behaviour , children are printed too .
1998-08-13 07:39:55 +04:00
*/
static void xmlNodeDump ( xmlDocPtr doc , xmlNodePtr cur , int level ) {
int i ;
if ( cur = = NULL ) {
fprintf ( stderr , " xmlNodeDump : node == NULL \n " ) ;
return ;
}
1998-10-14 06:36:47 +04:00
if ( cur - > type = = XML_TEXT_NODE ) {
1998-08-13 07:39:55 +04:00
if ( cur - > content ! = NULL )
xmlBufferWriteCHAR ( xmlEncodeEntities ( doc , cur - > content ) ) ;
return ;
}
1998-10-14 06:36:47 +04:00
if ( cur - > type = = XML_COMMENT_NODE ) {
1998-08-13 07:39:55 +04:00
if ( cur - > content ! = NULL ) {
xmlBufferWriteChar ( " <!-- " ) ;
xmlBufferWriteCHAR ( cur - > content ) ;
xmlBufferWriteChar ( " --> " ) ;
}
return ;
}
1998-10-27 09:21:04 +03:00
if ( cur - > type = = XML_ENTITY_REF_NODE ) {
xmlBufferWriteChar ( " & " ) ;
xmlBufferWriteCHAR ( cur - > name ) ;
xmlBufferWriteChar ( " ; " ) ;
return ;
}
1998-08-13 07:39:55 +04:00
if ( xmlIndentTreeOutput )
for ( i = 0 ; i < level ; i + + )
xmlBufferWriteChar ( " " ) ;
xmlBufferWriteChar ( " < " ) ;
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlBufferWriteCHAR ( cur - > ns - > prefix ) ;
xmlBufferWriteChar ( " : " ) ;
}
xmlBufferWriteCHAR ( cur - > name ) ;
if ( cur - > nsDef )
xmlNsListDump ( cur - > nsDef ) ;
if ( cur - > properties ! = NULL )
xmlAttrListDump ( doc , cur - > properties ) ;
if ( ( cur - > content = = NULL ) & & ( cur - > childs = = NULL ) ) {
xmlBufferWriteChar ( " /> \n " ) ;
return ;
}
xmlBufferWriteChar ( " > " ) ;
if ( cur - > content ! = NULL )
xmlBufferWriteCHAR ( xmlEncodeEntities ( doc , cur - > content ) ) ;
if ( cur - > childs ! = NULL ) {
xmlNodeListDump ( doc , cur - > childs , level + 1 ) ;
}
xmlBufferWriteChar ( " </ " ) ;
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
xmlBufferWriteCHAR ( cur - > ns - > prefix ) ;
xmlBufferWriteChar ( " : " ) ;
}
xmlBufferWriteCHAR ( cur - > name ) ;
xmlBufferWriteChar ( " > \n " ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlDocContentDump :
* @ cur : the document
*
* Dump an XML document .
1998-08-13 07:39:55 +04:00
*/
static void xmlDocContentDump ( xmlDocPtr cur ) {
if ( oldXMLWDcompatibility )
xmlBufferWriteChar ( " <?XML version= \" " ) ;
else
xmlBufferWriteChar ( " <?xml version= \" " ) ;
xmlBufferWriteCHAR ( cur - > version ) ;
xmlBufferWriteChar ( " \" " ) ;
if ( cur - > encoding ! = NULL ) {
xmlBufferWriteChar ( " encoding= \" " ) ;
xmlBufferWriteCHAR ( cur - > encoding ) ;
xmlBufferWriteChar ( " \" " ) ;
}
switch ( cur - > standalone ) {
case 0 :
xmlBufferWriteChar ( " standalone= \" no \" " ) ;
break ;
case 1 :
xmlBufferWriteChar ( " standalone= \" yes \" " ) ;
break ;
}
xmlBufferWriteChar ( " ?> \n " ) ;
if ( ( cur - > dtd ! = NULL ) | | ( cur - > entities ! = NULL ) )
xmlDtdDump ( cur ) ;
if ( cur - > root ! = NULL ) {
/* global namespace definitions, the old way */
if ( oldXMLWDcompatibility )
xmlGlobalNsListDump ( cur - > oldNs ) ;
else
xmlUpgradeOldNs ( cur ) ;
xmlNodeDump ( cur , cur - > root , 0 ) ;
}
}
1998-10-20 10:14:16 +04:00
/**
* xmlDocDumpMemory :
* @ cur : the document
* @ mem : OUT : the memory pointer
* @ size : OUT : the memory lenght
*
* Dump an XML document in memory and return the CHAR * and it ' s size .
* It ' s up to the caller to free the memory .
1998-08-13 07:39:55 +04:00
*/
void xmlDocDumpMemory ( xmlDocPtr cur , CHAR * * mem , int * size ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlDocDump : document == NULL \n " ) ;
* mem = NULL ;
* size = 0 ;
return ;
}
buffer_index = 0 ;
xmlDocContentDump ( cur ) ;
* mem = buffer ;
* size = buffer_index ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlGetDocCompressMode :
* @ doc : the document
*
* get the compression ratio for a document , ZLIB based
* return values : 0 ( uncompressed ) to 9 ( max compression )
1998-09-23 04:49:46 +04:00
*/
1998-09-24 23:15:06 +04:00
int xmlGetDocCompressMode ( xmlDocPtr doc ) {
if ( doc = = NULL ) return ( - 1 ) ;
return ( doc - > compression ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlSetDocCompressMode :
* @ doc : the document
* @ mode : the compression ratio
*
* set the compression ratio for a document , ZLIB based
* Correct values : 0 ( uncompressed ) to 9 ( max compression )
*/
1998-09-24 23:15:06 +04:00
void xmlSetDocCompressMode ( xmlDocPtr doc , int mode ) {
if ( doc = = NULL ) return ;
if ( mode < 0 ) doc - > compression = 0 ;
else if ( mode > 9 ) doc - > compression = 9 ;
else doc - > compression = mode ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlGetCompressMode :
*
* get the default compression mode used , ZLIB based .
* return values : 0 ( uncompressed ) to 9 ( max compression )
1998-09-24 23:15:06 +04:00
*/
1998-09-23 04:49:46 +04:00
int xmlGetCompressMode ( void ) {
return ( xmlCompressMode ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlSetCompressMode :
* @ mode : the compression ratio
*
* set the default compression mode used , ZLIB based
* Correct values : 0 ( uncompressed ) to 9 ( max compression )
*/
1998-09-23 04:49:46 +04:00
void xmlSetCompressMode ( int mode ) {
if ( mode < 0 ) xmlCompressMode = 0 ;
1998-09-24 23:15:06 +04:00
else if ( mode > 9 ) xmlCompressMode = 9 ;
1998-09-23 04:49:46 +04:00
else xmlCompressMode = mode ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlDocDump :
* @ f : the FILE *
* @ cur : the document
*
* Dump an XML document to an open FILE .
1998-08-13 07:39:55 +04:00
*/
void xmlDocDump ( FILE * f , xmlDocPtr cur ) {
if ( cur = = NULL ) {
fprintf ( stderr , " xmlDocDump : document == NULL \n " ) ;
return ;
}
buffer_index = 0 ;
xmlDocContentDump ( cur ) ;
fwrite ( buffer , sizeof ( CHAR ) , buffer_index , f ) ;
}
1998-10-20 10:14:16 +04:00
/**
* xmlSaveFile :
* @ filename : the filename
* @ cur : the document
*
* Dump an XML document to a file . Will use compression if
* compiled in and enabled .
* returns : the number of file written or - 1 in case of failure .
1998-09-23 04:49:46 +04:00
*/
int xmlSaveFile ( const char * filename , xmlDocPtr cur ) {
# ifdef HAVE_ZLIB_H
gzFile zoutput = NULL ;
char mode [ 15 ] ;
# endif
1998-10-27 09:21:04 +03:00
FILE * output = NULL ;
1998-09-23 04:49:46 +04:00
int ret ;
# ifdef HAVE_ZLIB_H
1998-09-24 23:25:54 +04:00
if ( ( cur - > compression > 0 ) & & ( cur - > compression < = 9 ) ) {
sprintf ( mode , " w%d " , cur - > compression ) ;
1998-09-23 04:49:46 +04:00
zoutput = gzopen ( filename , mode ) ;
}
if ( zoutput = = NULL ) {
# endif
output = fopen ( filename , " w " ) ;
if ( output = = NULL ) return ( - 1 ) ;
# ifdef HAVE_ZLIB_H
}
# endif
/*
* save the content to a temp buffer .
*/
buffer_index = 0 ;
xmlDocContentDump ( cur ) ;
# ifdef HAVE_ZLIB_H
if ( zoutput ! = NULL ) {
ret = gzwrite ( zoutput , buffer , sizeof ( CHAR ) * buffer_index ) ;
gzclose ( zoutput ) ;
return ( ret ) ;
}
# endif
ret = fwrite ( buffer , sizeof ( CHAR ) , buffer_index , output ) ;
fclose ( output ) ;
return ( ret * sizeof ( CHAR ) ) ;
}
1998-08-13 07:39:55 +04:00
/************************************************************************
* *
* Debug *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef STANDALONE
int main ( void ) {
xmlDocPtr doc ;
xmlNodePtr tree , subtree ;
xmlNsPtr ns1 ;
xmlNsPtr ns2 ;
/*
* build a fake XML document
*/
doc = xmlNewDoc ( " 1.0 " ) ;
ns1 = xmlNewNs ( doc , " http://www.ietf.org/standards/dav/ " , " D " ) ;
ns2 = xmlNewNs ( doc , " http://www.w3.com/standards/z39.50/ " , " Z " ) ;
1998-10-27 09:21:04 +03:00
doc - > root = xmlNewDocNode ( doc , ns1 , " multistatus " , NULL ) ;
1998-08-13 07:39:55 +04:00
tree = xmlNewChild ( doc - > root , NULL , " response " , NULL ) ;
subtree = xmlNewChild ( tree , NULL , " prop " , NULL ) ;
xmlNewChild ( subtree , ns2 , " Authors " , NULL ) ;
subtree = xmlNewChild ( tree , NULL , " status " , " HTTP/1.1 420 Method Failure " ) ;
tree = xmlNewChild ( doc - > root , NULL , " response " , NULL ) ;
subtree = xmlNewChild ( tree , NULL , " prop " , NULL ) ;
xmlNewChild ( subtree , ns2 , " Copyright-Owner " , NULL ) ;
subtree = xmlNewChild ( tree , NULL , " status " , " HTTP/1.1 409 Conflict " ) ;
tree = xmlNewChild ( doc - > root , NULL , " responsedescription " ,
" Copyright Owner can not be deleted or altered " ) ;
/*
* print it .
*/
xmlDocDump ( stdout , doc ) ;
/*
* free it .
*/
xmlFreeDoc ( doc ) ;
return ( 0 ) ;
}
# endif