1998-08-13 03:39:55 +00:00
/*
* SAX . c : Default SAX handler to build a tree .
1998-10-20 06:14:16 +00:00
*
1999-01-17 19:11:59 +00:00
* See Copyright for the status of this software .
*
1998-10-20 06:14:16 +00:00
* Daniel Veillard < Daniel . Veillard @ w3 . org >
1998-08-13 03:39:55 +00:00
*/
1999-09-22 09:46:25 +00:00
1999-12-22 11:30:41 +00:00
# ifdef WIN32
# include "win32config.h"
# else
# include "config.h"
# endif
1998-08-13 03:39:55 +00:00
# include <stdio.h>
1998-10-01 20:51:15 +00:00
# include <stdlib.h>
2000-07-14 14:49:25 +00:00
# include <string.h>
2000-04-03 19:48:13 +00: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>
2000-10-09 12:30:39 +00:00
# include <libxml/xmlerror.h>
2000-04-03 19:48:13 +00:00
# include <libxml/debugXML.h>
# include <libxml/xmlIO.h>
# include <libxml/SAX.h>
2000-06-28 23:40:59 +00:00
# include <libxml/uri.h>
2000-06-30 18:39:56 +00:00
# include <libxml/HTMLtree.h>
1998-08-13 03:39:55 +00:00
/* #define DEBUG_SAX */
1999-08-29 21:02:19 +00:00
/* #define DEBUG_SAX_TREE */
1998-08-13 03:39:55 +00:00
1998-10-20 06:14:16 +00:00
/**
* getPublicId :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* Return the public ID e . g . " -//SGMLSOURCE//DTD DEMO//EN "
1998-10-20 06:14:16 +00:00
*
1999-09-23 22:19:22 +00:00
* Returns a xmlChar *
1998-08-13 03:39:55 +00:00
*/
1999-09-23 22:19:22 +00:00
const xmlChar *
1999-05-29 11:51:49 +00:00
getPublicId ( void * ctx )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 03:39:55 +00:00
return ( NULL ) ;
}
1998-10-20 06:14:16 +00:00
/**
* getSystemId :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
*
1999-06-02 17:44:04 +00:00
* Return the system ID , basically URL or filename e . g .
1998-10-20 06:14:16 +00:00
* http : //www.sgmlsource.com/dtds/memo.dtd
*
1999-09-23 22:19:22 +00:00
* Returns a xmlChar *
1998-08-13 03:39:55 +00:00
*/
1999-09-23 22:19:22 +00:00
const xmlChar *
1999-05-29 11:51:49 +00:00
getSystemId ( void * ctx )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-08-29 21:02:19 +00:00
return ( BAD_CAST ctxt - > input - > filename ) ;
1998-08-13 03:39:55 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* getLineNumber :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* Return the line number of the current parsing point .
1998-10-20 06:14:16 +00:00
*
1999-02-22 10:33:01 +00:00
* Returns an int
1998-08-13 03:39:55 +00:00
*/
1998-10-20 06:14:16 +00:00
int
1999-05-29 11:51:49 +00:00
getLineNumber ( void * ctx )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 03:39:55 +00:00
return ( ctxt - > input - > line ) ;
}
1998-10-20 06:14:16 +00:00
/**
* getColumnNumber :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* Return the column number of the current parsing point .
1998-10-20 06:14:16 +00:00
*
1999-02-22 10:33:01 +00:00
* Returns an int
1998-08-13 03:39:55 +00:00
*/
1998-10-20 06:14:16 +00:00
int
1999-05-29 11:51:49 +00:00
getColumnNumber ( void * ctx )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 03:39:55 +00:00
return ( ctxt - > input - > col ) ;
}
/*
* The default SAX Locator .
*/
xmlSAXLocator xmlDefaultSAXLocator = {
getPublicId , getSystemId , getLineNumber , getColumnNumber
} ;
1999-04-05 12:20:10 +00:00
/**
* isStandalone :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
*
* Is this document tagged standalone ?
*
* Returns 1 if true
*/
int
1999-05-29 11:51:49 +00:00
isStandalone ( void * ctx )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
return ( ctxt - > myDoc - > standalone = = 1 ) ;
}
/**
* hasInternalSubset :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
*
* Does this document has an internal subset
*
* Returns 1 if true
*/
int
1999-05-29 11:51:49 +00:00
hasInternalSubset ( void * ctx )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
return ( ctxt - > myDoc - > intSubset ! = NULL ) ;
}
/**
* hasExternalSubset :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
*
* Does this document has an external subset
*
* Returns 1 if true
*/
int
1999-05-29 11:51:49 +00:00
hasExternalSubset ( void * ctx )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
return ( ctxt - > myDoc - > extSubset ! = NULL ) ;
}
/**
1999-08-10 19:04:08 +00:00
* internalSubset :
2000-04-24 11:33:38 +00:00
* @ 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 )
1999-04-05 12:20:10 +00:00
*
2000-01-03 11:08:02 +00:00
* Callback on internal subset declaration .
1999-04-05 12:20:10 +00:00
*/
void
1999-09-23 22:19:22 +00:00
internalSubset ( void * ctx , const xmlChar * name ,
const xmlChar * ExternalID , const xmlChar * SystemID )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2000-06-30 18:39:56 +00:00
xmlDtdPtr dtd ;
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.internalSubset(%s, %s, %s) \n " ,
1999-04-05 12:20:10 +00:00
name , ExternalID , SystemID ) ;
# endif
2000-06-30 18:39:56 +00:00
if ( ctxt - > myDoc = = NULL )
return ;
dtd = xmlGetIntSubset ( ctxt - > myDoc ) ;
if ( dtd ! = NULL ) {
2000-08-19 19:52:36 +00:00
if ( ctxt - > html )
return ;
2000-06-30 18:39:56 +00:00
xmlUnlinkNode ( ( xmlNodePtr ) dtd ) ;
xmlFreeDtd ( dtd ) ;
ctxt - > myDoc - > intSubset = NULL ;
}
ctxt - > myDoc - > intSubset =
xmlCreateIntSubset ( ctxt - > myDoc , name , ExternalID , SystemID ) ;
2000-03-14 18:30:20 +00:00
}
/**
* externalSubset :
* @ ctx : the user data ( XML parser context )
2000-04-24 11:33:38 +00:00
* @ name : the root element name
* @ ExternalID : the external ID
* @ SystemID : the SYSTEM ID ( e . g . filename or URL )
2000-03-14 18:30:20 +00:00
*
* Callback on external subset declaration .
*/
void
externalSubset ( void * ctx , const xmlChar * name ,
const xmlChar * ExternalID , const xmlChar * SystemID )
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.externalSubset(%s, %s, %s) \n " ,
2000-03-14 18:30:20 +00:00
name , ExternalID , SystemID ) ;
# endif
1999-08-10 19:04:08 +00:00
if ( ( ( ExternalID ! = NULL ) | | ( SystemID ! = NULL ) ) & &
( ctxt - > validate & & ctxt - > wellFormed & & ctxt - > myDoc ) ) {
/*
* Try to fetch and parse the external subset .
*/
2000-03-14 18:30:20 +00:00
xmlParserInputPtr oldinput ;
int oldinputNr ;
int oldinputMax ;
xmlParserInputPtr * oldinputTab ;
int oldwellFormed ;
1999-08-10 19:04:08 +00:00
xmlParserInputPtr input = NULL ;
xmlCharEncoding enc ;
2000-07-14 14:49:25 +00:00
int oldcharset ;
1999-08-10 19:04:08 +00:00
/*
* Ask the Entity resolver to load the damn thing
*/
2000-03-14 18:30:20 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > resolveEntity ! = NULL ) )
input = ctxt - > sax - > resolveEntity ( ctxt - > userData , ExternalID ,
1999-08-10 19:04:08 +00:00
SystemID ) ;
if ( input = = NULL ) {
return ;
}
2000-03-14 18:30:20 +00:00
xmlNewDtd ( ctxt - > myDoc , name , ExternalID , SystemID ) ;
1999-08-10 19:04:08 +00:00
/*
2000-03-14 18:30:20 +00:00
* make sure we won ' t destroy the main document context
1999-08-10 19:04:08 +00:00
*/
2000-03-14 18:30:20 +00:00
oldinput = ctxt - > input ;
oldinputNr = ctxt - > inputNr ;
oldinputMax = ctxt - > inputMax ;
oldinputTab = ctxt - > inputTab ;
oldwellFormed = ctxt - > wellFormed ;
2000-06-28 23:40:59 +00:00
oldcharset = ctxt - > charset ;
2000-03-14 18:30:20 +00:00
ctxt - > inputTab = ( xmlParserInputPtr * )
xmlMalloc ( 5 * sizeof ( xmlParserInputPtr ) ) ;
if ( ctxt - > inputTab = = NULL ) {
ctxt - > errNo = XML_ERR_NO_MEMORY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" externalSubset: out of memory \n " ) ;
ctxt - > errNo = XML_ERR_NO_MEMORY ;
ctxt - > input = oldinput ;
ctxt - > inputNr = oldinputNr ;
ctxt - > inputMax = oldinputMax ;
ctxt - > inputTab = oldinputTab ;
2000-06-28 23:40:59 +00:00
ctxt - > charset = oldcharset ;
2000-03-14 18:30:20 +00:00
return ;
}
ctxt - > inputNr = 0 ;
ctxt - > inputMax = 5 ;
ctxt - > input = NULL ;
xmlPushInput ( ctxt , input ) ;
/*
* On the fly encoding conversion if needed
*/
enc = xmlDetectCharEncoding ( ctxt - > input - > cur , 4 ) ;
xmlSwitchEncoding ( ctxt , enc ) ;
1999-08-10 19:04:08 +00:00
if ( input - > filename = = NULL )
1999-08-29 21:02:19 +00:00
input - > filename = ( char * ) xmlStrdup ( SystemID ) ;
1999-08-10 19:04:08 +00:00
input - > line = 1 ;
input - > col = 1 ;
2000-03-14 18:30:20 +00:00
input - > base = ctxt - > input - > cur ;
input - > cur = ctxt - > input - > cur ;
1999-08-10 19:04:08 +00:00
input - > free = NULL ;
/*
* let ' s parse that entity knowing it ' s an external subset .
*/
2000-03-14 18:30:20 +00:00
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 ;
2000-06-28 23:40:59 +00:00
ctxt - > charset = oldcharset ;
2000-03-14 18:30:20 +00:00
/* ctxt->wellFormed = oldwellFormed; */
1999-06-02 17:44:04 +00:00
}
1999-04-05 12:20:10 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* resolveEntity :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
2000-01-03 11:08:02 +00:00
* The entity loader , to control the loading of external entities ,
* the application can either :
* - override this resolveEntity ( ) callback in the SAX block
* - or better use the xmlSetExternalEntityLoader ( ) function to
* set up it ' s own entity resolution routine
1998-10-20 06:14:16 +00:00
*
1999-02-22 10:33:01 +00:00
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour .
1998-08-13 03:39:55 +00:00
*/
1998-10-20 06:14:16 +00:00
xmlParserInputPtr
1999-09-23 22:19:22 +00:00
resolveEntity ( void * ctx , const xmlChar * publicId , const xmlChar * systemId )
1998-10-20 06:14:16 +00:00
{
1999-06-02 17:44:04 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2000-09-10 16:14:55 +00:00
xmlParserInputPtr ret ;
2000-09-17 16:00:22 +00:00
xmlChar * URI ;
2000-09-10 16:14:55 +00:00
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
2000-09-17 16:00:22 +00:00
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.resolveEntity(%s, %s) \n " , publicId , systemId ) ;
1998-08-13 03:39:55 +00:00
# endif
1998-10-27 06:21:04 +00:00
2000-09-10 16:14:55 +00:00
ret = xmlLoadExternalEntity ( ( const char * ) URI ,
( const char * ) publicId , ctxt ) ;
if ( URI ! = NULL )
xmlFree ( URI ) ;
return ( ret ) ;
1998-08-13 03:39:55 +00:00
}
1999-04-05 12:20:10 +00:00
/**
* getEntity :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ name : The entity name
*
* Get an entity by name
*
1999-06-02 17:44:04 +00:00
* Returns the xmlEntityPtr if found .
1999-04-05 12:20:10 +00:00
*/
xmlEntityPtr
1999-09-23 22:19:22 +00:00
getEntity ( void * ctx , const xmlChar * name )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlEntityPtr ret ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.getEntity(%s) \n " , name ) ;
1999-04-05 12:20:10 +00:00
# endif
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
2000-08-12 21:12:04 +00:00
if ( ( ret ! = NULL ) & & ( ctxt - > validate ) & & ( ret - > children = = NULL ) & &
( ret - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY ) ) {
/*
* for validation purposes we really need to fetch and
* parse the external entity
*/
int parse ;
xmlNodePtr children ;
parse = xmlParseCtxtExternalEntity ( ctxt ,
ret - > SystemID , ret - > ExternalID , & children ) ;
xmlAddChildList ( ( xmlNodePtr ) ret , children ) ;
}
1999-04-05 12:20:10 +00:00
return ( ret ) ;
}
1999-08-10 19:04:08 +00:00
/**
* getParameterEntity :
* @ ctx : the user data ( XML parser context )
* @ name : The entity name
*
* Get a parameter entity by name
*
* Returns the xmlEntityPtr if found .
*/
xmlEntityPtr
1999-09-23 22:19:22 +00:00
getParameterEntity ( void * ctx , const xmlChar * name )
1999-08-10 19:04:08 +00:00
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlEntityPtr ret ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.getParameterEntity(%s) \n " , name ) ;
1999-08-10 19:04:08 +00:00
# endif
ret = xmlGetParameterEntity ( ctxt - > myDoc , name ) ;
return ( ret ) ;
}
1999-04-05 12:20:10 +00:00
/**
* entityDecl :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ 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
1999-09-23 22:19:22 +00:00
entityDecl ( void * ctx , const xmlChar * name , int type ,
const xmlChar * publicId , const xmlChar * systemId , xmlChar * content )
1999-04-05 12:20:10 +00:00
{
2000-08-26 21:40:43 +00:00
xmlEntityPtr ent ;
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.entityDecl(%s, %d, %s, %s, %s) \n " ,
1999-04-05 12:20:10 +00:00
name , type , publicId , systemId , content ) ;
# endif
2000-08-26 21:40:43 +00:00
if ( ctxt - > inSubset = = 1 ) {
ent = xmlAddDocEntity ( ctxt - > myDoc , name , type , publicId ,
2000-03-14 18:30:20 +00:00
systemId , content ) ;
2000-08-26 21:40:43 +00:00
if ( ( ent = = NULL ) & & ( ctxt - > pedantic ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt ,
" Entity(%s) already defined in the internal subset \n " , name ) ;
2000-09-10 16:14:55 +00:00
if ( ( ent ! = NULL ) & & ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
2000-09-17 16:00:22 +00:00
xmlChar * URI ;
2000-09-10 16:14:55 +00:00
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
2000-09-17 16:00:22 +00:00
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
2000-09-10 16:14:55 +00:00
ent - > URI = URI ;
}
2000-08-26 21:40:43 +00:00
} else if ( ctxt - > inSubset = = 2 ) {
ent = xmlAddDtdEntity ( ctxt - > myDoc , name , type , publicId ,
2000-03-14 18:30:20 +00:00
systemId , content ) ;
2000-08-26 21:40:43 +00:00
if ( ( ent = = NULL ) & & ( ctxt - > pedantic ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt ,
" Entity(%s) already defined in the external subset \n " , name ) ;
2000-09-10 16:14:55 +00:00
if ( ( ent ! = NULL ) & & ( ent - > URI = = NULL ) & & ( systemId ! = NULL ) ) {
2000-09-17 16:00:22 +00:00
xmlChar * URI ;
2000-09-10 16:14:55 +00:00
const char * base = NULL ;
if ( ctxt - > input ! = NULL )
base = ctxt - > input - > filename ;
if ( base = = NULL )
base = ctxt - > directory ;
2000-09-17 16:00:22 +00:00
URI = xmlBuildURI ( systemId , ( const xmlChar * ) base ) ;
2000-09-10 16:14:55 +00:00
ent - > URI = URI ;
}
2000-08-26 21:40:43 +00:00
} else {
2000-03-14 18:30:20 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" SAX.entityDecl(%s) called while not in subset \n " , name ) ;
}
1999-04-05 12:20:10 +00:00
}
/**
* attributeDecl :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
2000-04-24 11:33:38 +00:00
* @ elem : the name of the element
2000-03-14 18:30:20 +00:00
* @ fullname : the attribute name
1999-04-05 12:20:10 +00:00
* @ type : the attribute type
2000-04-24 11:33:38 +00:00
* @ def : the type of default value
* @ defaultValue : the attribute default value
* @ tree : the tree of enumerated value set
1999-04-05 12:20:10 +00:00
*
* An attribute definition has been parsed
*/
void
2000-03-14 18:30:20 +00:00
attributeDecl ( void * ctx , const xmlChar * elem , const xmlChar * fullname ,
1999-09-23 22:19:22 +00:00
int type , int def , const xmlChar * defaultValue ,
1999-04-05 12:20:10 +00:00
xmlEnumerationPtr tree )
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-08-10 19:04:08 +00:00
xmlAttributePtr attr ;
2000-03-14 18:30:20 +00:00
xmlChar * name = NULL , * prefix = NULL ;
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.attributeDecl(%s, %s, %d, %d, %s, ...) \n " ,
2000-03-14 18:30:20 +00:00
elem , fullname , type , def , defaultValue ) ;
1999-04-05 12:20:10 +00:00
# endif
2000-03-14 18:30:20 +00:00
name = xmlSplitQName ( ctxt , fullname , & prefix ) ;
if ( ctxt - > inSubset = = 1 )
attr = xmlAddAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , elem ,
2000-07-14 14:49:25 +00:00
name , prefix , ( xmlAttributeType ) type ,
( xmlAttributeDefault ) def , defaultValue , tree ) ;
2000-03-14 18:30:20 +00:00
else if ( ctxt - > inSubset = = 2 )
attr = xmlAddAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset , elem ,
2000-07-14 14:49:25 +00:00
name , prefix , ( xmlAttributeType ) type ,
( xmlAttributeDefault ) def , defaultValue , tree ) ;
2000-03-14 18:30:20 +00:00
else {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" SAX.attributeDecl(%s) called while not in subset \n " , name ) ;
return ;
}
1999-08-10 19:04:08 +00:00
if ( attr = = 0 ) ctxt - > valid = 0 ;
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateAttributeDecl ( & ctxt - > vctxt , ctxt - > myDoc ,
attr ) ;
2000-03-14 18:30:20 +00:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
if ( name ! = NULL )
xmlFree ( name ) ;
1999-04-05 12:20:10 +00:00
}
/**
* elementDecl :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ name : the element name
* @ type : the element type
2000-04-24 11:33:38 +00:00
* @ content : the element value tree
1999-04-05 12:20:10 +00:00
*
* An element definition has been parsed
*/
void
1999-09-23 22:19:22 +00:00
elementDecl ( void * ctx , const xmlChar * name , int type ,
1999-04-05 12:20:10 +00:00
xmlElementContentPtr content )
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2000-03-14 18:30:20 +00:00
xmlElementPtr elem = NULL ;
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.elementDecl(%s, %d, ...) \n " ,
2000-03-14 18:30:20 +00:00
fullname , type ) ;
1999-04-05 12:20:10 +00:00
# endif
1999-08-10 19:04:08 +00:00
2000-03-14 18:30:20 +00:00
if ( ctxt - > inSubset = = 1 )
elem = xmlAddElementDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset ,
2000-07-14 14:49:25 +00:00
name , ( xmlElementTypeVal ) type , content ) ;
2000-03-14 18:30:20 +00:00
else if ( ctxt - > inSubset = = 2 )
elem = xmlAddElementDecl ( & ctxt - > vctxt , ctxt - > myDoc - > extSubset ,
2000-07-14 14:49:25 +00:00
name , ( xmlElementTypeVal ) type , content ) ;
2000-03-14 18:30:20 +00:00
else {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" SAX.elementDecl(%s) called while not in subset \n " , name ) ;
return ;
}
if ( elem = = NULL ) ctxt - > valid = 0 ;
1999-08-10 19:04:08 +00:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateElementDecl ( & ctxt - > vctxt , ctxt - > myDoc , elem ) ;
1999-04-05 12:20:10 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* notationDecl :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
* @ name : The name of the notation
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
1998-08-13 03:39:55 +00:00
* What to do when a notation declaration has been parsed .
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
notationDecl ( void * ctx , const xmlChar * name ,
const xmlChar * publicId , const xmlChar * systemId )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
2000-03-14 18:30:20 +00:00
xmlNotationPtr nota = NULL ;
1999-08-10 19:04:08 +00:00
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.notationDecl(%s, %s, %s) \n " , name , publicId , systemId ) ;
1998-08-13 03:39:55 +00:00
# endif
1999-08-10 19:04:08 +00:00
2000-03-14 18:30:20 +00:00
if ( ctxt - > inSubset = = 1 )
nota = xmlAddNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , name ,
1999-08-10 19:04:08 +00:00
publicId , systemId ) ;
2000-03-14 18:30:20 +00:00
else if ( ctxt - > inSubset = = 2 )
nota = xmlAddNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc - > intSubset , name ,
publicId , systemId ) ;
else {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" SAX.notationDecl(%s) called while not in subset \n " , name ) ;
return ;
}
if ( nota = = NULL ) ctxt - > valid = 0 ;
1999-08-10 19:04:08 +00:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateNotationDecl ( & ctxt - > vctxt , ctxt - > myDoc ,
nota ) ;
1998-08-13 03:39:55 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* unparsedEntityDecl :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
* @ 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
*
1998-08-13 03:39:55 +00:00
* What to do when an unparsed entity declaration is parsed
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
unparsedEntityDecl ( void * ctx , const xmlChar * name ,
const xmlChar * publicId , const xmlChar * systemId ,
const xmlChar * notationName )
1998-10-20 06:14:16 +00:00
{
1999-08-29 21:02:19 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.unparsedEntityDecl(%s, %s, %s, %s) \n " ,
1998-08-13 03:39:55 +00:00
name , publicId , systemId , notationName ) ;
# endif
1999-08-29 21:02:19 +00:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateNotationUse ( & ctxt - > vctxt , ctxt - > myDoc ,
notationName ) ;
xmlAddDocEntity ( ctxt - > myDoc , name ,
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ,
publicId , systemId , notationName ) ;
1998-08-13 03:39:55 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* setDocumentLocator :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
* @ loc : A SAX Locator
*
1998-08-13 03:39:55 +00:00
* Receive the document locator at startup , actually xmlDefaultSAXLocator
* Everything is available on the context , so this is useless in our case .
*/
1998-10-20 06:14:16 +00:00
void
1999-05-29 11:51:49 +00:00
setDocumentLocator ( void * ctx , xmlSAXLocatorPtr loc )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.setDocumentLocator() \n " ) ;
1998-08-13 03:39:55 +00:00
# endif
}
1998-10-20 06:14:16 +00:00
/**
* startDocument :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* called when the document start being processed .
*/
1998-10-20 06:14:16 +00:00
void
1999-05-29 11:51:49 +00:00
startDocument ( void * ctx )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlDocPtr doc ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.startDocument() \n " ) ;
1998-08-13 03:39:55 +00:00
# endif
2000-06-30 17:58:25 +00:00
if ( ctxt - > html ) {
if ( ctxt - > myDoc = = NULL )
2000-08-12 21:12:04 +00:00
# ifdef LIBXML_HTML_ENABLED
2000-08-19 19:52:36 +00:00
ctxt - > myDoc = htmlNewDocNoDtD ( NULL , NULL ) ;
2000-08-12 21:12:04 +00:00
# else
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" libxml2 built without HTML support \n " ) ;
2000-08-12 21:12:04 +00:00
# endif
2000-06-30 17:58:25 +00:00
} else {
doc = ctxt - > myDoc = xmlNewDoc ( ctxt - > version ) ;
if ( doc ! = NULL ) {
if ( ctxt - > encoding ! = NULL )
doc - > encoding = xmlStrdup ( ctxt - > encoding ) ;
else
doc - > encoding = NULL ;
doc - > standalone = ctxt - > standalone ;
}
1999-04-05 12:20:10 +00:00
}
2000-08-12 21:12:04 +00:00
if ( ( ctxt - > myDoc ! = NULL ) & & ( ctxt - > myDoc - > URL = = NULL ) & &
( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ! = NULL ) ) {
ctxt - > myDoc - > URL = xmlStrdup ( ( xmlChar * ) ctxt - > input - > filename ) ;
}
1998-08-13 03:39:55 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* endDocument :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* called when the document end has been detected .
*/
1998-10-20 06:14:16 +00:00
void
1999-05-29 11:51:49 +00:00
endDocument ( void * ctx )
1998-10-20 06:14:16 +00:00
{
1999-09-08 21:35:25 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.endDocument() \n " ) ;
1998-08-13 03:39:55 +00:00
# endif
1999-09-08 21:35:25 +00:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateDocumentFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 14:20:55 +00: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 ;
}
2000-06-28 23:40:59 +00:00
if ( ( ctxt - > inputTab [ 0 ] - > encoding ! = NULL ) & & ( ctxt - > myDoc ! = NULL ) & &
( 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 ;
}
1998-08-13 03:39:55 +00:00
}
1999-04-05 12:20:10 +00:00
/**
* attribute :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
2000-04-24 11:33:38 +00:00
* @ fullname : The attribute name , including namespace prefix
1999-04-05 12:20:10 +00:00
* @ value : 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 .
*/
void
1999-09-23 22:19:22 +00:00
attribute ( void * ctx , const xmlChar * fullname , const xmlChar * value )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlAttrPtr ret ;
1999-09-23 22:19:22 +00:00
xmlChar * name ;
xmlChar * ns ;
2000-03-14 18:30:20 +00:00
xmlChar * nval ;
1999-08-29 21:02:19 +00:00
xmlNsPtr namespace ;
1999-04-05 12:20:10 +00:00
/****************
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.attribute(%s, %s) \n " , fullname , value ) ;
1999-04-05 12:20:10 +00:00
# endif
* * * * * * * * * * * * * * * */
/*
* Split the full name into a namespace prefix and the tag name
*/
2000-03-14 18:30:20 +00:00
name = xmlSplitQName ( ctxt , fullname , & ns ) ;
/*
2000-10-15 14:24:25 +00:00
* Do the last stage of the attribute normalization
* Needed for HTML too :
* http : //www.w3.org/TR/html4/types.html#h-6.2
2000-03-14 18:30:20 +00:00
*/
2000-10-15 14:24:25 +00:00
nval = xmlValidNormalizeAttributeValue ( ctxt - > myDoc , ctxt - > node ,
fullname , value ) ;
2000-03-14 18:30:20 +00:00
if ( nval ! = NULL )
value = nval ;
1999-04-05 12:20:10 +00:00
/*
* Check whether it ' s a namespace definition
*/
2000-06-28 23:40:59 +00:00
if ( ( ! ctxt - > html ) & & ( ns = = NULL ) & &
1999-04-05 12:20:10 +00:00
( name [ 0 ] = = ' x ' ) & & ( name [ 1 ] = = ' m ' ) & & ( name [ 2 ] = = ' l ' ) & &
( name [ 3 ] = = ' n ' ) & & ( name [ 4 ] = = ' s ' ) & & ( name [ 5 ] = = 0 ) ) {
2000-06-28 23:40:59 +00:00
xmlURIPtr uri ;
uri = xmlParseURI ( ( const char * ) value ) ;
if ( uri = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" nmlns: %s not a valid URI \n " , value ) ;
} else {
if ( uri - > scheme = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" nmlns: URI %s is not absolute \n " , value ) ;
}
xmlFreeURI ( uri ) ;
}
1999-04-05 12:20:10 +00:00
/* a default namespace definition */
xmlNewNs ( ctxt - > node , value , NULL ) ;
if ( name ! = NULL )
1999-09-02 22:04:43 +00:00
xmlFree ( name ) ;
2000-03-14 18:30:20 +00:00
if ( nval ! = NULL )
xmlFree ( nval ) ;
1999-04-05 12:20:10 +00:00
return ;
}
2000-06-28 23:40:59 +00:00
if ( ( ! ctxt - > html ) & &
( ns ! = NULL ) & & ( ns [ 0 ] = = ' x ' ) & & ( ns [ 1 ] = = ' m ' ) & & ( ns [ 2 ] = = ' l ' ) & &
1999-04-05 12:20:10 +00:00
( ns [ 3 ] = = ' n ' ) & & ( ns [ 4 ] = = ' s ' ) & & ( ns [ 5 ] = = 0 ) ) {
2000-03-14 18:30:20 +00:00
/*
* Validate also for namespace decls , they are attributes from
* an XML - 1.0 perspective
TODO . . . doesn ' t map well with current API
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt , ctxt - > myDoc ,
ctxt - > node , ret , value ) ;
*/
1999-04-05 12:20:10 +00:00
/* a standard namespace definition */
xmlNewNs ( ctxt - > node , value , name ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ns ) ;
1999-04-05 12:20:10 +00:00
if ( name ! = NULL )
1999-09-02 22:04:43 +00:00
xmlFree ( name ) ;
2000-03-14 18:30:20 +00:00
if ( nval ! = NULL )
xmlFree ( nval ) ;
1999-04-05 12:20:10 +00:00
return ;
}
1999-12-21 15:35:29 +00:00
if ( ns ! = NULL )
namespace = xmlSearchNs ( ctxt - > myDoc , ctxt - > node , ns ) ;
else {
namespace = NULL ;
}
1999-08-29 21:02:19 +00:00
/* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
ret = xmlNewNsProp ( ctxt - > node , namespace , name , NULL ) ;
1999-08-10 19:04:08 +00:00
1999-08-29 21:02:19 +00:00
if ( ret ! = NULL ) {
2000-03-14 18:30:20 +00:00
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 ;
}
2000-06-28 23:40:59 +00:00
} else if ( value ! = NULL ) {
2000-03-14 18:30:20 +00:00
ret - > children = xmlNewDocText ( ctxt - > myDoc , value ) ;
ret - > last = ret - > children ;
if ( ret - > children ! = NULL )
ret - > children - > parent = ( xmlNodePtr ) ret ;
}
1999-08-29 21:02:19 +00:00
}
1999-08-10 19:04:08 +00:00
2000-06-28 23:40:59 +00:00
if ( ( ! ctxt - > html ) & & ctxt - > validate & & ctxt - > wellFormed & &
2000-03-14 18:30:20 +00:00
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 {
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt ,
ctxt - > myDoc , ctxt - > node , ret , val ) ;
xmlFree ( val ) ;
}
} else {
ctxt - > valid & = xmlValidateOneAttribute ( & ctxt - > vctxt , ctxt - > myDoc ,
1999-08-10 19:04:08 +00:00
ctxt - > node , ret , value ) ;
2000-03-14 18:30:20 +00:00
}
} else {
1999-08-29 21:02:19 +00:00
/*
* when validating , the ID registration is done at the attribute
* validation level . Otherwise we have to do specific handling here .
*/
if ( xmlIsID ( ctxt - > myDoc , ctxt - > node , ret ) )
xmlAddID ( & ctxt - > vctxt , ctxt - > myDoc , value , ret ) ;
1999-09-08 21:35:25 +00:00
else if ( xmlIsRef ( ctxt - > myDoc , ctxt - > node , ret ) )
xmlAddRef ( & ctxt - > vctxt , ctxt - > myDoc , value , ret ) ;
1999-08-29 21:02:19 +00:00
}
1999-08-10 19:04:08 +00:00
2000-03-14 18:30:20 +00:00
if ( nval ! = NULL )
xmlFree ( nval ) ;
1999-04-05 12:20:10 +00:00
if ( name ! = NULL )
1999-09-02 22:04:43 +00:00
xmlFree ( name ) ;
1999-04-05 12:20:10 +00:00
if ( ns ! = NULL )
1999-09-02 22:04:43 +00:00
xmlFree ( ns ) ;
1999-04-05 12:20:10 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* startElement :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
2000-04-24 11:33:38 +00:00
* @ fullname : The element name , including namespace prefix
1999-04-05 12:20:10 +00:00
* @ atts : An array of name / value attributes pairs , NULL terminated
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* called when an opening tag has been processed .
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
startElement ( void * ctx , const xmlChar * fullname , const xmlChar * * atts )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlNodePtr ret ;
xmlNodePtr parent = ctxt - > node ;
xmlNsPtr ns ;
1999-09-23 22:19:22 +00:00
xmlChar * name ;
xmlChar * prefix ;
const xmlChar * att ;
const xmlChar * value ;
1999-04-05 12:20:10 +00:00
int i ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.startElement(%s) \n " , fullname ) ;
1998-08-13 03:39:55 +00:00
# endif
1999-09-22 09:46:25 +00: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 ) ) ) ) {
if ( ctxt - > vctxt . error ! = NULL ) {
ctxt - > vctxt . error ( ctxt - > vctxt . userData ,
" Validation failed: no DTD found ! \n " ) ;
}
ctxt - > validate = 0 ;
}
1999-04-05 12:20:10 +00:00
/*
* Split the full name into a namespace prefix and the tag name
*/
2000-03-14 18:30:20 +00:00
name = xmlSplitQName ( ctxt , fullname , & prefix ) ;
1999-04-05 12:20:10 +00:00
/*
* 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 = xmlNewDocNode ( ctxt - > myDoc , NULL , name , NULL ) ;
if ( ret = = NULL ) return ;
2000-03-14 18:30:20 +00:00
if ( ctxt - > myDoc - > children = = NULL ) {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " Setting %s as root \n " , name ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
1999-08-29 21:02:19 +00:00
} else if ( parent = = NULL ) {
2000-03-14 18:30:20 +00:00
parent = ctxt - > myDoc - > children ;
1999-08-29 21:02:19 +00:00
}
2000-06-28 23:40:59 +00:00
ctxt - > nodemem = - 1 ;
1999-04-05 12:20:10 +00:00
/*
* We are parsing a new node .
*/
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " pushing(%s) \n " , name ) ;
1999-08-29 21:02:19 +00:00
# endif
1999-04-05 12:20:10 +00:00
nodePush ( ctxt , ret ) ;
/*
* Link the child element
*/
1999-08-29 21:02:19 +00:00
if ( parent ! = NULL ) {
if ( parent - > type = = XML_ELEMENT_NODE ) {
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" adding child %s to %s \n " , name , parent - > name ) ;
1999-08-29 21:02:19 +00:00
# endif
xmlAddChild ( parent , ret ) ;
} else {
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" adding sibling %s to " , name ) ;
1999-08-29 21:02:19 +00:00
xmlDebugDumpOneNode ( stderr , parent , 0 ) ;
# endif
xmlAddSibling ( parent , ret ) ;
}
}
/*
* process all the attributes whose name start with " xml "
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
2000-06-28 23:40:59 +00:00
if ( ! ctxt - > html ) {
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
if ( ( att [ 0 ] = = ' x ' ) & & ( att [ 1 ] = = ' m ' ) & & ( att [ 2 ] = = ' l ' ) )
attribute ( ctxt , att , value ) ;
1999-08-29 21:02:19 +00:00
2000-06-28 23:40:59 +00:00
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
1999-08-29 21:02:19 +00:00
}
}
1999-04-05 12:20:10 +00:00
2000-06-28 23:40:59 +00:00
/*
* 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 ) ;
2000-08-27 21:12:29 +00:00
if ( ( prefix ! = NULL ) & & ( ns = = NULL ) ) {
ns = xmlNewNs ( ret , NULL , prefix ) ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" Namespace prefix %s is not defined \n " , prefix ) ;
}
2000-06-28 23:40:59 +00:00
xmlSetNs ( ret , ns ) ;
1999-04-05 12:20:10 +00:00
/*
1999-08-29 21:02:19 +00:00
* process all the other attributes
1999-04-05 12:20:10 +00:00
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
2000-06-28 23:40:59 +00:00
if ( ctxt - > html ) {
while ( att ! = NULL ) {
1999-08-29 21:02:19 +00:00
attribute ( ctxt , att , value ) ;
2000-06-28 23:40:59 +00:00
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
} else {
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
if ( ( att [ 0 ] ! = ' x ' ) | | ( att [ 1 ] ! = ' m ' ) | | ( att [ 2 ] ! = ' l ' ) )
attribute ( ctxt , att , value ) ;
/*
* Next ones
*/
att = atts [ i + + ] ;
value = atts [ i + + ] ;
}
1999-04-05 12:20:10 +00:00
}
}
/*
2000-06-28 23:40:59 +00:00
* If it ' s the Document root , finish the Dtd validation and
* check the document root element for validity
1999-04-05 12:20:10 +00:00
*/
2000-06-28 23:40:59 +00:00
if ( ( ctxt - > validate ) & & ( ctxt - > vctxt . finishDtd = = 0 ) ) {
ctxt - > valid & = xmlValidateDtdFinal ( & ctxt - > vctxt , ctxt - > myDoc ) ;
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
ctxt - > vctxt . finishDtd = 1 ;
}
1999-04-05 12:20:10 +00:00
if ( prefix ! = NULL )
1999-09-02 22:04:43 +00:00
xmlFree ( prefix ) ;
1999-04-05 12:20:10 +00:00
if ( name ! = NULL )
1999-09-02 22:04:43 +00:00
xmlFree ( name ) ;
1999-04-05 12:20:10 +00:00
1998-08-13 03:39:55 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* endElement :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
* @ name : The element name
*
1998-08-13 03:39:55 +00:00
* called when the end of an element has been detected .
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
endElement ( void * ctx , const xmlChar * name )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlParserNodeInfo node_info ;
xmlNodePtr cur = ctxt - > node ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
1999-04-05 12:20:10 +00:00
if ( name = = NULL )
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " SAX.endElement(NULL) \n " ) ;
1999-04-05 12:20:10 +00:00
else
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " SAX.endElement(%s) \n " , name ) ;
1998-08-13 03:39:55 +00:00
# endif
1999-04-05 12:20:10 +00:00
/* Capture end position and add node */
if ( cur ! = NULL & & ctxt - > record_info ) {
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 ) ;
}
2000-06-28 23:40:59 +00:00
ctxt - > nodemem = - 1 ;
1999-04-05 12:20:10 +00:00
1999-08-10 19:04:08 +00:00
if ( ctxt - > validate & & ctxt - > wellFormed & &
ctxt - > myDoc & & ctxt - > myDoc - > intSubset )
ctxt - > valid & = xmlValidateOneElement ( & ctxt - > vctxt , ctxt - > myDoc ,
cur ) ;
1999-04-05 12:20:10 +00:00
/*
* end of parsing of this node .
*/
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " popping(%s) \n " , cur - > name ) ;
1999-08-29 21:02:19 +00:00
# endif
1999-04-05 12:20:10 +00:00
nodePop ( ctxt ) ;
1998-08-13 03:39:55 +00:00
}
1998-10-24 18:27:49 +00:00
/**
1999-04-05 12:20:10 +00:00
* reference :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ name : The entity name
1998-10-24 18:27:49 +00:00
*
1999-04-05 12:20:10 +00:00
* called when an entity reference is detected .
1998-10-24 18:27:49 +00:00
*/
void
1999-09-23 22:19:22 +00:00
reference ( void * ctx , const xmlChar * name )
1998-10-24 18:27:49 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlNodePtr ret ;
1998-10-24 18:27:49 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.reference(%s) \n " , name ) ;
1998-10-24 18:27:49 +00:00
# endif
2000-03-14 18:30:20 +00:00
if ( name [ 0 ] = = ' # ' )
ret = xmlNewCharRef ( ctxt - > myDoc , name ) ;
else
ret = xmlNewReference ( ctxt - > myDoc , name ) ;
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" add reference %s to %s \n " , name , ctxt - > node - > name ) ;
1999-08-29 21:02:19 +00:00
# endif
1999-04-05 12:20:10 +00:00
xmlAddChild ( ctxt - > node , ret ) ;
1998-10-24 18:27:49 +00:00
}
1998-10-20 06:14:16 +00:00
/**
* characters :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-09-23 22:19:22 +00:00
* @ ch : a xmlChar string
* @ len : the number of xmlChar
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* receiving some chars from the parser .
* Question : how much at a time ? ? ?
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
characters ( void * ctx , const xmlChar * ch , int len )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 03:39:55 +00:00
xmlNodePtr lastChild ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.characters(%.30s, %d) \n " , ch , len ) ;
1998-08-13 03:39:55 +00:00
# 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 .
*/
1999-10-25 13:15:52 +00:00
if ( ctxt - > node = = NULL ) {
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" add chars: ctxt->node == NULL ! \n " ) ;
1999-10-25 13:15:52 +00:00
# endif
return ;
}
1998-08-13 03:39:55 +00:00
lastChild = xmlGetLastChild ( ctxt - > node ) ;
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" add chars to %s \n " , ctxt - > node - > name ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-06-28 23:40:59 +00:00
/*
* Here we needed an accelerator mechanism in case of very large
* elements . Use an attribute in the structure ! ! !
*/
if ( lastChild = = NULL ) {
/* first node, first time */
1999-04-05 12:20:10 +00:00
xmlNodeAddContentLen ( ctxt - > node , ch , len ) ;
2000-06-28 23:40:59 +00:00
# ifndef XML_USE_BUFFER_CONTENT
if ( ctxt - > node - > children ! = NULL ) {
ctxt - > nodelen = len ;
ctxt - > nodemem = len + 1 ;
}
# endif
} else {
2000-08-27 21:12:29 +00:00
if ( ( xmlNodeIsText ( lastChild ) ) & & ( ctxt - > nodemem ! = 0 ) ) {
2000-06-28 23:40:59 +00:00
# ifndef XML_USE_BUFFER_CONTENT
/*
* The whole point of maintaining nodelen and nodemem ,
* xmlTextConcat is too costly , i . e . compute lenght ,
* reallocate a new buffer , move data , append ch . Here
* We try to minimaze realloc ( ) uses and avoid copying
* and recomputing lenght over and over .
*/
if ( ctxt - > nodelen + len > = ctxt - > nodemem ) {
xmlChar * newbuf ;
int size ;
size = ctxt - > nodemem + len ;
size * = 2 ;
newbuf = ( xmlChar * ) xmlRealloc ( lastChild - > content , size ) ;
if ( newbuf = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" SAX.characters(): out of memory \n " ) ;
return ;
}
ctxt - > nodemem = size ;
lastChild - > content = newbuf ;
}
memcpy ( & lastChild - > content [ ctxt - > nodelen ] , ch , len ) ;
ctxt - > nodelen + = len ;
lastChild - > content [ ctxt - > nodelen ] = 0 ;
# else
1999-04-05 12:20:10 +00:00
xmlTextConcat ( lastChild , ch , len ) ;
2000-06-28 23:40:59 +00:00
# endif
} else {
/* Mixed content, first time */
1999-04-05 12:20:10 +00:00
lastChild = xmlNewTextLen ( ch , len ) ;
1998-08-13 03:39:55 +00:00
xmlAddChild ( ctxt - > node , lastChild ) ;
2000-06-28 23:40:59 +00:00
# ifndef XML_USE_BUFFER_CONTENT
if ( ctxt - > node - > children ! = NULL ) {
ctxt - > nodelen = len ;
ctxt - > nodemem = len + 1 ;
}
# endif
1998-08-13 03:39:55 +00:00
}
}
}
1998-10-20 06:14:16 +00:00
/**
* ignorableWhitespace :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-09-23 22:19:22 +00:00
* @ ch : a xmlChar string
* @ len : the number of xmlChar
1998-10-20 06:14:16 +00:00
*
1998-08-13 03:39:55 +00:00
* receiving some ignorable whitespaces from the parser .
* Question : how much at a time ? ? ?
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
ignorableWhitespace ( void * ctx , const xmlChar * ch , int len )
1998-10-20 06:14:16 +00:00
{
1999-05-29 11:51:49 +00:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.ignorableWhitespace(%.30s, %d) \n " , ch , len ) ;
1998-08-13 03:39:55 +00:00
# endif
}
1998-10-20 06:14:16 +00:00
/**
* processingInstruction :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1998-10-20 06:14:16 +00:00
* @ target : the target name
* @ data : the PI data ' s
*
* A processing instruction has been parsed .
1998-08-13 03:39:55 +00:00
*/
1998-10-20 06:14:16 +00:00
void
1999-09-23 22:19:22 +00:00
processingInstruction ( void * ctx , const xmlChar * target ,
const xmlChar * data )
1998-10-20 06:14:16 +00:00
{
1999-08-29 21:02:19 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
xmlNodePtr ret ;
xmlNodePtr parent = ctxt - > node ;
1998-08-13 03:39:55 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.processingInstruction(%s, %s) \n " , target , data ) ;
1998-08-13 03:39:55 +00:00
# endif
1999-08-29 21:02:19 +00:00
ret = xmlNewPI ( target , data ) ;
if ( ret = = NULL ) return ;
2000-03-14 18:30:20 +00:00
parent = ctxt - > node ;
if ( ctxt - > inSubset = = 1 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > intSubset , ret ) ;
return ;
} else if ( ctxt - > inSubset = = 2 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > extSubset , ret ) ;
return ;
}
if ( ( ctxt - > myDoc - > children = = NULL ) | | ( parent = = NULL ) ) {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" Setting PI %s as root \n " , target ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
return ;
1999-08-29 21:02:19 +00:00
}
2000-03-14 18:30:20 +00:00
if ( parent - > type = = XML_ELEMENT_NODE ) {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" adding PI %s child to %s \n " , target , parent - > name ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddChild ( parent , ret ) ;
} else {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" adding PI %s sibling to " , target ) ;
2000-03-14 18:30:20 +00:00
xmlDebugDumpOneNode ( stderr , parent , 0 ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddSibling ( parent , ret ) ;
1999-08-29 21:02:19 +00:00
}
1998-08-13 03:39:55 +00:00
}
1999-04-05 12:20:10 +00:00
/**
* globalNamespace :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ href : the namespace associated URN
* @ prefix : the namespace prefix
*
* An old global namespace has been parsed .
*/
void
1999-09-23 22:19:22 +00:00
globalNamespace ( void * ctx , const xmlChar * href , const xmlChar * prefix )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.globalNamespace(%s, %s) \n " , href , prefix ) ;
1999-04-05 12:20:10 +00:00
# endif
xmlNewGlobalNs ( ctxt - > myDoc , href , prefix ) ;
}
/**
* setNamespace :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ name : the namespace prefix
*
* Set the current element namespace .
*/
2000-04-24 11:33:38 +00:00
1999-04-05 12:20:10 +00:00
void
1999-09-23 22:19:22 +00:00
setNamespace ( void * ctx , const xmlChar * name )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlNsPtr ns ;
xmlNodePtr parent ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " SAX.setNamespace(%s) \n " , name ) ;
1999-04-05 12:20:10 +00:00
# endif
ns = xmlSearchNs ( ctxt - > myDoc , ctxt - > node , name ) ;
if ( ns = = NULL ) { /* ctxt->node may not have a parent yet ! */
if ( ctxt - > nodeNr > = 2 ) {
parent = ctxt - > nodeTab [ ctxt - > nodeNr - 2 ] ;
if ( parent ! = NULL )
ns = xmlSearchNs ( ctxt - > myDoc , parent , name ) ;
}
}
xmlSetNs ( ctxt - > node , ns ) ;
}
/**
* getNamespace :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
*
* Get the current element namespace .
2000-04-24 11:33:38 +00:00
*
* Returns the xmlNsPtr or NULL if none
1999-04-05 12:20:10 +00:00
*/
2000-04-24 11:33:38 +00:00
1999-04-05 12:20:10 +00:00
xmlNsPtr
1999-05-29 11:51:49 +00:00
getNamespace ( void * ctx )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlNsPtr ret ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " SAX.getNamespace() \n " ) ;
1999-04-05 12:20:10 +00:00
# endif
ret = ctxt - > node - > ns ;
return ( ret ) ;
}
/**
* checkNamespace :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ namespace : the namespace to check against
*
* Check that the current element namespace is the same as the
* one read upon parsing .
2000-04-24 11:33:38 +00:00
*
* Returns 1 if true 0 otherwise
1999-04-05 12:20:10 +00:00
*/
2000-04-24 11:33:38 +00:00
1999-04-05 12:20:10 +00:00
int
1999-09-23 22:19:22 +00:00
checkNamespace ( void * ctx , xmlChar * namespace )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
xmlNodePtr cur = ctxt - > node ;
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.checkNamespace(%s) \n " , namespace ) ;
1999-04-05 12:20:10 +00:00
# endif
/*
* Check that the Name in the ETag is the same as in the STag .
*/
if ( namespace = = NULL ) {
if ( ( cur - > ns ! = NULL ) & & ( cur - > ns - > prefix ! = NULL ) ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" End tags for %s don't hold the namespace %s \n " ,
cur - > name , cur - > ns - > prefix ) ;
ctxt - > wellFormed = 0 ;
}
} else {
if ( ( cur - > ns = = NULL ) | | ( cur - > ns - > prefix = = NULL ) ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" End tags %s holds a prefix %s not used by the open tag \n " ,
cur - > name , namespace ) ;
ctxt - > wellFormed = 0 ;
2000-10-01 20:28:44 +00:00
} else if ( ! xmlStrEqual ( namespace , cur - > ns - > prefix ) ) {
1999-04-05 12:20:10 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt ,
" Start and End tags for %s don't use the same namespaces: %s and %s \n " ,
cur - > name , cur - > ns - > prefix , namespace ) ;
ctxt - > wellFormed = 0 ;
} else
return ( 1 ) ;
}
return ( 0 ) ;
}
/**
* namespaceDecl :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ href : the namespace associated URN
* @ prefix : the namespace prefix
*
* A namespace has been parsed .
*/
void
1999-09-23 22:19:22 +00:00
namespaceDecl ( void * ctx , const xmlChar * href , const xmlChar * prefix )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
if ( prefix = = NULL )
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.namespaceDecl(%s, NULL) \n " , href ) ;
1999-04-05 12:20:10 +00:00
else
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.namespaceDecl(%s, %s) \n " , href , prefix ) ;
1999-04-05 12:20:10 +00:00
# endif
xmlNewNs ( ctxt - > node , href , prefix ) ;
}
/**
* comment :
1999-06-02 17:44:04 +00:00
* @ ctx : the user data ( XML parser context )
1999-04-05 12:20:10 +00:00
* @ value : the comment content
*
* A comment has been parsed .
*/
void
1999-09-23 22:19:22 +00:00
comment ( void * ctx , const xmlChar * value )
1999-04-05 12:20:10 +00:00
{
1999-05-29 11:51:49 +00:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-06-22 21:49:07 +00:00
xmlNodePtr ret ;
1999-08-29 21:02:19 +00:00
xmlNodePtr parent = ctxt - > node ;
1999-06-22 21:49:07 +00:00
1999-04-05 12:20:10 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext , " SAX.comment(%s) \n " , value ) ;
1999-04-05 12:20:10 +00:00
# endif
1999-06-22 21:49:07 +00:00
ret = xmlNewDocComment ( ctxt - > myDoc , value ) ;
1999-08-29 21:02:19 +00:00
if ( ret = = NULL ) return ;
2000-03-14 18:30:20 +00:00
if ( ctxt - > inSubset = = 1 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > intSubset , ret ) ;
return ;
} else if ( ctxt - > inSubset = = 2 ) {
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc - > extSubset , ret ) ;
return ;
}
if ( ( ctxt - > myDoc - > children = = NULL ) | | ( parent = = NULL ) ) {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" Setting comment as root \n " ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddChild ( ( xmlNodePtr ) ctxt - > myDoc , ( xmlNodePtr ) ret ) ;
return ;
1999-08-29 21:02:19 +00:00
}
2000-03-14 18:30:20 +00:00
if ( parent - > type = = XML_ELEMENT_NODE ) {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" adding comment child to %s \n " , parent - > name ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddChild ( parent , ret ) ;
} else {
1999-08-29 21:02:19 +00:00
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" adding comment sibling to " ) ;
2000-03-14 18:30:20 +00:00
xmlDebugDumpOneNode ( stderr , parent , 0 ) ;
1999-08-29 21:02:19 +00:00
# endif
2000-03-14 18:30:20 +00:00
xmlAddSibling ( parent , ret ) ;
1999-08-29 21:02:19 +00:00
}
1999-08-10 19:04:08 +00:00
}
/**
* cdataBlock :
* @ ctx : the user data ( XML parser context )
* @ value : The pcdata content
* @ len : the block length
*
* called when a pcdata block has been parsed
*/
void
1999-09-23 22:19:22 +00:00
cdataBlock ( void * ctx , const xmlChar * value , int len )
1999-08-10 19:04:08 +00:00
{
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-12-28 16:35:14 +00:00
xmlNodePtr ret , lastChild ;
1999-08-10 19:04:08 +00:00
# ifdef DEBUG_SAX
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" SAX.pcdata(%.10s, %d) \n " , value , len ) ;
1999-08-10 19:04:08 +00:00
# endif
1999-12-28 16:35:14 +00:00
lastChild = xmlGetLastChild ( ctxt - > node ) ;
# ifdef DEBUG_SAX_TREE
2000-10-25 19:56:55 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" add chars to %s \n " , ctxt - > node - > name ) ;
1999-12-28 16:35:14 +00:00
# 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 ) ;
}
1999-04-05 12:20:10 +00:00
}
1999-07-05 16:50:46 +00:00
/*
* Default handler for XML , builds the DOM tree
*/
1998-08-13 03:39:55 +00:00
xmlSAXHandler xmlDefaultSAXHandler = {
1999-04-05 12:20:10 +00:00
internalSubset ,
isStandalone ,
hasInternalSubset ,
hasExternalSubset ,
1998-08-13 03:39:55 +00:00
resolveEntity ,
1999-04-05 12:20:10 +00:00
getEntity ,
entityDecl ,
1998-08-13 03:39:55 +00:00
notationDecl ,
1999-04-05 12:20:10 +00:00
attributeDecl ,
elementDecl ,
1998-08-13 03:39:55 +00:00
unparsedEntityDecl ,
setDocumentLocator ,
startDocument ,
endDocument ,
startElement ,
endElement ,
1999-04-05 12:20:10 +00:00
reference ,
1998-08-13 03:39:55 +00:00
characters ,
ignorableWhitespace ,
processingInstruction ,
1999-04-05 12:20:10 +00:00
comment ,
1998-08-13 03:39:55 +00:00
xmlParserWarning ,
xmlParserError ,
xmlParserError ,
1999-08-10 19:04:08 +00:00
getParameterEntity ,
cdataBlock ,
2000-03-14 18:30:20 +00:00
externalSubset ,
1998-08-13 03:39:55 +00:00
} ;
1998-10-20 06:14:16 +00:00
/**
* xmlDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
xmlDefaultSAXHandlerInit ( void )
{
1999-04-05 12:20:10 +00:00
xmlDefaultSAXHandler . internalSubset = internalSubset ;
2000-03-14 18:30:20 +00:00
xmlDefaultSAXHandler . externalSubset = externalSubset ;
1999-04-05 12:20:10 +00:00
xmlDefaultSAXHandler . isStandalone = isStandalone ;
xmlDefaultSAXHandler . hasInternalSubset = hasInternalSubset ;
xmlDefaultSAXHandler . hasExternalSubset = hasExternalSubset ;
1998-08-13 03:39:55 +00:00
xmlDefaultSAXHandler . resolveEntity = resolveEntity ;
1999-04-05 12:20:10 +00:00
xmlDefaultSAXHandler . getEntity = getEntity ;
1999-08-10 19:04:08 +00:00
xmlDefaultSAXHandler . getParameterEntity = getParameterEntity ;
1999-04-05 12:20:10 +00:00
xmlDefaultSAXHandler . entityDecl = entityDecl ;
xmlDefaultSAXHandler . attributeDecl = attributeDecl ;
xmlDefaultSAXHandler . elementDecl = elementDecl ;
1998-08-13 03:39:55 +00:00
xmlDefaultSAXHandler . notationDecl = notationDecl ;
xmlDefaultSAXHandler . unparsedEntityDecl = unparsedEntityDecl ;
xmlDefaultSAXHandler . setDocumentLocator = setDocumentLocator ;
xmlDefaultSAXHandler . startDocument = startDocument ;
xmlDefaultSAXHandler . endDocument = endDocument ;
xmlDefaultSAXHandler . startElement = startElement ;
xmlDefaultSAXHandler . endElement = endElement ;
1999-04-05 12:20:10 +00:00
xmlDefaultSAXHandler . reference = reference ;
1998-08-13 03:39:55 +00:00
xmlDefaultSAXHandler . characters = characters ;
1999-08-10 19:04:08 +00:00
xmlDefaultSAXHandler . cdataBlock = cdataBlock ;
1998-08-13 03:39:55 +00:00
xmlDefaultSAXHandler . ignorableWhitespace = ignorableWhitespace ;
xmlDefaultSAXHandler . processingInstruction = processingInstruction ;
1999-04-05 12:20:10 +00:00
xmlDefaultSAXHandler . comment = comment ;
2000-03-14 18:30:20 +00:00
if ( xmlGetWarningsDefaultValue = = 0 )
xmlDefaultSAXHandler . warning = NULL ;
else
xmlDefaultSAXHandler . warning = xmlParserWarning ;
1998-08-13 03:39:55 +00:00
xmlDefaultSAXHandler . error = xmlParserError ;
xmlDefaultSAXHandler . fatalError = xmlParserError ;
}
1999-07-05 16:50:46 +00:00
/*
* Default handler for HTML , builds the DOM tree
*/
xmlSAXHandler htmlDefaultSAXHandler = {
2000-06-30 18:39:56 +00:00
internalSubset ,
1999-07-05 16:50:46 +00:00
NULL ,
NULL ,
NULL ,
NULL ,
getEntity ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
setDocumentLocator ,
startDocument ,
endDocument ,
startElement ,
endElement ,
NULL ,
characters ,
ignorableWhitespace ,
NULL ,
comment ,
xmlParserWarning ,
xmlParserError ,
xmlParserError ,
1999-08-10 19:04:08 +00:00
getParameterEntity ,
2000-10-14 23:38:43 +00:00
cdataBlock ,
2000-03-14 18:30:20 +00:00
NULL ,
1999-07-05 16:50:46 +00:00
} ;
/**
* htmlDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
htmlDefaultSAXHandlerInit ( void )
{
2000-06-30 18:39:56 +00:00
htmlDefaultSAXHandler . internalSubset = internalSubset ;
2000-03-14 18:30:20 +00:00
htmlDefaultSAXHandler . externalSubset = NULL ;
1999-07-05 16:50:46 +00:00
htmlDefaultSAXHandler . isStandalone = NULL ;
htmlDefaultSAXHandler . hasInternalSubset = NULL ;
htmlDefaultSAXHandler . hasExternalSubset = NULL ;
htmlDefaultSAXHandler . resolveEntity = NULL ;
htmlDefaultSAXHandler . getEntity = getEntity ;
1999-08-10 19:04:08 +00:00
htmlDefaultSAXHandler . getParameterEntity = NULL ;
1999-07-05 16:50:46 +00:00
htmlDefaultSAXHandler . entityDecl = NULL ;
htmlDefaultSAXHandler . attributeDecl = NULL ;
htmlDefaultSAXHandler . elementDecl = NULL ;
htmlDefaultSAXHandler . notationDecl = NULL ;
htmlDefaultSAXHandler . unparsedEntityDecl = NULL ;
htmlDefaultSAXHandler . setDocumentLocator = setDocumentLocator ;
htmlDefaultSAXHandler . startDocument = startDocument ;
htmlDefaultSAXHandler . endDocument = endDocument ;
htmlDefaultSAXHandler . startElement = startElement ;
htmlDefaultSAXHandler . endElement = endElement ;
htmlDefaultSAXHandler . reference = NULL ;
htmlDefaultSAXHandler . characters = characters ;
2000-11-12 15:56:56 +00:00
htmlDefaultSAXHandler . cdataBlock = cdataBlock ;
1999-07-05 16:50:46 +00:00
htmlDefaultSAXHandler . ignorableWhitespace = ignorableWhitespace ;
htmlDefaultSAXHandler . processingInstruction = NULL ;
htmlDefaultSAXHandler . comment = comment ;
htmlDefaultSAXHandler . warning = xmlParserWarning ;
htmlDefaultSAXHandler . error = xmlParserError ;
htmlDefaultSAXHandler . fatalError = xmlParserError ;
}
2000-09-10 16:14:55 +00:00
/*
* Default handler for HTML , builds the DOM tree
*/
xmlSAXHandler sgmlDefaultSAXHandler = {
internalSubset ,
NULL ,
NULL ,
NULL ,
NULL ,
getEntity ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
setDocumentLocator ,
startDocument ,
endDocument ,
startElement ,
endElement ,
NULL ,
characters ,
ignorableWhitespace ,
NULL ,
comment ,
xmlParserWarning ,
xmlParserError ,
xmlParserError ,
getParameterEntity ,
NULL ,
NULL ,
} ;
/**
* sgmlDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
sgmlDefaultSAXHandlerInit ( void )
{
sgmlDefaultSAXHandler . internalSubset = internalSubset ;
sgmlDefaultSAXHandler . externalSubset = NULL ;
sgmlDefaultSAXHandler . isStandalone = NULL ;
sgmlDefaultSAXHandler . hasInternalSubset = NULL ;
sgmlDefaultSAXHandler . hasExternalSubset = NULL ;
sgmlDefaultSAXHandler . resolveEntity = NULL ;
sgmlDefaultSAXHandler . getEntity = getEntity ;
sgmlDefaultSAXHandler . getParameterEntity = NULL ;
sgmlDefaultSAXHandler . entityDecl = NULL ;
sgmlDefaultSAXHandler . attributeDecl = NULL ;
sgmlDefaultSAXHandler . elementDecl = NULL ;
sgmlDefaultSAXHandler . notationDecl = NULL ;
sgmlDefaultSAXHandler . unparsedEntityDecl = NULL ;
sgmlDefaultSAXHandler . setDocumentLocator = setDocumentLocator ;
sgmlDefaultSAXHandler . startDocument = startDocument ;
sgmlDefaultSAXHandler . endDocument = endDocument ;
sgmlDefaultSAXHandler . startElement = startElement ;
sgmlDefaultSAXHandler . endElement = endElement ;
sgmlDefaultSAXHandler . reference = NULL ;
sgmlDefaultSAXHandler . characters = characters ;
sgmlDefaultSAXHandler . cdataBlock = NULL ;
sgmlDefaultSAXHandler . ignorableWhitespace = ignorableWhitespace ;
sgmlDefaultSAXHandler . processingInstruction = NULL ;
sgmlDefaultSAXHandler . comment = comment ;
sgmlDefaultSAXHandler . warning = xmlParserWarning ;
sgmlDefaultSAXHandler . error = xmlParserError ;
sgmlDefaultSAXHandler . fatalError = xmlParserError ;
}