2003-08-21 02:54:39 +04:00
/*
* SAX2 . c : Default SAX2 handler to build a tree .
*
* See Copyright for the status of this software .
*
* Daniel Veillard < daniel @ veillard . com >
*/
# define IN_LIBXML
# include "libxml.h"
# include <stdlib.h>
# include <string.h>
2008-11-17 18:59:21 +03:00
# include <limits.h>
2003-08-21 02:54:39 +04:00
# include <libxml/xmlmemory.h>
# include <libxml/tree.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/valid.h>
# include <libxml/entities.h>
# include <libxml/xmlerror.h>
# include <libxml/debugXML.h>
# include <libxml/xmlIO.h>
# include <libxml/SAX.h>
# include <libxml/uri.h>
# include <libxml/valid.h>
# include <libxml/HTMLtree.h>
# include <libxml/globals.h>
2008-11-17 18:59:21 +03:00
/* Define SIZE_T_MAX unless defined through <limits.h>. */
# ifndef SIZE_T_MAX
# define SIZE_T_MAX ((size_t)-1)
# endif /* !SIZE_T_MAX */
2003-08-21 02:54:39 +04:00
/* #define DEBUG_SAX2 */
/* #define DEBUG_SAX2_TREE */
2003-09-10 14:50:59 +04:00
/**
* TODO :
*
* macro to flag unimplemented blocks
* XML_CATALOG_PREFER user env to select between system / public prefered
* option . C . f . Richard Tobin < richard @ cogsci . ed . ac . uk >
* > Just FYI , I am using an environment variable XML_CATALOG_PREFER with
* > values " system " and " public " . I have made the default be " system " to
* > match yours .
*/
# define TODO \
xmlGenericError ( xmlGenericErrorContext , \
" Unimplemented block at %s:%d \n " , \
__FILE__ , __LINE__ ) ;
2004-07-29 11:07:16 +04:00
/*
* xmlSAX2ErrMemory :
* @ ctxt : an XML validation parser context
* @ msg : a string to accompany the error message
*/
static void
2004-07-31 20:24:01 +04:00
xmlSAX2ErrMemory ( xmlParserCtxtPtr ctxt , const char * msg ) {
2012-07-18 12:05:37 +04:00
xmlStructuredErrorFunc schannel = NULL ;
const char * str1 = " out of memory \n " ;
2004-11-04 20:34:35 +03:00
if ( ctxt ! = NULL ) {
2012-07-18 12:05:37 +04:00
ctxt - > errNo = XML_ERR_NO_MEMORY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > initialized = = XML_SAX2_MAGIC ) )
schannel = ctxt - > sax - > serror ;
__xmlRaiseError ( schannel ,
ctxt - > vctxt . error , ctxt - > vctxt . userData ,
ctxt , NULL , XML_FROM_PARSER , XML_ERR_NO_MEMORY ,
XML_ERR_ERROR , NULL , 0 , ( const char * ) str1 ,
NULL , NULL , 0 , 0 ,
msg , ( const char * ) str1 , NULL ) ;
2004-11-04 20:34:35 +03:00
ctxt - > errNo = XML_ERR_NO_MEMORY ;
ctxt - > instate = XML_PARSER_EOF ;
ctxt - > disableSAX = 1 ;
2012-07-18 12:05:37 +04:00
} else {
__xmlRaiseError ( schannel ,
NULL , NULL ,
ctxt , NULL , XML_FROM_PARSER , XML_ERR_NO_MEMORY ,
XML_ERR_ERROR , NULL , 0 , ( const char * ) str1 ,
NULL , NULL , 0 , 0 ,
msg , ( const char * ) str1 , NULL ) ;
2004-11-04 20:34:35 +03:00
}
2004-07-29 11:07:16 +04:00
}
2003-12-08 13:25:02 +03:00
/**
* xmlValidError :
* @ ctxt : an XML validation parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : extra data
* @ str2 : extra data
*
* Handle a validation error
*/
static void
xmlErrValid ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const char * str1 , const char * str2 )
{
xmlStructuredErrorFunc schannel = NULL ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > disableSAX ! = 0 ) & &
( ctxt - > instate = = XML_PARSER_EOF ) )
return ;
2004-11-04 20:34:35 +03:00
if ( ctxt ! = NULL ) {
ctxt - > errNo = error ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > initialized = = XML_SAX2_MAGIC ) )
schannel = ctxt - > sax - > serror ;
2006-03-09 19:49:24 +03:00
__xmlRaiseError ( schannel ,
ctxt - > vctxt . error , ctxt - > vctxt . userData ,
ctxt , NULL , XML_FROM_DTD , error ,
XML_ERR_ERROR , NULL , 0 , ( const char * ) str1 ,
( const char * ) str2 , NULL , 0 , 0 ,
msg , ( const char * ) str1 , ( const char * ) str2 ) ;
2004-11-04 20:34:35 +03:00
ctxt - > valid = 0 ;
2006-03-09 19:49:24 +03:00
} else {
__xmlRaiseError ( schannel ,
NULL , NULL ,
ctxt , NULL , XML_FROM_DTD , error ,
XML_ERR_ERROR , NULL , 0 , ( const char * ) str1 ,
( const char * ) str2 , NULL , 0 , 0 ,
msg , ( const char * ) str1 , ( const char * ) str2 ) ;
}
2003-12-08 13:25:02 +03:00
}
2005-07-05 18:04:36 +04:00
/**
* xmlFatalErrMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
* @ str2 : an error string
*
* Handle a fatal parser error , i . e . violating Well - Formedness constraints
*/
static void
xmlFatalErrMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
if ( ( ctxt ! = NULL ) & & ( ctxt - > disableSAX ! = 0 ) & &
( ctxt - > instate = = XML_PARSER_EOF ) )
return ;
if ( ctxt ! = NULL )
ctxt - > errNo = error ;
__xmlRaiseError ( NULL , NULL , NULL , ctxt , NULL , XML_FROM_PARSER , error ,
XML_ERR_FATAL , NULL , 0 ,
( const char * ) str1 , ( const char * ) str2 ,
NULL , 0 , 0 , msg , str1 , str2 ) ;
if ( ctxt ! = NULL ) {
ctxt - > wellFormed = 0 ;
ctxt - > valid = 0 ;
if ( ctxt - > recovery = = 0 )
ctxt - > disableSAX = 1 ;
}
}
/**
* xmlWarnMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
* @ str2 : an error string
*
* Handle a parser warning
*/
static void
xmlWarnMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 )
{
if ( ( ctxt ! = NULL ) & & ( ctxt - > disableSAX ! = 0 ) & &
( ctxt - > instate = = XML_PARSER_EOF ) )
return ;
if ( ctxt ! = NULL )
ctxt - > errNo = error ;
__xmlRaiseError ( NULL , NULL , NULL , ctxt , NULL , XML_FROM_PARSER , error ,
XML_ERR_WARNING , NULL , 0 ,
( const char * ) str1 , NULL ,
NULL , 0 , 0 , msg , str1 ) ;
}
/**
* xmlNsErrMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
* @ str2 : an error string
*
* Handle a namespace error
*/
static void
xmlNsErrMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
if ( ( ctxt ! = NULL ) & & ( ctxt - > disableSAX ! = 0 ) & &
( ctxt - > instate = = XML_PARSER_EOF ) )
return ;
if ( ctxt ! = NULL )
ctxt - > errNo = error ;
__xmlRaiseError ( NULL , NULL , NULL , ctxt , NULL , XML_FROM_NAMESPACE , error ,
XML_ERR_ERROR , NULL , 0 ,
( const char * ) str1 , ( const char * ) str2 ,
NULL , 0 , 0 , msg , str1 , str2 ) ;
}
/**
* xmlNsWarnMsg :
* @ ctxt : an XML parser context
* @ error : the error number
* @ msg : the error message
* @ str1 : an error string
*
* Handle a namespace warning
*/
static void
xmlNsWarnMsg ( xmlParserCtxtPtr ctxt , xmlParserErrors error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
if ( ( ctxt ! = NULL ) & & ( ctxt - > disableSAX ! = 0 ) & &
( ctxt - > instate = = XML_PARSER_EOF ) )
return ;
if ( ctxt ! = NULL )
ctxt - > errNo = error ;
__xmlRaiseError ( NULL , NULL , NULL , ctxt , NULL , XML_FROM_NAMESPACE , error ,
XML_ERR_WARNING , NULL , 0 ,
( const char * ) str1 , ( const char * ) str2 ,
NULL , 0 , 0 , msg , str1 , str2 ) ;
}
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2GetPublicId :
* @ ctx : the user data ( XML parser context )
*
* Provides the public ID e . g . " -//SGMLSOURCE//DTD DEMO//EN "
*
* Returns a xmlChar *
*/
const xmlChar *
xmlSAX2GetPublicId ( void * ctx ATTRIBUTE_UNUSED )
{
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
return ( NULL ) ;
}
/**
* xmlSAX2GetSystemId :
* @ ctx : the user data ( XML parser context )
*
* Provides the system ID , basically URL or filename e . g .
* http : //www.sgmlsource.com/dtds/memo.dtd
*
* Returns a xmlChar *
*/
const xmlChar *
xmlSAX2GetSystemId ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2005-07-29 03:49:35 +04:00
if ( ( ctx = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
return ( ( const xmlChar * ) ctxt - > input - > filename ) ;
}
/**
* xmlSAX2GetLineNumber :
* @ ctx : the user data ( XML parser context )
*
* Provide the line number of the current parsing point .
*
* Returns an int
*/
int
xmlSAX2GetLineNumber ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ( ctx = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > input - > line ) ;
}
/**
* xmlSAX2GetColumnNumber :
* @ ctx : the user data ( XML parser context )
*
* Provide the column number of the current parsing point .
*
* Returns an int
*/
int
xmlSAX2GetColumnNumber ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ( ctx = = NULL ) | | ( ctxt - > input = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > input - > col ) ;
}
/**
* xmlSAX2IsStandalone :
* @ ctx : the user data ( XML parser context )
*
* Is this document tagged standalone ?
*
* Returns 1 if true
*/
int
xmlSAX2IsStandalone ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ( ctx = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > myDoc - > standalone = = 1 ) ;
}
/**
* xmlSAX2HasInternalSubset :
* @ ctx : the user data ( XML parser context )
*
* Does this document has an internal subset
*
* Returns 1 if true
*/
int
xmlSAX2HasInternalSubset ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-08 17:02:18 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > myDoc - > intSubset ! = NULL ) ;
}
/**
* xmlSAX2HasExternalSubset :
* @ ctx : the user data ( XML parser context )
*
* Does this document has an external subset
*
* Returns 1 if true
*/
int
xmlSAX2HasExternalSubset ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-08 17:02:18 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ( 0 ) ;
2003-08-21 02:54:39 +04:00
return ( ctxt - > myDoc - > extSubset ! = NULL ) ;
}
/**
* xmlSAX2InternalSubset :
* @ ctx : the user data ( XML parser context )
* @ name : the root element name
* @ ExternalID : the external ID
* @ SystemID : the SYSTEM ID ( e . g . filename or URL )
*
* Callback on internal subset declaration .
*/
void
xmlSAX2InternalSubset ( void * ctx , const xmlChar * name ,
const xmlChar * ExternalID , const xmlChar * SystemID )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlDtdPtr dtd ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2InternalSubset(%s, %s, %s) \n " ,
name , ExternalID , SystemID ) ;
# endif
if ( ctxt - > myDoc = = NULL )
return ;
dtd = xmlGetIntSubset ( ctxt - > myDoc ) ;
if ( dtd ! = NULL ) {
if ( ctxt - > html )
return ;
xmlUnlinkNode ( ( xmlNodePtr ) dtd ) ;
xmlFreeDtd ( dtd ) ;
ctxt - > myDoc - > intSubset = NULL ;
}
ctxt - > myDoc - > intSubset =
xmlCreateIntSubset ( ctxt - > myDoc , name , ExternalID , SystemID ) ;
2004-07-29 11:07:16 +04:00
if ( ctxt - > myDoc - > intSubset = = NULL )
xmlSAX2ErrMemory ( ctxt , " xmlSAX2InternalSubset " ) ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2ExternalSubset :
* @ ctx : the user data ( XML parser context )
* @ name : the root element name
* @ ExternalID : the external ID
* @ SystemID : the SYSTEM ID ( e . g . filename or URL )
*
* Callback on external subset declaration .
*/
void
xmlSAX2ExternalSubset ( void * ctx , const xmlChar * name ,
const xmlChar * ExternalID , const xmlChar * SystemID )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2ExternalSubset(%s, %s, %s) \n " ,
name , ExternalID , SystemID ) ;
# endif
if ( ( ( ExternalID ! = NULL ) | | ( SystemID ! = NULL ) ) & &
( ( ( ctxt - > validate ) | | ( ctxt - > loadsubset ! = 0 ) ) & &
( ctxt - > wellFormed & & ctxt - > myDoc ) ) ) {
/*
* Try to fetch and parse the external subset .
*/
xmlParserInputPtr oldinput ;
int oldinputNr ;
int oldinputMax ;
xmlParserInputPtr * oldinputTab ;
xmlParserInputPtr input = NULL ;
xmlCharEncoding enc ;
int oldcharset ;
/*
* Ask the Entity resolver to load the damn thing
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > resolveEntity ! = NULL ) )
input = ctxt - > sax - > resolveEntity ( ctxt - > userData , ExternalID ,
SystemID ) ;
if ( input = = NULL ) {
return ;
}
xmlNewDtd ( ctxt - > myDoc , name , ExternalID , SystemID ) ;
/*
* make sure we won ' t destroy the main document context
*/
oldinput = ctxt - > input ;
oldinputNr = ctxt - > inputNr ;
oldinputMax = ctxt - > inputMax ;
oldinputTab = ctxt - > inputTab ;
oldcharset = ctxt - > charset ;
ctxt - > inputTab = ( xmlParserInputPtr * )
xmlMalloc ( 5 * sizeof ( xmlParserInputPtr ) ) ;
if ( ctxt - > inputTab = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2ExternalSubset " ) ;
2003-08-21 02:54:39 +04:00
ctxt - > input = oldinput ;
ctxt - > inputNr = oldinputNr ;
ctxt - > inputMax = oldinputMax ;
ctxt - > inputTab = oldinputTab ;
ctxt - > charset = oldcharset ;
return ;
}
ctxt - > inputNr = 0 ;
ctxt - > inputMax = 5 ;
ctxt - > input = NULL ;
xmlPushInput ( ctxt , input ) ;
/*
* On the fly encoding conversion if needed
*/
if ( ctxt - > input - > length > = 4 ) {
enc = xmlDetectCharEncoding ( ctxt - > input - > cur , 4 ) ;
xmlSwitchEncoding ( ctxt , enc ) ;
}
if ( input - > filename = = NULL )
input - > filename = ( char * ) xmlCanonicPath ( SystemID ) ;
input - > line = 1 ;
input - > col = 1 ;
input - > base = ctxt - > input - > cur ;
input - > cur = ctxt - > input - > cur ;
input - > free = NULL ;
/*
* let ' s parse that entity knowing it ' s an external subset .
*/
xmlParseExternalSubset ( ctxt , ExternalID , SystemID ) ;
/*
* Free up the external entities
*/
while ( ctxt - > inputNr > 1 )
xmlPopInput ( ctxt ) ;
xmlFreeInputStream ( ctxt - > input ) ;
xmlFree ( ctxt - > inputTab ) ;
/*
* Restore the parsing context of the main entity
*/
ctxt - > input = oldinput ;
ctxt - > inputNr = oldinputNr ;
ctxt - > inputMax = oldinputMax ;
ctxt - > inputTab = oldinputTab ;
ctxt - > charset = oldcharset ;
/* ctxt->wellFormed = oldwellFormed; */
}
}
/**
* xmlSAX2ResolveEntity :
* @ ctx : the user data ( XML parser context )
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
* The entity loader , to control the loading of external entities ,
* the application can either :
* - override this xmlSAX2ResolveEntity ( ) callback in the SAX block
* - or better use the xmlSetExternalEntityLoader ( ) function to
* set up it ' s own entity resolution routine
*
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour .
*/
xmlParserInputPtr
xmlSAX2ResolveEntity ( void * ctx , const xmlChar * publicId , const xmlChar * systemId )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserInputPtr ret ;
xmlChar * URI ;
const char * base = NULL ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2ResolveEntity(%s, %s) \n " , publicId , systemId ) ;
# endif
ret = xmlLoadExternalEntity ( ( const char * ) URI ,
( const char * ) publicId , ctxt ) ;
if ( URI ! = NULL )
xmlFree ( URI ) ;
return ( ret ) ;
}
/**
* xmlSAX2GetEntity :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
* Get an entity by name
*
* Returns the xmlEntityPtr if found .
*/
xmlEntityPtr
xmlSAX2GetEntity ( void * ctx , const xmlChar * name )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlEntityPtr ret = NULL ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2GetEntity(%s) \n " , name ) ;
# endif
if ( ctxt - > inSubset = = 0 ) {
ret = xmlGetPredefinedEntity ( name ) ;
if ( ret ! = NULL )
return ( ret ) ;
}
if ( ( ctxt - > myDoc ! = NULL ) & & ( ctxt - > myDoc - > standalone = = 1 ) ) {
if ( ctxt - > inSubset = = 2 ) {
ctxt - > myDoc - > standalone = 0 ;
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
ctxt - > myDoc - > standalone = 1 ;
} else {
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
if ( ret = = NULL ) {
ctxt - > myDoc - > standalone = 0 ;
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
if ( ret ! = NULL ) {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_NOT_STANDALONE ,
" Entity(%s) document marked standalone but requires external subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
}
ctxt - > myDoc - > standalone = 1 ;
}
}
} else {
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
}
if ( ( ret ! = NULL ) & &
( ( ctxt - > validate ) | | ( ctxt - > replaceEntities ) ) & &
( ret - > children = = NULL ) & &
( ret - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY ) ) {
int val ;
/*
* for validation purposes we really need to fetch and
* parse the external entity
*/
xmlNodePtr children ;
val = xmlParseCtxtExternalEntity ( ctxt , ret - > URI ,
ret - > ExternalID , & children ) ;
if ( val = = 0 ) {
xmlAddChildList ( ( xmlNodePtr ) ret , children ) ;
} else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_ENTITY_PROCESSING ,
" Failure to process entity %s \n " , name , NULL ) ;
2003-08-21 02:54:39 +04:00
ctxt - > validate = 0 ;
return ( NULL ) ;
}
ret - > owner = 1 ;
2008-08-25 12:57:48 +04:00
if ( ret - > checked = = 0 )
ret - > checked = 1 ;
2003-08-21 02:54:39 +04:00
}
return ( ret ) ;
}
/**
* xmlSAX2GetParameterEntity :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
* Get a parameter entity by name
*
* Returns the xmlEntityPtr if found .
*/
xmlEntityPtr
xmlSAX2GetParameterEntity ( void * ctx , const xmlChar * name )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlEntityPtr ret ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ( NULL ) ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2GetParameterEntity(%s) \n " , name ) ;
# endif
ret = xmlGetParameterEntity ( ctxt - > myDoc , name ) ;
return ( ret ) ;
}
/**
* xmlSAX2EntityDecl :
* @ ctx : the user data ( XML parser context )
* @ name : the entity name
* @ type : the entity type
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
* @ content : the entity value ( without processing ) .
*
* An entity definition has been parsed
*/
void
xmlSAX2EntityDecl ( void * ctx , const xmlChar * name , int type ,
const xmlChar * publicId , const xmlChar * systemId , xmlChar * content )
{
xmlEntityPtr ent ;
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2EntityDecl(%s, %d, %s, %s, %s) \n " ,
name , type , publicId , systemId , content ) ;
# endif
if ( ctxt - > inSubset = = 1 ) {
ent = xmlAddDocEntity ( ctxt - > myDoc , name , type , publicId ,
systemId , content ) ;
2005-07-05 18:04:36 +04:00
if ( ( ent = = NULL ) & & ( ctxt - > pedantic ) )
xmlWarnMsg ( ctxt , XML_WAR_ENTITY_REDEFINED ,
" Entity(%s) already defined in the internal subset \n " ,
name ) ;
2003-08-21 02:54:39 +04:00
if ( ( ent ! = NULL ) & & ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
xmlChar * URI ;
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
ent - > URI = URI ;
}
} else if ( ctxt - > inSubset = = 2 ) {
ent = xmlAddDtdEntity ( ctxt - > myDoc , name , type , publicId ,
systemId , content ) ;
if ( ( ent = = NULL ) & & ( ctxt - > pedantic ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
2003-09-06 22:02:53 +04:00
ctxt - > sax - > warning ( ctxt - > userData ,
2003-08-21 02:54:39 +04:00
" Entity(%s) already defined in the external subset \n " , name ) ;
if ( ( ent ! = NULL ) & & ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
xmlChar * URI ;
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
ent - > URI = URI ;
}
} else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_ENTITY_PROCESSING ,
" SAX.xmlSAX2EntityDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
}
}
/**
* xmlSAX2AttributeDecl :
* @ ctx : the user data ( XML parser context )
* @ elem : the name of the element
* @ fullname : the attribute name
* @ type : the attribute type
* @ def : the type of default value
* @ defaultValue : the attribute default value
* @ tree : the tree of enumerated value set
*
* An attribute definition has been parsed
*/
void
xmlSAX2AttributeDecl ( void * ctx , const xmlChar * elem , const xmlChar * fullname ,
int type , int def , const xmlChar * defaultValue ,
xmlEnumerationPtr tree )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlAttributePtr attr ;
xmlChar * name = NULL , * prefix = NULL ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...) \n " ,
elem , fullname , type , def , defaultValue ) ;
# endif
2004-04-19 00:55:39 +04:00
if ( ( xmlStrEqual ( fullname , BAD_CAST " xml:id " ) ) & &
( type ! = XML_ATTRIBUTE_ID ) ) {
/*
* Raise the error but keep the validity flag
*/
int tmp = ctxt - > valid ;
xmlErrValid ( ctxt , XML_DTD_XMLID_TYPE ,
" xml:id : attribute type should be ID \n " , NULL , NULL ) ;
ctxt - > valid = tmp ;
}
2003-09-10 14:50:59 +04:00
/* TODO: optimize name/prefix allocation */
2003-08-21 02:54:39 +04:00
name = xmlSplitQName ( ctxt , fullname , & prefix ) ;
ctxt - > vctxt . valid = 1 ;
if ( ctxt - > inSubset = = 1 )
attr = xmlAddAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , elem ,
name , prefix , ( xmlAttributeType ) type ,
( xmlAttributeDefault ) def , defaultValue , tree ) ;
else if ( ctxt - > inSubset = = 2 )
attr = xmlAddAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset , elem ,
name , prefix , ( xmlAttributeType ) type ,
( xmlAttributeDefault ) def , defaultValue , tree ) ;
else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_INTERNAL_ERROR ,
" SAX.xmlSAX2AttributeDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-09-10 14:50:59 +04:00
xmlFreeEnumeration ( tree ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ctxt - > vctxt . valid = = 0 )
ctxt - > valid = 0 ;
if ( ( attr ! = NULL ) & & ( ctxt - > validate ) & & ( ctxt - > wellFormed ) & &
2006-03-09 19:49:24 +03:00
( ctxt - > myDoc - > intSubset ! = NULL ) )
2003-08-21 02:54:39 +04:00
ctxt - > valid & = xmlValidateAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc ,
attr ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
if ( name ! = NULL )
xmlFree ( name ) ;
}
/**
* xmlSAX2ElementDecl :
* @ ctx : the user data ( XML parser context )
* @ name : the element name
* @ type : the element type
* @ content : the element value tree
*
* An element definition has been parsed
*/
void
xmlSAX2ElementDecl ( void * ctx , const xmlChar * name , int type ,
xmlElementContentPtr content )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlElementPtr elem = NULL ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2ElementDecl(%s, %d, ...) \n " , name , type ) ;
# endif
if ( ctxt - > inSubset = = 1 )
elem = xmlAddElementDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset ,
name , ( xmlElementTypeVal ) type , content ) ;
else if ( ctxt - > inSubset = = 2 )
elem = xmlAddElementDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset ,
name , ( xmlElementTypeVal ) type , content ) ;
else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_INTERNAL_ERROR ,
" SAX.xmlSAX2ElementDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( elem = = NULL )
ctxt - > valid = 0 ;
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & =
xmlValidateElementDecl ( & ctxt - > vctxt , ctxt - > myDoc , elem ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2NotationDecl :
* @ ctx : the user data ( XML parser context )
* @ name : The name of the notation
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
* What to do when a notation declaration has been parsed .
*/
void
xmlSAX2NotationDecl ( void * ctx , const xmlChar * name ,
const xmlChar * publicId , const xmlChar * systemId )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNotationPtr nota = NULL ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt = = NULL ) | | ( ctxt - > myDoc = = NULL ) )
return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2NotationDecl(%s, %s, %s) \n " , name , publicId , systemId ) ;
# endif
if ( ( publicId = = NULL ) & & ( systemId = = NULL ) ) {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_NOTATION_PROCESSING ,
" SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
return ;
} else if ( ctxt - > inSubset = = 1 )
nota = xmlAddNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , name ,
publicId , systemId ) ;
else if ( ctxt - > inSubset = = 2 )
nota = xmlAddNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset , name ,
publicId , systemId ) ;
else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_NOTATION_PROCESSING ,
" SAX.xmlSAX2NotationDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( nota = = NULL ) ctxt - > valid = 0 ;
2006-03-09 19:49:24 +03:00
if ( ( ctxt - > validate ) & & ( ctxt - > wellFormed ) & &
( ctxt - > myDoc - > intSubset ! = NULL ) )
2003-08-21 02:54:39 +04:00
ctxt - > valid & = xmlValidateNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc ,
nota ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2UnparsedEntityDecl :
* @ ctx : the user data ( XML parser context )
* @ name : The name of the entity
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
* @ notationName : the name of the notation
*
* What to do when an unparsed entity declaration is parsed
*/
void
xmlSAX2UnparsedEntityDecl ( void * ctx , const xmlChar * name ,
const xmlChar * publicId , const xmlChar * systemId ,
const xmlChar * notationName )
{
xmlEntityPtr ent ;
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s) \n " ,
name , publicId , systemId , notationName ) ;
# endif
if ( ctxt - > inSubset = = 1 ) {
ent = xmlAddDocEntity ( ctxt - > myDoc , name ,
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ,
publicId , systemId , notationName ) ;
if ( ( ent = = NULL ) & & ( ctxt - > pedantic ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
2003-09-06 22:02:53 +04:00
ctxt - > sax - > warning ( ctxt - > userData ,
2003-08-21 02:54:39 +04:00
" Entity(%s) already defined in the internal subset \n " , name ) ;
if ( ( ent ! = NULL ) & & ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
xmlChar * URI ;
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
ent - > URI = URI ;
}
} else if ( ctxt - > inSubset = = 2 ) {
ent = xmlAddDtdEntity ( ctxt - > myDoc , name ,
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ,
publicId , systemId , notationName ) ;
if ( ( ent = = NULL ) & & ( ctxt - > pedantic ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
2003-09-06 22:02:53 +04:00
ctxt - > sax - > warning ( ctxt - > userData ,
2003-08-21 02:54:39 +04:00
" Entity(%s) already defined in the external subset \n " , name ) ;
if ( ( ent ! = NULL ) & & ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
xmlChar * URI ;
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
ent - > URI = URI ;
}
} else {
2005-07-05 18:04:36 +04:00
xmlFatalErrMsg ( ctxt , XML_ERR_INTERNAL_ERROR ,
" SAX.xmlSAX2UnparsedEntityDecl(%s) called while not in subset \n " ,
name , NULL ) ;
2003-08-21 02:54:39 +04:00
}
}
/**
* xmlSAX2SetDocumentLocator :
* @ ctx : the user data ( XML parser context )
* @ loc : A SAX Locator
*
* Receive the document locator at startup , actually xmlDefaultSAXLocator
* Everything is available on the context , so this is useless in our case .
*/
void
xmlSAX2SetDocumentLocator ( void * ctx ATTRIBUTE_UNUSED , xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED )
{
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2SetDocumentLocator() \n " ) ;
# endif
}
/**
* xmlSAX2StartDocument :
* @ ctx : the user data ( XML parser context )
*
* called when the document start being processed .
*/
void
xmlSAX2StartDocument ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlDocPtr doc ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2StartDocument() \n " ) ;
# endif
if ( ctxt - > html ) {
# ifdef LIBXML_HTML_ENABLED
if ( ctxt - > myDoc = = NULL )
ctxt - > myDoc = htmlNewDocNoDtD ( NULL , NULL ) ;
2008-07-31 23:54:59 +04:00
ctxt - > myDoc - > properties = XML_DOC_HTML ;
ctxt - > myDoc - > parseFlags = ctxt - > options ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > myDoc = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartDocument " ) ;
2003-08-21 02:54:39 +04:00
return ;
}
# else
xmlGenericError ( xmlGenericErrorContext ,
" libxml2 built without HTML support \n " ) ;
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
ctxt - > instate = XML_PARSER_EOF ;
ctxt - > disableSAX = 1 ;
return ;
# endif
} else {
doc = ctxt - > myDoc = xmlNewDoc ( ctxt - > version ) ;
if ( doc ! = NULL ) {
2008-07-31 23:54:59 +04:00
doc - > properties = 0 ;
if ( ctxt - > options & XML_PARSE_OLD10 )
doc - > properties | = XML_DOC_OLD10 ;
doc - > parseFlags = ctxt - > options ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > encoding ! = NULL )
doc - > encoding = xmlStrdup ( ctxt - > encoding ) ;
else
doc - > encoding = NULL ;
doc - > standalone = ctxt - > standalone ;
} else {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartDocument " ) ;
2003-08-21 02:54:39 +04:00
return ;
}
2004-03-22 18:22:58 +03:00
if ( ( ctxt - > dictNames ) & & ( doc ! = NULL ) ) {
2003-09-25 01:23:56 +04:00
doc - > dict = ctxt - > dict ;
2004-03-22 18:22:58 +03:00
xmlDictReference ( doc - > dict ) ;
}
2003-08-21 02:54:39 +04:00
}
if ( ( ctxt - > myDoc ! = NULL ) & & ( ctxt - > myDoc - > URL = = NULL ) & &
( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ! = NULL ) ) {
2006-10-10 16:37:14 +04:00
ctxt - > myDoc - > URL = xmlPathToURI ( ( const xmlChar * ) ctxt - > input - > filename ) ;
2003-08-21 02:54:39 +04:00
if ( ctxt - > myDoc - > URL = = NULL )
2004-07-31 20:24:01 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartDocument " ) ;
2003-08-21 02:54:39 +04:00
}
}
/**
* xmlSAX2EndDocument :
* @ ctx : the user data ( XML parser context )
*
* called when the document end has been detected .
*/
void
xmlSAX2EndDocument ( void * ctx )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2EndDocument() \n " ) ;
# endif
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateDocumentFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
/*
* Grab the encoding if it was added on - the - fly
*/
if ( ( ctxt - > encoding ! = NULL ) & & ( ctxt - > myDoc ! = NULL ) & &
( ctxt - > myDoc - > encoding = = NULL ) ) {
ctxt - > myDoc - > encoding = ctxt - > encoding ;
ctxt - > encoding = NULL ;
}
2004-11-02 17:52:23 +03:00
if ( ( ctxt - > inputTab ! = NULL ) & &
( ctxt - > inputNr > 0 ) & & ( ctxt - > inputTab [ 0 ] ! = NULL ) & &
( ctxt - > inputTab [ 0 ] - > encoding ! = NULL ) & & ( ctxt - > myDoc ! = NULL ) & &
2003-08-21 02:54:39 +04:00
( ctxt - > myDoc - > encoding = = NULL ) ) {
ctxt - > myDoc - > encoding = xmlStrdup ( ctxt - > inputTab [ 0 ] - > encoding ) ;
}
if ( ( ctxt - > charset ! = XML_CHAR_ENCODING_NONE ) & & ( ctxt - > myDoc ! = NULL ) & &
( ctxt - > myDoc - > charset = = XML_CHAR_ENCODING_NONE ) ) {
ctxt - > myDoc - > charset = ctxt - > charset ;
}
}
2005-08-24 02:14:02 +04:00
# if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2AttributeInternal :
* @ ctx : the user data ( XML parser context )
* @ fullname : The attribute name , including namespace prefix
* @ value : The attribute value
* @ prefix : the prefix on the element node
*
* Handle an attribute that has been read by the parser .
* The default handling is to convert the attribute into an
* DOM subtree and past it in a new xmlAttr element added to
* the element .
*/
static void
xmlSAX2AttributeInternal ( void * ctx , const xmlChar * fullname ,
2003-09-29 17:20:24 +04:00
const xmlChar * value , const xmlChar * prefix ATTRIBUTE_UNUSED )
2003-08-21 02:54:39 +04:00
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlAttrPtr ret ;
xmlChar * name ;
xmlChar * ns ;
xmlChar * nval ;
xmlNsPtr namespace ;
2007-06-12 19:15:52 +04:00
if ( ctxt - > html ) {
2003-08-21 02:54:39 +04:00
name = xmlStrdup ( fullname ) ;
2007-06-12 19:15:52 +04:00
ns = NULL ;
namespace = NULL ;
} else {
/*
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName ( ctxt , fullname , & ns ) ;
if ( ( name ! = NULL ) & & ( name [ 0 ] = = 0 ) ) {
if ( xmlStrEqual ( ns , BAD_CAST " xmlns " ) ) {
xmlNsErrMsg ( ctxt , XML_ERR_NS_DECL_ERROR ,
" invalid namespace declaration '%s' \n " ,
fullname , NULL ) ;
} else {
xmlNsWarnMsg ( ctxt , XML_WAR_NS_COLUMN ,
" Avoid attribute ending with ':' like '%s' \n " ,
fullname , NULL ) ;
}
if ( ns ! = NULL )
xmlFree ( ns ) ;
ns = NULL ;
xmlFree ( name ) ;
name = xmlStrdup ( fullname ) ;
}
2003-08-21 02:54:39 +04:00
}
if ( name = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElement " ) ;
2003-08-21 02:54:39 +04:00
if ( ns ! = NULL )
xmlFree ( ns ) ;
return ;
}
2010-03-15 17:47:50 +03:00
# ifdef LIBXML_HTML_ENABLED
if ( ( ctxt - > html ) & &
( value = = NULL ) & & ( htmlIsBooleanAttr ( fullname ) ) ) {
2010-03-15 18:08:44 +03:00
nval = xmlStrdup ( fullname ) ;
value = ( const xmlChar * ) nval ;
2010-03-15 17:47:50 +03:00
} else
# endif
{
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2010-03-15 17:47:50 +03:00
/*
* Do the last stage of the attribute normalization
* Needed for HTML too :
* http : //www.w3.org/TR/html4/types.html#h-6.2
*/
ctxt - > vctxt . valid = 1 ;
nval = xmlValidCtxtNormalizeAttributeValue ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node ,
fullname , value ) ;
if ( ctxt - > vctxt . valid ! = 1 ) {
ctxt - > valid = 0 ;
}
if ( nval ! = NULL )
value = nval ;
2003-09-28 22:58:27 +04:00
# else
2010-03-15 17:47:50 +03:00
nval = NULL ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2010-03-15 17:47:50 +03:00
}
2003-08-21 02:54:39 +04:00
/*
* Check whether it ' s a namespace definition
*/
if ( ( ! ctxt - > html ) & & ( ns = = NULL ) & &
( name [ 0 ] = = ' x ' ) & & ( name [ 1 ] = = ' m ' ) & & ( name [ 2 ] = = ' l ' ) & &
( name [ 3 ] = = ' n ' ) & & ( name [ 4 ] = = ' s ' ) & & ( name [ 5 ] = = 0 ) ) {
xmlNsPtr nsret ;
xmlChar * val ;
if ( ! ctxt - > replaceEntities ) {
ctxt - > depth + + ;
val = xmlStringDecodeEntities ( ctxt , value , XML_SUBSTITUTE_REF ,
0 , 0 , 0 ) ;
ctxt - > depth - - ;
} else {
val = ( xmlChar * ) value ;
}
if ( val [ 0 ] ! = 0 ) {
xmlURIPtr uri ;
uri = xmlParseURI ( ( const char * ) val ) ;
if ( uri = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
2003-09-06 22:02:53 +04:00
" xmlns: %s not a valid URI \n " , val ) ;
2003-08-21 02:54:39 +04:00
} else {
if ( uri - > scheme = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" xmlns: URI %s is not absolute \n " , val ) ;
}
xmlFreeURI ( uri ) ;
}
}
/* a default namespace definition */
nsret = xmlNewNs ( ctxt - > node , val , NULL ) ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
/*
* Validate also for namespace decls , they are attributes from
* an XML - 1.0 perspective
*/
if ( nsret ! = NULL & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneNamespace ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , prefix , nsret , val ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
if ( name ! = NULL )
xmlFree ( name ) ;
if ( nval ! = NULL )
xmlFree ( nval ) ;
if ( val ! = value )
xmlFree ( val ) ;
return ;
}
if ( ( ! ctxt - > html ) & &
( ns ! = NULL ) & & ( ns [ 0 ] = = ' x ' ) & & ( ns [ 1 ] = = ' m ' ) & & ( ns [ 2 ] = = ' l ' ) & &
( ns [ 3 ] = = ' n ' ) & & ( ns [ 4 ] = = ' s ' ) & & ( ns [ 5 ] = = 0 ) ) {
xmlNsPtr nsret ;
xmlChar * val ;
if ( ! ctxt - > replaceEntities ) {
ctxt - > depth + + ;
val = xmlStringDecodeEntities ( ctxt , value , XML_SUBSTITUTE_REF ,
0 , 0 , 0 ) ;
ctxt - > depth - - ;
if ( val = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElement " ) ;
2003-08-21 02:54:39 +04:00
xmlFree ( ns ) ;
if ( name ! = NULL )
xmlFree ( name ) ;
return ;
}
} else {
val = ( xmlChar * ) value ;
}
if ( val [ 0 ] = = 0 ) {
2005-07-05 18:04:36 +04:00
xmlNsErrMsg ( ctxt , XML_NS_ERR_EMPTY ,
" Empty namespace name for prefix %s \n " , name , NULL ) ;
2003-08-21 02:54:39 +04:00
}
if ( ( ctxt - > pedantic ! = 0 ) & & ( val [ 0 ] ! = 0 ) ) {
xmlURIPtr uri ;
uri = xmlParseURI ( ( const char * ) val ) ;
if ( uri = = NULL ) {
2005-07-05 18:04:36 +04:00
xmlNsWarnMsg ( ctxt , XML_WAR_NS_URI ,
2003-08-21 02:54:39 +04:00
" xmlns:%s: %s not a valid URI \n " , name , value ) ;
} else {
if ( uri - > scheme = = NULL ) {
2005-07-05 18:04:36 +04:00
xmlNsWarnMsg ( ctxt , XML_WAR_NS_URI_RELATIVE ,
2003-08-21 02:54:39 +04:00
" xmlns:%s: URI %s is not absolute \n " , name , value ) ;
}
xmlFreeURI ( uri ) ;
}
}
/* a standard namespace definition */
nsret = xmlNewNs ( ctxt - > node , val , name ) ;
xmlFree ( ns ) ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
/*
* Validate also for namespace decls , they are attributes from
* an XML - 1.0 perspective
*/
if ( nsret ! = NULL & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneNamespace ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , prefix , nsret , value ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
if ( name ! = NULL )
xmlFree ( name ) ;
if ( nval ! = NULL )
xmlFree ( nval ) ;
if ( val ! = value )
xmlFree ( val ) ;
return ;
}
if ( ns ! = NULL ) {
namespace = xmlSearchNs ( ctxt - > myDoc , ctxt - > node , ns ) ;
2009-09-07 14:15:08 +04:00
2003-08-29 01:13:25 +04:00
if ( namespace = = NULL ) {
2005-07-05 18:04:36 +04:00
xmlNsErrMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
2003-09-06 22:02:53 +04:00
" Namespace prefix %s of attribute %s is not defined \n " ,
2003-08-29 01:13:25 +04:00
ns , name ) ;
2009-09-07 14:15:08 +04:00
} else {
xmlAttrPtr prop ;
prop = ctxt - > node - > properties ;
while ( prop ! = NULL ) {
if ( prop - > ns ! = NULL ) {
if ( ( xmlStrEqual ( name , prop - > name ) ) & &
( ( namespace = = prop - > ns ) | |
( xmlStrEqual ( namespace - > href , prop - > ns - > href ) ) ) ) {
xmlNsErrMsg ( ctxt , XML_ERR_ATTRIBUTE_REDEFINED ,
" Attribute %s in %s redefined \n " ,
name , namespace - > href ) ;
ctxt - > wellFormed = 0 ;
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
goto error ;
}
}
prop = prop - > next ;
}
}
2003-08-21 02:54:39 +04:00
} else {
namespace = NULL ;
}
/* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
ret = xmlNewNsPropEatName ( ctxt - > node , namespace , name , NULL ) ;
if ( ret ! = NULL ) {
if ( ( ctxt - > replaceEntities = = 0 ) & & ( ! ctxt - > html ) ) {
xmlNodePtr tmp ;
ret - > children = xmlStringGetNodeList ( ctxt - > myDoc , value ) ;
tmp = ret - > children ;
while ( tmp ! = NULL ) {
tmp - > parent = ( xmlNodePtr ) ret ;
if ( tmp - > next = = NULL )
ret - > last = tmp ;
tmp = tmp - > next ;
}
} else if ( value ! = NULL ) {
ret - > children = xmlNewDocText ( ctxt - > myDoc , value ) ;
ret - > last = ret - > children ;
if ( ret - > children ! = NULL )
ret - > children - > parent = ( xmlNodePtr ) ret ;
}
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
/*
* If we don ' t substitute entities , the validation should be
* done on a value with replaced entities anyway .
*/
if ( ! ctxt - > replaceEntities ) {
xmlChar * val ;
ctxt - > depth + + ;
val = xmlStringDecodeEntities ( ctxt , value , XML_SUBSTITUTE_REF ,
0 , 0 , 0 ) ;
ctxt - > depth - - ;
if ( val = = NULL )
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , value ) ;
else {
xmlChar * nvalnorm ;
/*
* Do the last stage of the attribute normalization
* It need to be done twice . . . it ' s an extra burden related
* to the ability to keep xmlSAX2References in attributes
*/
nvalnorm = xmlValidNormalizeAttributeValue ( ctxt - > myDoc ,
ctxt - > node , fullname , val ) ;
if ( nvalnorm ! = NULL ) {
xmlFree ( val ) ;
val = nvalnorm ;
}
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , val ) ;
xmlFree ( val ) ;
}
} else {
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , ret , value ) ;
}
2003-09-28 22:58:27 +04:00
} else
# endif /* LIBXML_VALID_ENABLED */
if ( ( ( ctxt - > loadsubset & XML_SKIP_IDS ) = = 0 ) & &
2003-08-21 02:54:39 +04:00
( ( ( ctxt - > replaceEntities = = 0 ) & & ( ctxt - > external ! = 2 ) ) | |
( ( ctxt - > replaceEntities ! = 0 ) & & ( ctxt - > inSubset = = 0 ) ) ) ) {
/*
* when validating , the ID registration is done at the attribute
* validation level . Otherwise we have to do specific handling here .
*/
2005-09-03 17:28:24 +04:00
if ( xmlStrEqual ( fullname , BAD_CAST " xml:id " ) ) {
2004-04-10 01:51:49 +04:00
/*
* Add the xml : id value
*
* Open issue : normalization of the value .
*/
2004-04-19 00:55:39 +04:00
if ( xmlValidateNCName ( value , 1 ) ! = 0 ) {
xmlErrValid ( ctxt , XML_DTD_XMLID_VALUE ,
" xml:id : attribute value %s is not an NCName \n " ,
( const char * ) value , NULL ) ;
}
2004-04-10 01:51:49 +04:00
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , value , ret ) ;
2005-09-03 17:28:24 +04:00
} else if ( xmlIsID ( ctxt - > myDoc , ctxt - > node , ret ) )
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , value , ret ) ;
else if ( xmlIsRef ( ctxt - > myDoc , ctxt - > node , ret ) )
xmlAddRef ( & ctxt - > vctxt , ctxt - > myDoc , value , ret ) ;
2003-08-21 02:54:39 +04:00
}
error :
if ( nval ! = NULL )
xmlFree ( nval ) ;
if ( ns ! = NULL )
xmlFree ( ns ) ;
}
/*
* xmlCheckDefaultedAttributes :
*
* Check defaulted attributes from the DTD
*/
static void
xmlCheckDefaultedAttributes ( xmlParserCtxtPtr ctxt , const xmlChar * name ,
const xmlChar * prefix , const xmlChar * * atts ) {
xmlElementPtr elemDecl ;
const xmlChar * att ;
int internal = 1 ;
int i ;
elemDecl = xmlGetDtdQElementDesc ( ctxt - > myDoc - > intSubset , name , prefix ) ;
if ( elemDecl = = NULL ) {
elemDecl = xmlGetDtdQElementDesc ( ctxt - > myDoc - > extSubset , name , prefix ) ;
internal = 0 ;
}
process_external_subset :
if ( elemDecl ! = NULL ) {
xmlAttributePtr attr = elemDecl - > attributes ;
/*
* Check against defaulted attributes from the external subset
* if the document is stamped as standalone
*/
if ( ( ctxt - > myDoc - > standalone = = 1 ) & &
( ctxt - > myDoc - > extSubset ! = NULL ) & &
( ctxt - > validate ) ) {
while ( attr ! = NULL ) {
if ( ( attr - > defaultValue ! = NULL ) & &
( xmlGetDtdQAttrDesc ( ctxt - > myDoc - > extSubset ,
attr - > elem , attr - > name ,
attr - > prefix ) = = attr ) & &
( xmlGetDtdQAttrDesc ( ctxt - > myDoc - > intSubset ,
attr - > elem , attr - > name ,
attr - > prefix ) = = NULL ) ) {
xmlChar * fulln ;
if ( attr - > prefix ! = NULL ) {
fulln = xmlStrdup ( attr - > prefix ) ;
fulln = xmlStrcat ( fulln , BAD_CAST " : " ) ;
fulln = xmlStrcat ( fulln , attr - > name ) ;
} else {
fulln = xmlStrdup ( attr - > name ) ;
}
2009-07-29 13:33:32 +04:00
if ( fulln = = NULL ) {
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElement " ) ;
break ;
}
2003-08-21 02:54:39 +04:00
/*
* Check that the attribute is not declared in the
* serialization
*/
att = NULL ;
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i ] ;
while ( att ! = NULL ) {
if ( xmlStrEqual ( att , fulln ) )
break ;
i + = 2 ;
att = atts [ i ] ;
}
}
if ( att = = NULL ) {
2003-12-08 13:25:02 +03:00
xmlErrValid ( ctxt , XML_DTD_STANDALONE_DEFAULTED ,
2003-08-21 02:54:39 +04:00
" standalone: attribute %s on %s defaulted from external subset \n " ,
2003-12-10 13:42:59 +03:00
( const char * ) fulln ,
( const char * ) attr - > elem ) ;
2003-08-21 02:54:39 +04:00
}
2009-07-29 13:34:50 +04:00
xmlFree ( fulln ) ;
2003-08-21 02:54:39 +04:00
}
attr = attr - > nexth ;
}
}
/*
* Actually insert defaulted values when needed
*/
attr = elemDecl - > attributes ;
while ( attr ! = NULL ) {
/*
* Make sure that attributes redefinition occuring in the
* internal subset are not overriden by definitions in the
* external subset .
*/
if ( attr - > defaultValue ! = NULL ) {
/*
* the element should be instantiated in the tree if :
* - this is a namespace prefix
* - the user required for completion in the tree
* like XSLT
* - there isn ' t already an attribute definition
* in the internal subset overriding it .
*/
if ( ( ( attr - > prefix ! = NULL ) & &
( xmlStrEqual ( attr - > prefix , BAD_CAST " xmlns " ) ) ) | |
( ( attr - > prefix = = NULL ) & &
( xmlStrEqual ( attr - > name , BAD_CAST " xmlns " ) ) ) | |
( ctxt - > loadsubset & XML_COMPLETE_ATTRS ) ) {
xmlAttributePtr tst ;
tst = xmlGetDtdQAttrDesc ( ctxt - > myDoc - > intSubset ,
attr - > elem , attr - > name ,
attr - > prefix ) ;
if ( ( tst = = attr ) | | ( tst = = NULL ) ) {
xmlChar fn [ 50 ] ;
xmlChar * fulln ;
fulln = xmlBuildQName ( attr - > name , attr - > prefix , fn , 50 ) ;
if ( fulln = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElement " ) ;
2003-08-21 02:54:39 +04:00
return ;
}
/*
* Check that the attribute is not declared in the
* serialization
*/
att = NULL ;
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i ] ;
while ( att ! = NULL ) {
if ( xmlStrEqual ( att , fulln ) )
break ;
i + = 2 ;
att = atts [ i ] ;
}
}
if ( att = = NULL ) {
xmlSAX2AttributeInternal ( ctxt , fulln ,
attr - > defaultValue , prefix ) ;
}
if ( ( fulln ! = fn ) & & ( fulln ! = attr - > name ) )
xmlFree ( fulln ) ;
}
}
}
attr = attr - > nexth ;
}
if ( internal = = 1 ) {
elemDecl = xmlGetDtdQElementDesc ( ctxt - > myDoc - > extSubset ,
name , prefix ) ;
internal = 0 ;
goto process_external_subset ;
}
}
}
/**
* xmlSAX2StartElement :
* @ ctx : the user data ( XML parser context )
* @ fullname : The element name , including namespace prefix
* @ atts : An array of name / value attributes pairs , NULL terminated
*
* called when an opening tag has been processed .
*/
void
xmlSAX2StartElement ( void * ctx , const xmlChar * fullname , const xmlChar * * atts )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-08 17:02:18 +03:00
xmlNodePtr parent ;
2003-08-21 02:54:39 +04:00
xmlNsPtr ns ;
xmlChar * name ;
xmlChar * prefix ;
const xmlChar * att ;
const xmlChar * value ;
int i ;
2004-11-09 17:59:59 +03:00
if ( ( ctx = = NULL ) | | ( fullname = = NULL ) | | ( ctxt - > myDoc = = NULL ) ) return ;
2004-11-08 17:02:18 +03:00
parent = ctxt - > node ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2StartElement(%s) \n " , fullname ) ;
# endif
/*
* First check on validity :
*/
if ( ctxt - > validate & & ( ctxt - > myDoc - > extSubset = = NULL ) & &
( ( ctxt - > myDoc - > intSubset = = NULL ) | |
( ( ctxt - > myDoc - > intSubset - > notations = = NULL ) & &
( ctxt - > myDoc - > intSubset - > elements = = NULL ) & &
( ctxt - > myDoc - > intSubset - > attributes = = NULL ) & &
( ctxt - > myDoc - > intSubset - > entities = = NULL ) ) ) ) {
2003-12-08 13:25:02 +03:00
xmlErrValid ( ctxt , XML_ERR_NO_DTD ,
" Validation failed: no DTD found ! " , NULL , NULL ) ;
2003-08-21 02:54:39 +04:00
ctxt - > validate = 0 ;
}
/*
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName ( ctxt , fullname , & prefix ) ;
/*
* Note : the namespace resolution is deferred until the end of the
* attributes parsing , since local namespace can be defined as
* an attribute at this level .
*/
ret = xmlNewDocNodeEatName ( ctxt - > myDoc , NULL , name , NULL ) ;
if ( ret = = NULL ) {
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElement " ) ;
2003-08-21 02:54:39 +04:00
return ;
}
if ( ctxt - > myDoc - > children = = NULL ) {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext , " Setting %s as root \n " , name ) ;
# endif
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
} else if ( parent = = NULL ) {
parent = ctxt - > myDoc - > children ;
}
ctxt - > nodemem = - 1 ;
if ( ctxt - > linenumbers ) {
2003-10-21 04:05:38 +04:00
if ( ctxt - > input ! = NULL ) {
if ( ctxt - > input - > line < 65535 )
ret - > line = ( short ) ctxt - > input - > line ;
else
ret - > line = 65535 ;
}
2003-08-21 02:54:39 +04:00
}
/*
* We are parsing a new node .
*/
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext , " pushing(%s) \n " , name ) ;
# endif
nodePush ( ctxt , ret ) ;
/*
* Link the child element
*/
if ( parent ! = NULL ) {
if ( parent - > type = = XML_ELEMENT_NODE ) {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" adding child %s to %s \n " , name , parent - > name ) ;
# endif
xmlAddChild ( parent , ret ) ;
} else {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" adding sibling %s to " , name ) ;
xmlDebugDumpOneNode ( stderr , parent , 0 ) ;
# endif
xmlAddSibling ( parent , ret ) ;
}
}
/*
* Insert all the defaulted attributes from the DTD especially namespaces
*/
if ( ( ! ctxt - > html ) & &
( ( ctxt - > myDoc - > intSubset ! = NULL ) | |
( ctxt - > myDoc - > extSubset ! = NULL ) ) ) {
xmlCheckDefaultedAttributes ( ctxt , name , prefix , atts ) ;
}
/*
* process all the attributes whose name start with " xmlns "
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
if ( ! ctxt - > html ) {
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
if ( ( att [ 0 ] = = ' x ' ) & & ( att [ 1 ] = = ' m ' ) & & ( att [ 2 ] = = ' l ' ) & &
( att [ 3 ] = = ' n ' ) & & ( att [ 4 ] = = ' s ' ) )
xmlSAX2AttributeInternal ( ctxt , att , value , prefix ) ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
}
}
/*
* Search the namespace , note that since the attributes have been
* processed , the local namespaces are available .
*/
ns = xmlSearchNs ( ctxt - > myDoc , ret , prefix ) ;
if ( ( ns = = NULL ) & & ( parent ! = NULL ) )
ns = xmlSearchNs ( ctxt - > myDoc , parent , prefix ) ;
if ( ( prefix ! = NULL ) & & ( ns = = NULL ) ) {
ns = xmlNewNs ( ret , NULL , prefix ) ;
2006-07-13 10:21:09 +04:00
xmlNsWarnMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
" Namespace prefix %s is not defined \n " ,
prefix , NULL ) ;
2003-08-21 02:54:39 +04:00
}
/*
* set the namespace node , making sure that if the default namspace
* is unbound on a parent we simply kee it NULL
*/
if ( ( ns ! = NULL ) & & ( ns - > href ! = NULL ) & &
( ( ns - > href [ 0 ] ! = 0 ) | | ( ns - > prefix ! = NULL ) ) )
xmlSetNs ( ret , ns ) ;
/*
* process all the other attributes
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
if ( ctxt - > html ) {
while ( att ! = NULL ) {
xmlSAX2AttributeInternal ( ctxt , att , value , NULL ) ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
} else {
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
if ( ( att [ 0 ] ! = ' x ' ) | | ( att [ 1 ] ! = ' m ' ) | | ( att [ 2 ] ! = ' l ' ) | |
( att [ 3 ] ! = ' n ' ) | | ( att [ 4 ] ! = ' s ' ) )
xmlSAX2AttributeInternal ( ctxt , att , value , NULL ) ;
/*
* Next ones
*/
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
}
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
/*
* If it ' s the Document root , finish the DTD validation and
* check the document root element for validity
*/
2004-10-29 16:10:55 +04:00
if ( ( ctxt - > validate ) & & ( ctxt - > vctxt . finishDtd = = XML_CTXT_FINISH_DTD_0 ) ) {
2003-08-21 02:54:39 +04:00
int chk ;
chk = xmlValidateDtdFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
if ( chk < = 0 )
ctxt - > valid = 0 ;
if ( chk < 0 )
ctxt - > wellFormed = 0 ;
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
2004-10-29 16:10:55 +04:00
ctxt - > vctxt . finishDtd = XML_CTXT_FINISH_DTD_1 ;
2003-08-21 02:54:39 +04:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
/**
* xmlSAX2EndElement :
* @ ctx : the user data ( XML parser context )
* @ name : The element name
*
* called when the end of an element has been detected .
*/
void
xmlSAX2EndElement ( void * ctx , const xmlChar * name ATTRIBUTE_UNUSED )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2004-11-08 17:02:18 +03:00
xmlNodePtr cur ;
2003-08-21 02:54:39 +04:00
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2004-11-08 17:02:18 +03:00
cur = ctxt - > node ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
if ( name = = NULL )
xmlGenericError ( xmlGenericErrorContext , " SAX.xmlSAX2EndElement(NULL) \n " ) ;
else
xmlGenericError ( xmlGenericErrorContext , " SAX.xmlSAX2EndElement(%s) \n " , name ) ;
# endif
/* Capture end position and add node */
if ( cur ! = NULL & & ctxt - > record_info ) {
2012-05-08 07:01:12 +04:00
ctxt - > nodeInfo - > end_pos = ctxt - > input - > cur - ctxt - > input - > base ;
ctxt - > nodeInfo - > end_line = ctxt - > input - > line ;
ctxt - > nodeInfo - > node = cur ;
xmlParserAddNodeInfo ( ctxt , ctxt - > nodeInfo ) ;
2003-08-21 02:54:39 +04:00
}
ctxt - > nodemem = - 1 ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-08-21 02:54:39 +04:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneElement ( & ctxt - > vctxt , ctxt - > myDoc ,
cur ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-08-21 02:54:39 +04:00
/*
* end of parsing of this node .
*/
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext , " popping(%s) \n " , cur - > name ) ;
# endif
nodePop ( ctxt ) ;
}
2003-09-30 04:43:48 +04:00
# endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
2003-08-21 02:54:39 +04:00
2003-09-17 17:59:32 +04:00
/*
* xmlSAX2TextNode :
* @ ctxt : the parser context
* @ str : the input string
* @ len : the string length
*
* Remove the entities from an attribute value
*
* Returns the newly allocated string or NULL if not needed or error
*/
static xmlNodePtr
xmlSAX2TextNode ( xmlParserCtxtPtr ctxt , const xmlChar * str , int len ) {
xmlNodePtr ret ;
2003-09-25 01:23:56 +04:00
const xmlChar * intern = NULL ;
2003-09-17 17:59:32 +04:00
2003-09-25 01:23:56 +04:00
/*
* Allocate
*/
2003-09-17 17:59:32 +04:00
if ( ctxt - > freeElems ! = NULL ) {
ret = ctxt - > freeElems ;
ctxt - > freeElems = ret - > next ;
ctxt - > freeElemsNr - - ;
} else {
2003-09-25 01:23:56 +04:00
ret = ( xmlNodePtr ) xmlMalloc ( sizeof ( xmlNode ) ) ;
2003-09-17 17:59:32 +04:00
}
if ( ret = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlErrMemory ( ctxt , " xmlSAX2Characters " ) ;
2003-09-17 17:59:32 +04:00
return ( NULL ) ;
}
2005-08-25 17:19:21 +04:00
memset ( ret , 0 , sizeof ( xmlNode ) ) ;
2003-09-25 01:23:56 +04:00
/*
* intern the formatting blanks found between tags , or the
* very short strings
*/
if ( ctxt - > dictNames ) {
xmlChar cur = str [ len ] ;
2005-08-25 17:19:21 +04:00
if ( ( len < ( int ) ( 2 * sizeof ( void * ) ) ) & &
( ctxt - > options & XML_PARSE_COMPACT ) ) {
/* store the string in the node overrithing properties and nsDef */
xmlChar * tmp = ( xmlChar * ) & ( ret - > properties ) ;
memcpy ( tmp , str , len ) ;
tmp [ len ] = 0 ;
intern = tmp ;
} else if ( ( len < = 3 ) & & ( ( cur = = ' " ' ) | | ( cur = = ' \' ' ) | |
2003-09-26 17:53:14 +04:00
( ( cur = = ' < ' ) & & ( str [ len + 1 ] ! = ' ! ' ) ) ) ) {
2003-09-25 01:23:56 +04:00
intern = xmlDictLookup ( ctxt - > dict , str , len ) ;
2003-10-18 20:20:14 +04:00
} else if ( IS_BLANK_CH ( * str ) & & ( len < 60 ) & & ( cur = = ' < ' ) & &
2003-09-26 17:53:14 +04:00
( str [ len + 1 ] ! = ' ! ' ) ) {
2003-09-25 01:23:56 +04:00
int i ;
for ( i = 1 ; i < len ; i + + ) {
2004-01-02 13:42:01 +03:00
if ( ! IS_BLANK_CH ( str [ i ] ) ) goto skip ;
2003-09-25 01:23:56 +04:00
}
intern = xmlDictLookup ( ctxt - > dict , str , len ) ;
}
}
skip :
ret - > type = XML_TEXT_NODE ;
ret - > name = xmlStringText ;
2004-07-28 11:40:12 +04:00
if ( intern = = NULL ) {
2003-09-25 01:23:56 +04:00
ret - > content = xmlStrndup ( str , len ) ;
2004-07-28 11:40:12 +04:00
if ( ret - > content = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2TextNode " ) ;
xmlFree ( ret ) ;
2004-07-28 11:40:12 +04:00
return ( NULL ) ;
}
} else
2003-09-25 01:23:56 +04:00
ret - > content = ( xmlChar * ) intern ;
2008-07-07 17:52:52 +04:00
if ( ctxt - > input ! = NULL )
ret - > line = ctxt - > input - > line ;
2003-09-25 01:23:56 +04:00
if ( ( __xmlRegisterCallbacks ) & & ( xmlRegisterNodeDefaultValue ) )
xmlRegisterNodeDefaultValue ( ret ) ;
2003-09-17 17:59:32 +04:00
return ( ret ) ;
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
/*
* xmlSAX2DecodeAttrEntities :
* @ ctxt : the parser context
* @ str : the input string
* @ len : the string length
*
* Remove the entities from an attribute value
*
* Returns the newly allocated string or NULL if not needed or error
*/
static xmlChar *
xmlSAX2DecodeAttrEntities ( xmlParserCtxtPtr ctxt , const xmlChar * str ,
const xmlChar * end ) {
const xmlChar * in ;
xmlChar * ret ;
in = str ;
while ( in < end )
if ( * in + + = = ' & ' )
goto decode ;
return ( NULL ) ;
decode :
ctxt - > depth + + ;
ret = xmlStringLenDecodeEntities ( ctxt , str , end - str ,
XML_SUBSTITUTE_REF , 0 , 0 , 0 ) ;
ctxt - > depth - - ;
return ( ret ) ;
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
/**
* xmlSAX2AttributeNs :
* @ ctx : the user data ( XML parser context )
2003-09-15 16:56:36 +04:00
* @ localname : the local name of the attribute
* @ prefix : the attribute namespace prefix if available
* @ URI : the attribute namespace name if available
2003-09-10 14:50:59 +04:00
* @ value : Start of the attribute value
* @ valueend : end of the attribute value
*
* Handle an attribute that has been read by the parser .
* The default handling is to convert the attribute into an
* DOM subtree and past it in a new xmlAttr element added to
* the element .
*/
static void
xmlSAX2AttributeNs ( xmlParserCtxtPtr ctxt ,
const xmlChar * localname ,
const xmlChar * prefix ,
const xmlChar * value ,
const xmlChar * valueend )
{
xmlAttrPtr ret ;
xmlNsPtr namespace = NULL ;
xmlChar * dup = NULL ;
/*
* Note : if prefix = = NULL , the attribute is not in the default namespace
*/
if ( prefix ! = NULL )
namespace = xmlSearchNs ( ctxt - > myDoc , ctxt - > node , prefix ) ;
2003-09-15 18:50:06 +04:00
/*
* allocate the node
*/
if ( ctxt - > freeAttrs ! = NULL ) {
ret = ctxt - > freeAttrs ;
ctxt - > freeAttrs = ret - > next ;
2003-09-17 17:59:32 +04:00
ctxt - > freeAttrsNr - - ;
2003-09-15 18:50:06 +04:00
memset ( ret , 0 , sizeof ( xmlAttr ) ) ;
ret - > type = XML_ATTRIBUTE_NODE ;
ret - > parent = ctxt - > node ;
ret - > doc = ctxt - > myDoc ;
ret - > ns = namespace ;
if ( ctxt - > dictNames )
ret - > name = localname ;
else
ret - > name = xmlStrdup ( localname ) ;
2003-09-17 14:26:25 +04:00
/* link at the end to preserv order, TODO speed up with a last */
if ( ctxt - > node - > properties = = NULL ) {
ctxt - > node - > properties = ret ;
} else {
xmlAttrPtr prev = ctxt - > node - > properties ;
while ( prev - > next ! = NULL ) prev = prev - > next ;
prev - > next = ret ;
ret - > prev = prev ;
}
2003-09-15 18:50:06 +04:00
if ( ( __xmlRegisterCallbacks ) & & ( xmlRegisterNodeDefaultValue ) )
xmlRegisterNodeDefaultValue ( ( xmlNodePtr ) ret ) ;
} else {
if ( ctxt - > dictNames )
ret = xmlNewNsPropEatName ( ctxt - > node , namespace ,
( xmlChar * ) localname , NULL ) ;
else
ret = xmlNewNsProp ( ctxt - > node , namespace , localname , NULL ) ;
if ( ret = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlErrMemory ( ctxt , " xmlSAX2AttributeNs " ) ;
2003-09-15 18:50:06 +04:00
return ;
}
}
2003-09-10 14:50:59 +04:00
2003-09-15 18:50:06 +04:00
if ( ( ctxt - > replaceEntities = = 0 ) & & ( ! ctxt - > html ) ) {
xmlNodePtr tmp ;
2003-09-17 17:59:32 +04:00
/*
* We know that if there is an entity reference , then
* the string has been dup ' ed and terminates with 0
* otherwise with ' or "
*/
if ( * valueend ! = 0 ) {
tmp = xmlSAX2TextNode ( ctxt , value , valueend - value ) ;
ret - > children = tmp ;
ret - > last = tmp ;
if ( tmp ! = NULL ) {
tmp - > doc = ret - > doc ;
tmp - > parent = ( xmlNodePtr ) ret ;
}
} else {
ret - > children = xmlStringLenGetNodeList ( ctxt - > myDoc , value ,
valueend - value ) ;
tmp = ret - > children ;
while ( tmp ! = NULL ) {
2004-10-07 17:14:19 +04:00
tmp - > doc = ret - > doc ;
2003-09-17 17:59:32 +04:00
tmp - > parent = ( xmlNodePtr ) ret ;
if ( tmp - > next = = NULL )
ret - > last = tmp ;
tmp = tmp - > next ;
}
2003-09-10 14:50:59 +04:00
}
2003-09-15 18:50:06 +04:00
} else if ( value ! = NULL ) {
2003-09-17 17:59:32 +04:00
xmlNodePtr tmp ;
tmp = xmlSAX2TextNode ( ctxt , value , valueend - value ) ;
ret - > children = tmp ;
ret - > last = tmp ;
if ( tmp ! = NULL ) {
tmp - > doc = ret - > doc ;
tmp - > parent = ( xmlNodePtr ) ret ;
}
2003-09-10 14:50:59 +04:00
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
/*
* If we don ' t substitute entities , the validation should be
* done on a value with replaced entities anyway .
*/
if ( ! ctxt - > replaceEntities ) {
dup = xmlSAX2DecodeAttrEntities ( ctxt , value , valueend ) ;
if ( dup = = NULL ) {
2003-09-15 16:56:36 +04:00
if ( * valueend = = 0 ) {
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , value ) ;
} else {
/*
* That should already be normalized .
* cheaper to finally allocate here than duplicate
* entry points in the full validation code
*/
dup = xmlStrndup ( value , valueend - value ) ;
2003-09-10 14:50:59 +04:00
2003-09-15 16:56:36 +04:00
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , dup ) ;
}
2003-09-10 14:50:59 +04:00
} else {
2003-09-15 16:56:36 +04:00
/*
* dup now contains a string of the flattened attribute
* content with entities substitued . Check if we need to
* apply an extra layer of normalization .
2003-09-10 14:50:59 +04:00
* It need to be done twice . . . it ' s an extra burden related
* to the ability to keep references in attributes
*/
2003-09-15 16:56:36 +04:00
if ( ctxt - > attsSpecial ! = NULL ) {
xmlChar * nvalnorm ;
xmlChar fn [ 50 ] ;
xmlChar * fullname ;
fullname = xmlBuildQName ( localname , prefix , fn , 50 ) ;
if ( fullname ! = NULL ) {
ctxt - > vctxt . valid = 1 ;
nvalnorm = xmlValidCtxtNormalizeAttributeValue (
& ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , fullname , dup ) ;
if ( ctxt - > vctxt . valid ! = 1 )
ctxt - > valid = 0 ;
if ( ( fullname ! = fn ) & & ( fullname ! = localname ) )
xmlFree ( fullname ) ;
if ( nvalnorm ! = NULL ) {
xmlFree ( dup ) ;
dup = nvalnorm ;
}
}
2003-09-10 14:50:59 +04:00
}
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , dup ) ;
}
} else {
2003-09-10 14:50:59 +04:00
/*
* if entities already have been substitued , then
* the attribute as passed is already normalized
*/
2003-09-10 14:50:59 +04:00
dup = xmlStrndup ( value , valueend - value ) ;
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , dup ) ;
}
2003-09-28 22:58:27 +04:00
} else
# endif /* LIBXML_VALID_ENABLED */
if ( ( ( ctxt - > loadsubset & XML_SKIP_IDS ) = = 0 ) & &
2003-09-10 14:50:59 +04:00
( ( ( ctxt - > replaceEntities = = 0 ) & & ( ctxt - > external ! = 2 ) ) | |
( ( ctxt - > replaceEntities ! = 0 ) & & ( ctxt - > inSubset = = 0 ) ) ) ) {
/*
* when validating , the ID registration is done at the attribute
* validation level . Otherwise we have to do specific handling here .
*/
2005-09-03 17:28:24 +04:00
if ( ( prefix = = ctxt - > str_xml ) & &
2004-04-10 01:51:49 +04:00
( localname [ 0 ] = = ' i ' ) & & ( localname [ 1 ] = = ' d ' ) & &
( localname [ 2 ] = = 0 ) ) {
/*
* Add the xml : id value
*
* Open issue : normalization of the value .
*/
if ( dup = = NULL )
dup = xmlStrndup ( value , valueend - value ) ;
2004-05-24 03:56:47 +04:00
# ifdef LIBXML_VALID_ENABLED
2004-04-19 00:55:39 +04:00
if ( xmlValidateNCName ( dup , 1 ) ! = 0 ) {
xmlErrValid ( ctxt , XML_DTD_XMLID_VALUE ,
" xml:id : attribute value %s is not an NCName \n " ,
( const char * ) dup , NULL ) ;
}
2004-05-22 05:09:26 +04:00
# endif
2004-04-10 01:51:49 +04:00
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , dup , ret ) ;
2005-09-03 17:28:24 +04:00
} else if ( xmlIsID ( ctxt - > myDoc , ctxt - > node , ret ) ) {
/* might be worth duplicate entry points and not copy */
if ( dup = = NULL )
dup = xmlStrndup ( value , valueend - value ) ;
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , dup , ret ) ;
} else if ( xmlIsRef ( ctxt - > myDoc , ctxt - > node , ret ) ) {
if ( dup = = NULL )
dup = xmlStrndup ( value , valueend - value ) ;
xmlAddRef ( & ctxt - > vctxt , ctxt - > myDoc , dup , ret ) ;
2004-04-10 01:51:49 +04:00
}
2003-09-10 14:50:59 +04:00
}
if ( dup ! = NULL )
xmlFree ( dup ) ;
}
/**
* xmlSAX2StartElementNs :
* @ ctx : the user data ( XML parser context )
* @ localname : the local name of the element
* @ prefix : the element namespace prefix if available
* @ URI : the element namespace name if available
* @ nb_namespaces : number of namespace definitions on that node
* @ namespaces : pointer to the array of prefix / URI pairs namespace definitions
* @ nb_attributes : the number of attributes on that node
2003-09-25 16:18:34 +04:00
* @ nb_defaulted : the number of defaulted attributes .
2003-09-10 14:50:59 +04:00
* @ attributes : pointer to the array of ( localname / prefix / URI / value / end )
* attribute values .
*
* SAX2 callback when an element start has been detected by the parser .
* It provides the namespace informations for the element , as well as
* the new namespace declarations on the element .
*/
void
xmlSAX2StartElementNs ( void * ctx ,
const xmlChar * localname ,
const xmlChar * prefix ,
const xmlChar * URI ,
int nb_namespaces ,
const xmlChar * * namespaces ,
int nb_attributes ,
int nb_defaulted ,
const xmlChar * * attributes )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-08 17:02:18 +03:00
xmlNodePtr parent ;
2003-09-10 14:50:59 +04:00
xmlNsPtr last = NULL , ns ;
const xmlChar * uri , * pref ;
2012-01-26 15:11:02 +04:00
xmlChar * lname = NULL ;
2003-09-10 14:50:59 +04:00
int i , j ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2004-11-08 17:02:18 +03:00
parent = ctxt - > node ;
2003-09-10 14:50:59 +04:00
/*
* First check on validity :
*/
if ( ctxt - > validate & & ( ctxt - > myDoc - > extSubset = = NULL ) & &
( ( ctxt - > myDoc - > intSubset = = NULL ) | |
( ( ctxt - > myDoc - > intSubset - > notations = = NULL ) & &
( ctxt - > myDoc - > intSubset - > elements = = NULL ) & &
( ctxt - > myDoc - > intSubset - > attributes = = NULL ) & &
( ctxt - > myDoc - > intSubset - > entities = = NULL ) ) ) ) {
2003-12-08 13:25:02 +03:00
xmlErrValid ( ctxt , XML_ERR_NO_DTD ,
" Validation failed: no DTD found ! " , NULL , NULL ) ;
2003-09-10 14:50:59 +04:00
ctxt - > validate = 0 ;
}
2012-01-26 15:11:02 +04:00
/*
* Take care of the rare case of an undefined namespace prefix
*/
if ( ( prefix ! = NULL ) & & ( URI = = NULL ) ) {
if ( ctxt - > dictNames ) {
const xmlChar * fullname ;
fullname = xmlDictQLookup ( ctxt - > dict , prefix , localname ) ;
if ( fullname ! = NULL )
localname = fullname ;
} else {
lname = xmlBuildQName ( localname , prefix , NULL , 0 ) ;
}
}
2003-09-15 18:50:06 +04:00
/*
* allocate the node
*/
if ( ctxt - > freeElems ! = NULL ) {
ret = ctxt - > freeElems ;
ctxt - > freeElems = ret - > next ;
2003-09-17 17:59:32 +04:00
ctxt - > freeElemsNr - - ;
2003-09-15 18:50:06 +04:00
memset ( ret , 0 , sizeof ( xmlNode ) ) ;
ret - > type = XML_ELEMENT_NODE ;
if ( ctxt - > dictNames )
ret - > name = localname ;
2004-07-28 11:40:12 +04:00
else {
2012-01-26 15:11:02 +04:00
if ( lname = = NULL )
ret - > name = xmlStrdup ( localname ) ;
else
ret - > name = lname ;
2004-07-28 11:40:12 +04:00
if ( ret - > name = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElementNs " ) ;
2004-07-28 11:40:12 +04:00
return ;
}
}
2003-09-15 18:50:06 +04:00
if ( ( __xmlRegisterCallbacks ) & & ( xmlRegisterNodeDefaultValue ) )
xmlRegisterNodeDefaultValue ( ret ) ;
} else {
if ( ctxt - > dictNames )
ret = xmlNewDocNodeEatName ( ctxt - > myDoc , NULL ,
( xmlChar * ) localname , NULL ) ;
2012-01-26 15:11:02 +04:00
else if ( lname = = NULL )
2003-09-15 18:50:06 +04:00
ret = xmlNewDocNode ( ctxt - > myDoc , NULL , localname , NULL ) ;
2012-01-26 15:11:02 +04:00
else
ret = xmlNewDocNodeEatName ( ctxt - > myDoc , NULL ,
( xmlChar * ) lname , NULL ) ;
2003-09-15 18:50:06 +04:00
if ( ret = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElementNs " ) ;
2003-09-15 18:50:06 +04:00
return ;
}
2003-09-10 14:50:59 +04:00
}
2003-09-19 02:03:46 +04:00
if ( ctxt - > linenumbers ) {
2003-10-21 04:05:38 +04:00
if ( ctxt - > input ! = NULL ) {
if ( ctxt - > input - > line < 65535 )
ret - > line = ( short ) ctxt - > input - > line ;
else
ret - > line = 65535 ;
}
2003-09-19 02:03:46 +04:00
}
2003-09-15 18:50:06 +04:00
2012-01-18 07:25:08 +04:00
if ( parent = = NULL ) {
2003-09-10 14:50:59 +04:00
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
}
/*
* Build the namespace list
*/
for ( i = 0 , j = 0 ; j < nb_namespaces ; j + + ) {
pref = namespaces [ i + + ] ;
uri = namespaces [ i + + ] ;
ns = xmlNewNs ( NULL , uri , pref ) ;
if ( ns ! = NULL ) {
if ( last = = NULL ) {
ret - > nsDef = last = ns ;
} else {
last - > next = ns ;
last = ns ;
}
if ( ( URI ! = NULL ) & & ( prefix = = pref ) )
ret - > ns = ns ;
} else {
2010-09-09 20:17:47 +04:00
/*
* any out of memory error would already have been raised
* but we can ' t be garanteed it ' s the actual error due to the
* API , best is to skip in this case
*/
continue ;
2003-09-10 14:50:59 +04:00
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-19 02:03:46 +04:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset ) {
ctxt - > valid & = xmlValidateOneNamespace ( & ctxt - > vctxt , ctxt - > myDoc ,
ret , prefix , ns , uri ) ;
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
}
ctxt - > nodemem = - 1 ;
/*
* We are parsing a new node .
*/
nodePush ( ctxt , ret ) ;
/*
* Link the child element
*/
if ( parent ! = NULL ) {
if ( parent - > type = = XML_ELEMENT_NODE ) {
xmlAddChild ( parent , ret ) ;
} else {
xmlAddSibling ( parent , ret ) ;
}
}
/*
* Insert the defaulted attributes from the DTD only if requested :
*/
if ( ( nb_defaulted ! = 0 ) & &
( ( ctxt - > loadsubset & XML_COMPLETE_ATTRS ) = = 0 ) )
nb_attributes - = nb_defaulted ;
/*
* Search the namespace if it wasn ' t already found
2004-08-31 10:47:17 +04:00
* Note that , if prefix is NULL , this searches for the default Ns
2003-09-10 14:50:59 +04:00
*/
if ( ( URI ! = NULL ) & & ( ret - > ns = = NULL ) ) {
2004-08-31 10:47:17 +04:00
ret - > ns = xmlSearchNs ( ctxt - > myDoc , parent , prefix ) ;
2006-01-04 17:03:10 +03:00
if ( ( ret - > ns = = NULL ) & & ( xmlStrEqual ( prefix , BAD_CAST " xml " ) ) ) {
ret - > ns = xmlSearchNs ( ctxt - > myDoc , ret , prefix ) ;
}
2003-09-10 14:50:59 +04:00
if ( ret - > ns = = NULL ) {
ns = xmlNewNs ( ret , NULL , prefix ) ;
2004-07-28 11:40:12 +04:00
if ( ns = = NULL ) {
2006-01-04 17:03:10 +03:00
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2StartElementNs " ) ;
2004-07-28 11:40:12 +04:00
return ;
}
2009-08-26 17:57:20 +04:00
if ( prefix ! = NULL )
xmlNsWarnMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
" Namespace prefix %s was not found \n " ,
prefix , NULL ) ;
else
xmlNsWarnMsg ( ctxt , XML_NS_ERR_UNDEFINED_NAMESPACE ,
" Namespace default prefix was not found \n " ,
NULL , NULL ) ;
2003-09-10 14:50:59 +04:00
}
}
/*
* process all the other attributes
*/
if ( nb_attributes > 0 ) {
for ( j = 0 , i = 0 ; i < nb_attributes ; i + + , j + = 5 ) {
2012-01-26 15:43:06 +04:00
/*
* Handle the rare case of an undefined atribute prefix
*/
if ( ( attributes [ j + 1 ] ! = NULL ) & & ( attributes [ j + 2 ] = = NULL ) ) {
if ( ctxt - > dictNames ) {
const xmlChar * fullname ;
fullname = xmlDictQLookup ( ctxt - > dict , attributes [ j + 1 ] ,
attributes [ j ] ) ;
if ( fullname ! = NULL ) {
xmlSAX2AttributeNs ( ctxt , fullname , NULL ,
attributes [ j + 3 ] , attributes [ j + 4 ] ) ;
continue ;
}
} else {
lname = xmlBuildQName ( attributes [ j ] , attributes [ j + 1 ] ,
NULL , 0 ) ;
if ( lname ! = NULL ) {
xmlSAX2AttributeNs ( ctxt , lname , NULL ,
attributes [ j + 3 ] , attributes [ j + 4 ] ) ;
xmlFree ( lname ) ;
continue ;
}
}
}
2003-09-10 14:50:59 +04:00
xmlSAX2AttributeNs ( ctxt , attributes [ j ] , attributes [ j + 1 ] ,
2012-01-26 15:43:06 +04:00
attributes [ j + 3 ] , attributes [ j + 4 ] ) ;
2003-09-10 14:50:59 +04:00
}
}
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
/*
* If it ' s the Document root , finish the DTD validation and
* check the document root element for validity
*/
2004-10-29 16:10:55 +04:00
if ( ( ctxt - > validate ) & & ( ctxt - > vctxt . finishDtd = = XML_CTXT_FINISH_DTD_0 ) ) {
2003-09-10 14:50:59 +04:00
int chk ;
chk = xmlValidateDtdFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
if ( chk < = 0 )
ctxt - > valid = 0 ;
if ( chk < 0 )
ctxt - > wellFormed = 0 ;
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
2004-10-29 16:10:55 +04:00
ctxt - > vctxt . finishDtd = XML_CTXT_FINISH_DTD_1 ;
2003-09-10 14:50:59 +04:00
}
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
}
/**
* xmlSAX2EndElementNs :
* @ ctx : the user data ( XML parser context )
* @ localname : the local name of the element
* @ prefix : the element namespace prefix if available
* @ URI : the element namespace name if available
*
* SAX2 callback when an element end has been detected by the parser .
* It provides the namespace informations for the element .
*/
void
xmlSAX2EndElementNs ( void * ctx ,
const xmlChar * localname ATTRIBUTE_UNUSED ,
const xmlChar * prefix ATTRIBUTE_UNUSED ,
const xmlChar * URI ATTRIBUTE_UNUSED )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlParserNodeInfo node_info ;
2004-11-08 17:02:18 +03:00
xmlNodePtr cur ;
2003-09-10 14:50:59 +04:00
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2004-11-08 17:02:18 +03:00
cur = ctxt - > node ;
2003-09-10 14:50:59 +04:00
/* Capture end position and add node */
if ( ( ctxt - > record_info ) & & ( cur ! = NULL ) ) {
node_info . end_pos = ctxt - > input - > cur - ctxt - > input - > base ;
node_info . end_line = ctxt - > input - > line ;
node_info . node = cur ;
xmlParserAddNodeInfo ( ctxt , & node_info ) ;
}
ctxt - > nodemem = - 1 ;
2003-09-28 22:58:27 +04:00
# ifdef LIBXML_VALID_ENABLED
2003-09-10 14:50:59 +04:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneElement ( & ctxt - > vctxt , ctxt - > myDoc , cur ) ;
2003-09-28 22:58:27 +04:00
# endif /* LIBXML_VALID_ENABLED */
2003-09-10 14:50:59 +04:00
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
}
2003-08-21 02:54:39 +04:00
/**
* xmlSAX2Reference :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
* called when an entity xmlSAX2Reference is detected .
*/
void
xmlSAX2Reference ( void * ctx , const xmlChar * name )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2Reference(%s) \n " , name ) ;
# endif
if ( name [ 0 ] = = ' # ' )
ret = xmlNewCharRef ( ctxt - > myDoc , name ) ;
else
ret = xmlNewReference ( ctxt - > myDoc , name ) ;
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" add xmlSAX2Reference %s to %s \n " , name , ctxt - > node - > name ) ;
# endif
2008-02-08 12:56:31 +03:00
if ( xmlAddChild ( ctxt - > node , ret ) = = NULL ) {
xmlFreeNode ( ret ) ;
}
2003-08-21 02:54:39 +04:00
}
/**
* xmlSAX2Characters :
* @ ctx : the user data ( XML parser context )
* @ ch : a xmlChar string
* @ len : the number of xmlChar
*
* receiving some chars from the parser .
*/
void
xmlSAX2Characters ( void * ctx , const xmlChar * ch , int len )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr lastChild ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2Characters(%.30s, %d) \n " , ch , len ) ;
# endif
/*
* Handle the data if any . If there is no child
* add it as content , otherwise if the last child is text ,
* concatenate it , else create a new node of type text .
*/
if ( ctxt - > node = = NULL ) {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" add chars: ctxt->node == NULL ! \n " ) ;
# endif
return ;
}
2003-09-17 17:59:32 +04:00
lastChild = ctxt - > node - > last ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" add chars to %s \n " , ctxt - > node - > name ) ;
# endif
/*
* Here we needed an accelerator mechanism in case of very large
* elements . Use an attribute in the structure ! ! !
*/
if ( lastChild = = NULL ) {
2003-09-17 17:59:32 +04:00
lastChild = xmlSAX2TextNode ( ctxt , ch , len ) ;
if ( lastChild ! = NULL ) {
ctxt - > node - > children = lastChild ;
ctxt - > node - > last = lastChild ;
lastChild - > parent = ctxt - > node ;
lastChild - > doc = ctxt - > node - > doc ;
2003-08-21 02:54:39 +04:00
ctxt - > nodelen = len ;
ctxt - > nodemem = len + 1 ;
2004-07-31 20:24:01 +04:00
} else {
xmlSAX2ErrMemory ( ctxt , " xmlSAX2Characters " ) ;
return ;
2003-08-21 02:54:39 +04:00
}
} else {
int coalesceText = ( lastChild ! = NULL ) & &
( lastChild - > type = = XML_TEXT_NODE ) & &
( lastChild - > name = = xmlStringText ) ;
if ( ( coalesceText ) & & ( ctxt - > nodemem ! = 0 ) ) {
/*
* The whole point of maintaining nodelen and nodemem ,
* xmlTextConcat is too costly , i . e . compute length ,
* reallocate a new buffer , move data , append ch . Here
* We try to minimaze realloc ( ) uses and avoid copying
* and recomputing length over and over .
*/
2005-08-25 17:19:21 +04:00
if ( lastChild - > content = = ( xmlChar * ) & ( lastChild - > properties ) ) {
lastChild - > content = xmlStrdup ( lastChild - > content ) ;
lastChild - > properties = NULL ;
} else if ( ( ctxt - > nodemem = = ctxt - > nodelen + 1 ) & &
( xmlDictOwns ( ctxt - > dict , lastChild - > content ) ) ) {
2003-10-10 23:36:36 +04:00
lastChild - > content = xmlStrdup ( lastChild - > content ) ;
}
2009-01-19 00:43:30 +03:00
if ( ( ( size_t ) ctxt - > nodelen + ( size_t ) len > XML_MAX_TEXT_LENGTH ) & &
2009-01-18 17:08:36 +03:00
( ( ctxt - > options & XML_PARSE_HUGE ) = = 0 ) ) {
xmlSAX2ErrMemory ( ctxt , " xmlSAX2Characters: huge text node " ) ;
return ;
}
2008-11-17 18:59:21 +03:00
if ( ( size_t ) ctxt - > nodelen > SIZE_T_MAX - ( size_t ) len | |
( size_t ) ctxt - > nodemem + ( size_t ) len > SIZE_T_MAX / 2 ) {
2009-01-18 17:08:36 +03:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2Characters overflow prevented " ) ;
return ;
2008-11-17 18:59:21 +03:00
}
2003-08-21 02:54:39 +04:00
if ( ctxt - > nodelen + len > = ctxt - > nodemem ) {
xmlChar * newbuf ;
2008-11-17 18:59:21 +03:00
size_t size ;
2003-08-21 02:54:39 +04:00
size = ctxt - > nodemem + len ;
size * = 2 ;
newbuf = ( xmlChar * ) xmlRealloc ( lastChild - > content , size ) ;
if ( newbuf = = NULL ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2Characters " ) ;
2003-08-21 02:54:39 +04:00
return ;
}
ctxt - > nodemem = size ;
lastChild - > content = newbuf ;
}
memcpy ( & lastChild - > content [ ctxt - > nodelen ] , ch , len ) ;
ctxt - > nodelen + = len ;
lastChild - > content [ ctxt - > nodelen ] = 0 ;
} else if ( coalesceText ) {
if ( xmlTextConcat ( lastChild , ch , len ) ) {
2004-07-29 11:07:16 +04:00
xmlSAX2ErrMemory ( ctxt , " xmlSAX2Characters " ) ;
2003-08-21 02:54:39 +04:00
}
if ( ctxt - > node - > children ! = NULL ) {
ctxt - > nodelen = xmlStrlen ( lastChild - > content ) ;
ctxt - > nodemem = ctxt - > nodelen + 1 ;
}
} else {
/* Mixed content, first time */
2003-09-17 17:59:32 +04:00
lastChild = xmlSAX2TextNode ( ctxt , ch , len ) ;
if ( lastChild ! = NULL ) {
2003-08-21 02:54:39 +04:00
xmlAddChild ( ctxt - > node , lastChild ) ;
if ( ctxt - > node - > children ! = NULL ) {
ctxt - > nodelen = len ;
ctxt - > nodemem = len + 1 ;
}
}
}
}
}
/**
* xmlSAX2IgnorableWhitespace :
* @ ctx : the user data ( XML parser context )
* @ ch : a xmlChar string
* @ len : the number of xmlChar
*
* receiving some ignorable whitespaces from the parser .
* UNUSED : by default the DOM building will use xmlSAX2Characters
*/
void
xmlSAX2IgnorableWhitespace ( void * ctx ATTRIBUTE_UNUSED , const xmlChar * ch ATTRIBUTE_UNUSED , int len ATTRIBUTE_UNUSED )
{
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2IgnorableWhitespace(%.30s, %d) \n " , ch , len ) ;
# endif
}
/**
* xmlSAX2ProcessingInstruction :
* @ ctx : the user data ( XML parser context )
* @ target : the target name
* @ data : the PI data ' s
*
* A processing instruction has been parsed .
*/
void
xmlSAX2ProcessingInstruction ( void * ctx , const xmlChar * target ,
const xmlChar * data )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-08 20:16:15 +03:00
xmlNodePtr parent ;
2003-08-21 02:54:39 +04:00
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2004-11-08 20:16:15 +03:00
parent = ctxt - > node ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.xmlSAX2ProcessingInstruction(%s, %s) \n " , target , data ) ;
# endif
2004-10-26 20:06:51 +04:00
ret = xmlNewDocPI ( ctxt - > myDoc , target , data ) ;
2003-08-21 02:54:39 +04:00
if ( ret = = NULL ) return ;
2005-08-24 18:05:37 +04:00
if ( ctxt - > linenumbers ) {
if ( ctxt - > input ! = NULL ) {
if ( ctxt - > input - > line < 65535 )
ret - > line = ( short ) ctxt - > input - > line ;
else
ret - > line = 65535 ;
}
}
2003-08-21 02:54:39 +04:00
if ( ctxt - > inSubset = = 1 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > intSubset , ret ) ;
return ;
} else if ( ctxt - > inSubset = = 2 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > extSubset , ret ) ;
return ;
}
2012-01-18 07:25:08 +04:00
if ( parent = = NULL ) {
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" Setting PI %s as root \n " , target ) ;
# endif
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
return ;
}
if ( parent - > type = = XML_ELEMENT_NODE ) {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" adding PI %s child to %s \n " , target , parent - > name ) ;
# endif
xmlAddChild ( parent , ret ) ;
} else {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" adding PI %s sibling to " , target ) ;
xmlDebugDumpOneNode ( stderr , parent , 0 ) ;
# endif
xmlAddSibling ( parent , ret ) ;
}
}
/**
* xmlSAX2Comment :
* @ ctx : the user data ( XML parser context )
* @ value : the xmlSAX2Comment content
*
* A xmlSAX2Comment has been parsed .
*/
void
xmlSAX2Comment ( void * ctx , const xmlChar * value )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
2004-11-04 20:34:35 +03:00
xmlNodePtr parent ;
2003-08-21 02:54:39 +04:00
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
parent = ctxt - > node ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext , " SAX.xmlSAX2Comment(%s) \n " , value ) ;
# endif
ret = xmlNewDocComment ( ctxt - > myDoc , value ) ;
if ( ret = = NULL ) return ;
2005-08-24 18:05:37 +04:00
if ( ctxt - > linenumbers ) {
if ( ctxt - > input ! = NULL ) {
if ( ctxt - > input - > line < 65535 )
ret - > line = ( short ) ctxt - > input - > line ;
else
ret - > line = 65535 ;
}
}
2003-08-21 02:54:39 +04:00
if ( ctxt - > inSubset = = 1 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > intSubset , ret ) ;
return ;
} else if ( ctxt - > inSubset = = 2 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > extSubset , ret ) ;
return ;
}
2012-01-18 07:25:08 +04:00
if ( parent = = NULL ) {
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" Setting xmlSAX2Comment as root \n " ) ;
# endif
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
return ;
}
if ( parent - > type = = XML_ELEMENT_NODE ) {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" adding xmlSAX2Comment child to %s \n " , parent - > name ) ;
# endif
xmlAddChild ( parent , ret ) ;
} else {
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" adding xmlSAX2Comment sibling to " ) ;
xmlDebugDumpOneNode ( stderr , parent , 0 ) ;
# endif
xmlAddSibling ( parent , ret ) ;
}
}
/**
* xmlSAX2CDataBlock :
* @ ctx : the user data ( XML parser context )
* @ value : The pcdata content
* @ len : the block length
*
* called when a pcdata block has been parsed
*/
void
xmlSAX2CDataBlock ( void * ctx , const xmlChar * value , int len )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret , lastChild ;
2004-11-04 20:34:35 +03:00
if ( ctx = = NULL ) return ;
2003-08-21 02:54:39 +04:00
# ifdef DEBUG_SAX
xmlGenericError ( xmlGenericErrorContext ,
" SAX.pcdata(%.10s, %d) \n " , value , len ) ;
# endif
lastChild = xmlGetLastChild ( ctxt - > node ) ;
# ifdef DEBUG_SAX_TREE
xmlGenericError ( xmlGenericErrorContext ,
" add chars to %s \n " , ctxt - > node - > name ) ;
# endif
if ( ( lastChild ! = NULL ) & &
( lastChild - > type = = XML_CDATA_SECTION_NODE ) ) {
xmlTextConcat ( lastChild , value , len ) ;
} else {
ret = xmlNewCDataBlock ( ctxt - > myDoc , value , len ) ;
xmlAddChild ( ctxt - > node , ret ) ;
}
}
2003-09-15 16:56:36 +04:00
static int xmlSAX2DefaultVersionValue = 2 ;
2003-09-10 14:50:59 +04:00
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
2003-08-21 02:54:39 +04:00
/**
2003-09-10 14:50:59 +04:00
* xmlSAXDefaultVersion :
* @ version : the version , 1 or 2
2003-08-21 02:54:39 +04:00
*
2003-09-10 14:50:59 +04:00
* Set the default version of SAX used globally by the library .
2004-06-30 15:48:47 +04:00
* By default , during initialization the default is set to 2.
* Note that it is generally a better coding style to use
* xmlSAXVersion ( ) to set up the version explicitly for a given
* parsing context .
2003-09-10 14:50:59 +04:00
*
* Returns the previous value in case of success and - 1 in case of error .
2003-08-21 02:54:39 +04:00
*/
2003-09-10 14:50:59 +04:00
int
xmlSAXDefaultVersion ( int version )
2003-08-21 02:54:39 +04:00
{
2003-09-10 14:50:59 +04:00
int ret = xmlSAX2DefaultVersionValue ;
if ( ( version ! = 1 ) & & ( version ! = 2 ) )
return ( - 1 ) ;
xmlSAX2DefaultVersionValue = version ;
return ( ret ) ;
}
2003-09-30 04:43:48 +04:00
# endif /* LIBXML_SAX1_ENABLED */
2003-08-21 02:54:39 +04:00
2003-09-10 14:50:59 +04:00
/**
* xmlSAXVersion :
* @ hdlr : the SAX handler
* @ version : the version , 1 or 2
*
* Initialize the default XML SAX handler according to the version
*
* Returns 0 in case of success and - 1 in case of error .
*/
int
xmlSAXVersion ( xmlSAXHandler * hdlr , int version )
{
if ( hdlr = = NULL ) return ( - 1 ) ;
2003-09-30 04:43:48 +04:00
if ( version = = 2 ) {
2003-09-10 14:50:59 +04:00
hdlr - > startElement = NULL ;
hdlr - > endElement = NULL ;
hdlr - > startElementNs = xmlSAX2StartElementNs ;
hdlr - > endElementNs = xmlSAX2EndElementNs ;
2003-10-10 18:46:54 +04:00
hdlr - > serror = NULL ;
2003-09-25 18:29:29 +04:00
hdlr - > initialized = XML_SAX2_MAGIC ;
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
} else if ( version = = 1 ) {
hdlr - > startElement = xmlSAX2StartElement ;
hdlr - > endElement = xmlSAX2EndElement ;
hdlr - > initialized = 1 ;
# endif /* LIBXML_SAX1_ENABLED */
2003-09-10 14:50:59 +04:00
} else
return ( - 1 ) ;
2003-08-21 02:54:39 +04:00
hdlr - > internalSubset = xmlSAX2InternalSubset ;
hdlr - > externalSubset = xmlSAX2ExternalSubset ;
hdlr - > isStandalone = xmlSAX2IsStandalone ;
hdlr - > hasInternalSubset = xmlSAX2HasInternalSubset ;
hdlr - > hasExternalSubset = xmlSAX2HasExternalSubset ;
hdlr - > resolveEntity = xmlSAX2ResolveEntity ;
hdlr - > getEntity = xmlSAX2GetEntity ;
hdlr - > getParameterEntity = xmlSAX2GetParameterEntity ;
hdlr - > entityDecl = xmlSAX2EntityDecl ;
hdlr - > attributeDecl = xmlSAX2AttributeDecl ;
hdlr - > elementDecl = xmlSAX2ElementDecl ;
hdlr - > notationDecl = xmlSAX2NotationDecl ;
hdlr - > unparsedEntityDecl = xmlSAX2UnparsedEntityDecl ;
hdlr - > setDocumentLocator = xmlSAX2SetDocumentLocator ;
hdlr - > startDocument = xmlSAX2StartDocument ;
hdlr - > endDocument = xmlSAX2EndDocument ;
hdlr - > reference = xmlSAX2Reference ;
hdlr - > characters = xmlSAX2Characters ;
hdlr - > cdataBlock = xmlSAX2CDataBlock ;
hdlr - > ignorableWhitespace = xmlSAX2Characters ;
hdlr - > processingInstruction = xmlSAX2ProcessingInstruction ;
hdlr - > comment = xmlSAX2Comment ;
2003-09-10 14:50:59 +04:00
hdlr - > warning = xmlParserWarning ;
2003-08-21 02:54:39 +04:00
hdlr - > error = xmlParserError ;
hdlr - > fatalError = xmlParserError ;
2003-09-10 14:50:59 +04:00
return ( 0 ) ;
}
/**
* xmlSAX2InitDefaultSAXHandler :
* @ hdlr : the SAX handler
* @ warning : flag if non - zero sets the handler warning procedure
*
* Initialize the default XML SAX2 handler
*/
void
xmlSAX2InitDefaultSAXHandler ( xmlSAXHandler * hdlr , int warning )
{
if ( ( hdlr = = NULL ) | | ( hdlr - > initialized ! = 0 ) )
return ;
xmlSAXVersion ( hdlr , xmlSAX2DefaultVersionValue ) ;
if ( warning = = 0 )
hdlr - > warning = NULL ;
else
hdlr - > warning = xmlParserWarning ;
2003-08-21 02:54:39 +04:00
}
/**
* xmlDefaultSAXHandlerInit :
*
* Initialize the default SAX2 handler
*/
void
xmlDefaultSAXHandlerInit ( void )
{
2003-09-30 04:43:48 +04:00
# ifdef LIBXML_SAX1_ENABLED
2003-09-25 18:29:29 +04:00
xmlSAXVersion ( ( xmlSAXHandlerPtr ) & xmlDefaultSAXHandler , 1 ) ;
2003-09-30 04:43:48 +04:00
# endif /* LIBXML_SAX1_ENABLED */
2003-08-21 02:54:39 +04:00
}
# ifdef LIBXML_HTML_ENABLED
/**
* xmlSAX2InitHtmlDefaultSAXHandler :
* @ hdlr : the SAX handler
*
* Initialize the default HTML SAX2 handler
*/
void
xmlSAX2InitHtmlDefaultSAXHandler ( xmlSAXHandler * hdlr )
{
2004-11-08 17:02:18 +03:00
if ( ( hdlr = = NULL ) | | ( hdlr - > initialized ! = 0 ) )
2003-08-21 02:54:39 +04:00
return ;
hdlr - > internalSubset = xmlSAX2InternalSubset ;
hdlr - > externalSubset = NULL ;
hdlr - > isStandalone = NULL ;
hdlr - > hasInternalSubset = NULL ;
hdlr - > hasExternalSubset = NULL ;
hdlr - > resolveEntity = NULL ;
hdlr - > getEntity = xmlSAX2GetEntity ;
hdlr - > getParameterEntity = NULL ;
hdlr - > entityDecl = NULL ;
hdlr - > attributeDecl = NULL ;
hdlr - > elementDecl = NULL ;
hdlr - > notationDecl = NULL ;
hdlr - > unparsedEntityDecl = NULL ;
hdlr - > setDocumentLocator = xmlSAX2SetDocumentLocator ;
hdlr - > startDocument = xmlSAX2StartDocument ;
hdlr - > endDocument = xmlSAX2EndDocument ;
hdlr - > startElement = xmlSAX2StartElement ;
hdlr - > endElement = xmlSAX2EndElement ;
hdlr - > reference = NULL ;
hdlr - > characters = xmlSAX2Characters ;
hdlr - > cdataBlock = xmlSAX2CDataBlock ;
hdlr - > ignorableWhitespace = xmlSAX2IgnorableWhitespace ;
2004-10-22 18:34:23 +04:00
hdlr - > processingInstruction = xmlSAX2ProcessingInstruction ;
2003-08-21 02:54:39 +04:00
hdlr - > comment = xmlSAX2Comment ;
hdlr - > warning = xmlParserWarning ;
hdlr - > error = xmlParserError ;
hdlr - > fatalError = xmlParserError ;
2003-09-25 18:29:29 +04:00
hdlr - > initialized = 1 ;
2003-08-21 02:54:39 +04:00
}
/**
* htmlDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
htmlDefaultSAXHandlerInit ( void )
{
2003-09-25 18:29:29 +04:00
xmlSAX2InitHtmlDefaultSAXHandler ( ( xmlSAXHandlerPtr ) & htmlDefaultSAXHandler ) ;
2003-08-21 02:54:39 +04:00
}
# endif /* LIBXML_HTML_ENABLED */
# ifdef LIBXML_DOCB_ENABLED
/**
* xmlSAX2InitDocbDefaultSAXHandler :
* @ hdlr : the SAX handler
*
* Initialize the default DocBook SAX2 handler
*/
void
xmlSAX2InitDocbDefaultSAXHandler ( xmlSAXHandler * hdlr )
{
2004-11-08 17:02:18 +03:00
if ( ( hdlr = = NULL ) | | ( hdlr - > initialized ! = 0 ) )
2003-08-21 02:54:39 +04:00
return ;
hdlr - > internalSubset = xmlSAX2InternalSubset ;
hdlr - > externalSubset = NULL ;
hdlr - > isStandalone = xmlSAX2IsStandalone ;
hdlr - > hasInternalSubset = xmlSAX2HasInternalSubset ;
hdlr - > hasExternalSubset = xmlSAX2HasExternalSubset ;
hdlr - > resolveEntity = xmlSAX2ResolveEntity ;
hdlr - > getEntity = xmlSAX2GetEntity ;
hdlr - > getParameterEntity = NULL ;
hdlr - > entityDecl = xmlSAX2EntityDecl ;
hdlr - > attributeDecl = NULL ;
hdlr - > elementDecl = NULL ;
hdlr - > notationDecl = NULL ;
hdlr - > unparsedEntityDecl = NULL ;
hdlr - > setDocumentLocator = xmlSAX2SetDocumentLocator ;
hdlr - > startDocument = xmlSAX2StartDocument ;
hdlr - > endDocument = xmlSAX2EndDocument ;
hdlr - > startElement = xmlSAX2StartElement ;
hdlr - > endElement = xmlSAX2EndElement ;
hdlr - > reference = xmlSAX2Reference ;
hdlr - > characters = xmlSAX2Characters ;
hdlr - > cdataBlock = NULL ;
hdlr - > ignorableWhitespace = xmlSAX2IgnorableWhitespace ;
hdlr - > processingInstruction = NULL ;
hdlr - > comment = xmlSAX2Comment ;
hdlr - > warning = xmlParserWarning ;
hdlr - > error = xmlParserError ;
hdlr - > fatalError = xmlParserError ;
2003-10-10 18:46:54 +04:00
hdlr - > initialized = 1 ;
2003-08-21 02:54:39 +04:00
}
/**
* docbDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
docbDefaultSAXHandlerInit ( void )
{
2003-09-25 18:29:29 +04:00
xmlSAX2InitDocbDefaultSAXHandler ( ( xmlSAXHandlerPtr ) & docbDefaultSAXHandler ) ;
2003-08-21 02:54:39 +04:00
}
# endif /* LIBXML_DOCB_ENABLED */
2005-04-01 17:11:58 +04:00
# define bottom_SAX2
# include "elfgcchack.h"