1998-08-13 07:39:55 +04:00
/*
* SAX . c : Default SAX handler to build a tree .
1998-10-20 10:14:16 +04:00
*
1999-01-17 22:11:59 +03:00
* See Copyright for the status of this software .
*
1998-10-20 10:14:16 +04:00
* Daniel Veillard < Daniel . Veillard @ w3 . org >
1998-08-13 07:39:55 +04:00
*/
# include <stdio.h>
1998-10-02 00:51:15 +04:00
# include <stdlib.h>
1998-08-13 07:39:55 +04:00
# include "tree.h"
# include "parser.h"
1999-04-05 16:20:10 +04:00
# include "parserInternals.h"
# include "valid.h"
1998-10-27 09:21:04 +03:00
# include "entities.h"
1999-03-05 09:26:45 +03:00
# include "xml-error.h"
1998-08-13 07:39:55 +04:00
/* #define DEBUG_SAX */
1998-10-20 10:14:16 +04:00
/**
* getPublicId :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
*
1998-08-13 07:39:55 +04:00
* Return the public ID e . g . " -//SGMLSOURCE//DTD DEMO//EN "
1998-10-20 10:14:16 +04:00
*
1999-02-22 13:33:01 +03:00
* Returns a CHAR *
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
const CHAR *
1999-05-29 15:51:49 +04:00
getPublicId ( void * ctx )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 07:39:55 +04:00
return ( NULL ) ;
}
1998-10-20 10:14:16 +04:00
/**
* getSystemId :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
*
1999-06-02 21:44:04 +04:00
* Return the system ID , basically URL or filename e . g .
1998-10-20 10:14:16 +04:00
* http : //www.sgmlsource.com/dtds/memo.dtd
*
1999-02-22 13:33:01 +03:00
* Returns a CHAR *
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
const CHAR *
1999-05-29 15:51:49 +04:00
getSystemId ( void * ctx )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 07:39:55 +04:00
return ( ctxt - > input - > filename ) ;
}
1998-10-20 10:14:16 +04:00
/**
* getLineNumber :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
*
1998-08-13 07:39:55 +04:00
* Return the line number of the current parsing point .
1998-10-20 10:14:16 +04:00
*
1999-02-22 13:33:01 +03:00
* Returns an int
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
int
1999-05-29 15:51:49 +04:00
getLineNumber ( void * ctx )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 07:39:55 +04:00
return ( ctxt - > input - > line ) ;
}
1998-10-20 10:14:16 +04:00
/**
* getColumnNumber :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
*
1998-08-13 07:39:55 +04:00
* Return the column number of the current parsing point .
1998-10-20 10:14:16 +04:00
*
1999-02-22 13:33:01 +03:00
* Returns an int
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
int
1999-05-29 15:51:49 +04:00
getColumnNumber ( void * ctx )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 07:39:55 +04:00
return ( ctxt - > input - > col ) ;
}
/*
* The default SAX Locator .
*/
xmlSAXLocator xmlDefaultSAXLocator = {
getPublicId , getSystemId , getLineNumber , getColumnNumber
} ;
1999-04-05 16:20:10 +04:00
/**
* isStandalone :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
*
* Is this document tagged standalone ?
*
* Returns 1 if true
*/
int
1999-05-29 15:51:49 +04:00
isStandalone ( void * ctx )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
return ( ctxt - > myDoc - > standalone = = 1 ) ;
}
/**
* hasInternalSubset :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
*
* Does this document has an internal subset
*
* Returns 1 if true
*/
int
1999-05-29 15:51:49 +04:00
hasInternalSubset ( void * ctx )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
return ( ctxt - > myDoc - > intSubset ! = NULL ) ;
}
/**
* hasExternalSubset :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
*
* Does this document has an external subset
*
* Returns 1 if true
*/
int
1999-05-29 15:51:49 +04:00
hasExternalSubset ( void * ctx )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
return ( ctxt - > myDoc - > extSubset ! = NULL ) ;
}
/**
* hasInternalSubset :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
*
* Does this document has an internal subset
*/
void
1999-05-29 15:51:49 +04:00
internalSubset ( void * ctx , const CHAR * name ,
1999-04-05 16:20:10 +04:00
const CHAR * ExternalID , const CHAR * SystemID )
{
1999-06-02 21:44:04 +04:00
xmlDtdPtr externalSubset ;
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.internalSubset(%s, %s, %s) \n " ,
name , ExternalID , SystemID ) ;
# endif
xmlCreateIntSubset ( ctxt - > myDoc , name , ExternalID , SystemID ) ;
1999-06-02 21:44:04 +04:00
if ( ( ExternalID ! = NULL ) | | ( SystemID ! = NULL ) ) {
externalSubset = xmlParseDTD ( ExternalID , SystemID ) ;
}
1999-04-05 16:20:10 +04:00
}
1998-10-20 10:14:16 +04:00
/**
* resolveEntity :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
1998-08-13 07:39:55 +04:00
* Special entity resolver , better left to the parser , it has
* more context than the application layer .
1998-10-27 09:21:04 +03:00
* The default behaviour is to NOT resolve the entities , in that case
* the ENTITY_REF nodes are built in the structure ( and the parameter
* values ) .
1998-10-20 10:14:16 +04:00
*
1999-02-22 13:33:01 +03:00
* Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour .
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
xmlParserInputPtr
1999-05-29 15:51:49 +04:00
resolveEntity ( void * ctx , const CHAR * publicId , const CHAR * systemId )
1998-10-20 10:14:16 +04:00
{
1999-06-02 21:44:04 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.resolveEntity(%s, %s) \n " , publicId , systemId ) ;
# endif
1998-10-27 09:21:04 +03:00
1999-04-05 16:20:10 +04:00
/*
* TODO : not 100 % sure that the appropriate handling in that case .
*/
1999-06-02 21:44:04 +04:00
if ( systemId ! = NULL ) {
1999-07-07 02:25:25 +04:00
if ( ! xmlStrncmp ( systemId , " http:// " , 7 ) ) {
/* !!!!!!!!! TODO */
} else if ( ! xmlStrncmp ( systemId , " ftp:// " , 6 ) ) {
/* !!!!!!!!! TODO */
} else {
return ( xmlNewInputFromFile ( ctxt , systemId ) ) ;
}
1999-06-02 21:44:04 +04:00
}
1998-08-13 07:39:55 +04:00
return ( NULL ) ;
}
1999-04-05 16:20:10 +04:00
/**
* getEntity :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ name : The entity name
*
* Get an entity by name
*
1999-06-02 21:44:04 +04:00
* Returns the xmlEntityPtr if found .
1999-04-05 16:20:10 +04:00
*/
xmlEntityPtr
1999-05-29 15:51:49 +04:00
getEntity ( void * ctx , const CHAR * name )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlEntityPtr ret ;
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.getEntity(%s) \n " , name ) ;
# endif
ret = xmlGetDocEntity ( ctxt - > myDoc , name ) ;
return ( ret ) ;
}
/**
* entityDecl :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04: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-05-29 15:51:49 +04:00
entityDecl ( void * ctx , const CHAR * name , int type ,
1999-04-05 16:20:10 +04:00
const CHAR * publicId , const CHAR * systemId , CHAR * content )
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.entityDecl(%s, %d, %s, %s, %s) \n " ,
name , type , publicId , systemId , content ) ;
# endif
xmlAddDocEntity ( ctxt - > myDoc , name , type , publicId , systemId , content ) ;
}
/**
* attributeDecl :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ name : the attribute name
* @ type : the attribute type
* @ publicId : The public ID of the attribute
* @ systemId : The system ID of the attribute
* @ content : the attribute value ( without processing ) .
*
* An attribute definition has been parsed
*/
void
1999-05-29 15:51:49 +04:00
attributeDecl ( void * ctx , const CHAR * elem , const CHAR * name ,
1999-04-05 16:20:10 +04:00
int type , int def , const CHAR * defaultValue ,
xmlEnumerationPtr tree )
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.attributeDecl(%s, %s, %d, %d, %s, ...) \n " ,
elem , name , type , def , defaultValue ) ;
# endif
xmlAddAttributeDecl ( ctxt - > myDoc - > intSubset , elem , name , type , def ,
defaultValue , tree ) ;
}
/**
* elementDecl :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ name : the element name
* @ type : the element type
* @ publicId : The public ID of the element
* @ systemId : The system ID of the element
* @ content : the element value ( without processing ) .
*
* An element definition has been parsed
*/
void
1999-05-29 15:51:49 +04:00
elementDecl ( void * ctx , const CHAR * name , int type ,
1999-04-05 16:20:10 +04:00
xmlElementContentPtr content )
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.elementDecl(%s, %d, ...) \n " ,
name , type ) ;
# endif
xmlAddElementDecl ( ctxt - > myDoc - > intSubset , name , type , content ) ;
}
1998-10-20 10:14:16 +04:00
/**
* notationDecl :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ name : The name of the notation
* @ publicId : The public ID of the entity
* @ systemId : The system ID of the entity
*
1998-08-13 07:39:55 +04:00
* What to do when a notation declaration has been parsed .
* TODO Not handled currently .
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
notationDecl ( void * ctx , const CHAR * name ,
1998-10-20 10:14:16 +04:00
const CHAR * publicId , const CHAR * systemId )
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.notationDecl(%s, %s, %s) \n " , name , publicId , systemId ) ;
# endif
1999-04-05 16:20:10 +04:00
xmlAddNotationDecl ( ctxt - > myDoc - > intSubset , name , publicId , systemId ) ;
1998-08-13 07:39:55 +04:00
}
1998-10-20 10:14:16 +04:00
/**
* unparsedEntityDecl :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04: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 07:39:55 +04:00
* What to do when an unparsed entity declaration is parsed
* TODO Create an Entity node .
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
unparsedEntityDecl ( void * ctx , const CHAR * name ,
1998-10-20 10:14:16 +04:00
const CHAR * publicId , const CHAR * systemId ,
const CHAR * notationName )
{
1999-05-29 15:51:49 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.unparsedEntityDecl(%s, %s, %s, %s) \n " ,
name , publicId , systemId , notationName ) ;
# endif
}
1998-10-20 10:14:16 +04:00
/**
* setDocumentLocator :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ loc : A SAX Locator
*
1998-08-13 07:39:55 +04: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 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
setDocumentLocator ( void * ctx , xmlSAXLocatorPtr loc )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.setDocumentLocator() \n " ) ;
# endif
}
1998-10-20 10:14:16 +04:00
/**
* startDocument :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
*
1998-08-13 07:39:55 +04:00
* called when the document start being processed .
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
startDocument ( void * ctx )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlDocPtr doc ;
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.startDocument() \n " ) ;
# endif
1999-04-05 16:20:10 +04:00
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 ;
}
1998-08-13 07:39:55 +04:00
}
1998-10-20 10:14:16 +04:00
/**
* endDocument :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
*
1998-08-13 07:39:55 +04:00
* called when the document end has been detected .
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
endDocument ( void * ctx )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.endDocument() \n " ) ;
# endif
}
1999-04-05 16:20:10 +04:00
/**
* attribute :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ name : The attribute name
* @ 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-05-29 15:51:49 +04:00
attribute ( void * ctx , const CHAR * fullname , const CHAR * value )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlAttrPtr ret ;
CHAR * name ;
CHAR * ns ;
/****************
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.attribute(%s, %s) \n " , fullname , value ) ;
# endif
* * * * * * * * * * * * * * * */
/*
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName ( fullname , & ns ) ;
/*
* Check whether it ' s a namespace definition
*/
if ( ( ns = = NULL ) & &
( name [ 0 ] = = ' x ' ) & & ( name [ 1 ] = = ' m ' ) & & ( name [ 2 ] = = ' l ' ) & &
( name [ 3 ] = = ' n ' ) & & ( name [ 4 ] = = ' s ' ) & & ( name [ 5 ] = = 0 ) ) {
/* a default namespace definition */
xmlNewNs ( ctxt - > node , value , NULL ) ;
if ( name ! = NULL )
free ( name ) ;
return ;
}
if ( ( ns ! = NULL ) & & ( ns [ 0 ] = = ' x ' ) & & ( ns [ 1 ] = = ' m ' ) & & ( ns [ 2 ] = = ' l ' ) & &
( ns [ 3 ] = = ' n ' ) & & ( ns [ 4 ] = = ' s ' ) & & ( ns [ 5 ] = = 0 ) ) {
/* a standard namespace definition */
xmlNewNs ( ctxt - > node , value , name ) ;
free ( ns ) ;
if ( name ! = NULL )
free ( name ) ;
return ;
}
ret = xmlNewProp ( ctxt - > node , name , NULL ) ;
1999-06-02 21:44:04 +04:00
if ( ( ret ! = NULL ) & & ( ctxt - > replaceEntities = = 0 ) )
1999-04-05 16:20:10 +04:00
ret - > val = xmlStringGetNodeList ( ctxt - > myDoc , value ) ;
if ( name ! = NULL )
free ( name ) ;
if ( ns ! = NULL )
free ( ns ) ;
}
1998-10-20 10:14:16 +04:00
/**
* startElement :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ name : The element name
1999-04-05 16:20:10 +04:00
* @ atts : An array of name / value attributes pairs , NULL terminated
1998-10-20 10:14:16 +04:00
*
1998-08-13 07:39:55 +04:00
* called when an opening tag has been processed .
* TODO We currently have a small pblm with the arguments . . .
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
startElement ( void * ctx , const CHAR * fullname , const CHAR * * atts )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlNodePtr ret ;
xmlNodePtr parent = ctxt - > node ;
xmlNsPtr ns ;
CHAR * name ;
CHAR * prefix ;
const CHAR * att ;
const CHAR * value ;
int i ;
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
1999-04-05 16:20:10 +04:00
fprintf ( stderr , " SAX.startElement(%s) \n " , fullname ) ;
1998-08-13 07:39:55 +04:00
# endif
1999-04-05 16:20:10 +04:00
/*
* Split the full name into a namespace prefix and the tag name
*/
name = xmlSplitQName ( 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 = xmlNewDocNode ( ctxt - > myDoc , NULL , name , NULL ) ;
if ( ret = = NULL ) return ;
if ( ctxt - > myDoc - > root = = NULL )
ctxt - > myDoc - > root = ret ;
/*
* We are parsing a new node .
*/
nodePush ( ctxt , ret ) ;
/*
* Link the child element
*/
if ( parent ! = NULL )
xmlAddChild ( parent , ctxt - > node ) ;
/*
* process all the attributes .
*/
if ( atts ! = NULL ) {
i = 0 ;
att = atts [ i + + ] ;
value = atts [ i + + ] ;
while ( ( att ! = NULL ) & & ( value ! = NULL ) ) {
/*
* Handle one pair of attribute / value
*/
attribute ( ctxt , att , value ) ;
/*
* Next ones
*/
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 ) ;
xmlSetNs ( ret , ns ) ;
if ( prefix ! = NULL )
free ( prefix ) ;
if ( name ! = NULL )
free ( name ) ;
1998-08-13 07:39:55 +04:00
}
1998-10-20 10:14:16 +04:00
/**
* endElement :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ name : The element name
*
1998-08-13 07:39:55 +04:00
* called when the end of an element has been detected .
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
endElement ( void * ctx , const CHAR * name )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlParserNodeInfo node_info ;
xmlNodePtr cur = ctxt - > node ;
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
1999-04-05 16:20:10 +04:00
if ( name = = NULL )
fprintf ( stderr , " SAX.endElement(NULL) \n " ) ;
else
fprintf ( stderr , " SAX.endElement(%s) \n " , name ) ;
1998-08-13 07:39:55 +04:00
# endif
1999-04-05 16:20:10 +04: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 ) ;
}
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
1998-08-13 07:39:55 +04:00
}
1998-10-24 22:27:49 +04:00
/**
1999-04-05 16:20:10 +04:00
* reference :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ name : The entity name
1998-10-24 22:27:49 +04:00
*
1999-04-05 16:20:10 +04:00
* called when an entity reference is detected .
1998-10-24 22:27:49 +04:00
*/
void
1999-05-29 15:51:49 +04:00
reference ( void * ctx , const CHAR * name )
1998-10-24 22:27:49 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlNodePtr ret ;
1998-10-24 22:27:49 +04:00
# ifdef DEBUG_SAX
1999-04-05 16:20:10 +04:00
fprintf ( stderr , " SAX.reference(%s) \n " , name ) ;
1998-10-24 22:27:49 +04:00
# endif
1999-04-05 16:20:10 +04:00
ret = xmlNewReference ( ctxt - > myDoc , name ) ;
xmlAddChild ( ctxt - > node , ret ) ;
1998-10-24 22:27:49 +04:00
}
1998-10-20 10:14:16 +04:00
/**
* characters :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ ch : a CHAR string
* @ len : the number of CHAR
*
1998-08-13 07:39:55 +04:00
* receiving some chars from the parser .
* Question : how much at a time ? ? ?
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
characters ( void * ctx , const CHAR * ch , int len )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1998-08-13 07:39:55 +04:00
xmlNodePtr lastChild ;
# ifdef DEBUG_SAX
1999-04-05 16:20:10 +04:00
fprintf ( stderr , " SAX.characters(%.30s, %d) \n " , ch , len ) ;
1998-08-13 07:39:55 +04: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 .
*/
lastChild = xmlGetLastChild ( ctxt - > node ) ;
if ( lastChild = = NULL )
1999-04-05 16:20:10 +04:00
xmlNodeAddContentLen ( ctxt - > node , ch , len ) ;
1998-08-13 07:39:55 +04:00
else {
if ( xmlNodeIsText ( lastChild ) )
1999-04-05 16:20:10 +04:00
xmlTextConcat ( lastChild , ch , len ) ;
1998-08-13 07:39:55 +04:00
else {
1999-04-05 16:20:10 +04:00
lastChild = xmlNewTextLen ( ch , len ) ;
1998-08-13 07:39:55 +04:00
xmlAddChild ( ctxt - > node , lastChild ) ;
}
}
}
1998-10-20 10:14:16 +04:00
/**
* ignorableWhitespace :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ ch : a CHAR string
* @ len : the number of CHAR
*
1998-08-13 07:39:55 +04:00
* receiving some ignorable whitespaces from the parser .
* Question : how much at a time ? ? ?
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
ignorableWhitespace ( void * ctx , const CHAR * ch , int len )
1998-10-20 10:14:16 +04:00
{
1999-05-29 15:51:49 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
1999-04-05 16:20:10 +04:00
fprintf ( stderr , " SAX.ignorableWhitespace(%.30s, %d) \n " , ch , len ) ;
1998-08-13 07:39:55 +04:00
# endif
}
1998-10-20 10:14:16 +04:00
/**
* processingInstruction :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1998-10-20 10:14:16 +04:00
* @ target : the target name
* @ data : the PI data ' s
* @ len : the number of CHAR
*
* A processing instruction has been parsed .
1998-08-13 07:39:55 +04:00
*/
1998-10-20 10:14:16 +04:00
void
1999-05-29 15:51:49 +04:00
processingInstruction ( void * ctx , const CHAR * target ,
1998-10-20 10:14:16 +04:00
const CHAR * data )
{
1999-05-29 15:51:49 +04:00
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1998-08-13 07:39:55 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.processingInstruction(%s, %s) \n " , target , data ) ;
# endif
}
1999-04-05 16:20:10 +04:00
/**
* globalNamespace :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ href : the namespace associated URN
* @ prefix : the namespace prefix
*
* An old global namespace has been parsed .
*/
void
1999-05-29 15:51:49 +04:00
globalNamespace ( void * ctx , const CHAR * href , const CHAR * prefix )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.globalNamespace(%s, %s) \n " , href , prefix ) ;
# endif
xmlNewGlobalNs ( ctxt - > myDoc , href , prefix ) ;
}
/**
* setNamespace :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ name : the namespace prefix
*
* Set the current element namespace .
*/
void
1999-05-29 15:51:49 +04:00
setNamespace ( void * ctx , const CHAR * name )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlNsPtr ns ;
xmlNodePtr parent ;
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.setNamespace(%s) \n " , name ) ;
# 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 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
*
* Get the current element namespace .
*/
xmlNsPtr
1999-05-29 15:51:49 +04:00
getNamespace ( void * ctx )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlNsPtr ret ;
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.getNamespace() \n " ) ;
# endif
ret = ctxt - > node - > ns ;
return ( ret ) ;
}
/**
* checkNamespace :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ namespace : the namespace to check against
*
* Check that the current element namespace is the same as the
* one read upon parsing .
*/
int
1999-05-29 15:51:49 +04:00
checkNamespace ( void * ctx , CHAR * namespace )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
xmlNodePtr cur = ctxt - > node ;
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.checkNamespace(%s) \n " , namespace ) ;
# 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 ;
} else if ( strcmp ( namespace , cur - > ns - > prefix ) ) {
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 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ href : the namespace associated URN
* @ prefix : the namespace prefix
*
* A namespace has been parsed .
*/
void
1999-05-29 15:51:49 +04:00
namespaceDecl ( void * ctx , const CHAR * href , const CHAR * prefix )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
if ( prefix = = NULL )
fprintf ( stderr , " SAX.namespaceDecl(%s, NULL) \n " , href ) ;
else
fprintf ( stderr , " SAX.namespaceDecl(%s, %s) \n " , href , prefix ) ;
# endif
xmlNewNs ( ctxt - > node , href , prefix ) ;
}
/**
* comment :
1999-06-02 21:44:04 +04:00
* @ ctx : the user data ( XML parser context )
1999-04-05 16:20:10 +04:00
* @ value : the comment content
*
* A comment has been parsed .
*/
void
1999-05-29 15:51:49 +04:00
comment ( void * ctx , const CHAR * value )
1999-04-05 16:20:10 +04:00
{
1999-05-29 15:51:49 +04:00
xmlParserCtxtPtr ctxt = ( xmlParserCtxtPtr ) ctx ;
1999-06-23 01:49:07 +04:00
xmlNodePtr ret ;
1999-04-05 16:20:10 +04:00
# ifdef DEBUG_SAX
fprintf ( stderr , " SAX.comment(%s) \n " , value ) ;
# endif
1999-06-23 01:49:07 +04:00
ret = xmlNewDocComment ( ctxt - > myDoc , value ) ;
xmlAddChild ( ctxt - > node , ret ) ;
1999-04-05 16:20:10 +04:00
}
1999-07-05 20:50:46 +04:00
/*
* Default handler for XML , builds the DOM tree
*/
1998-08-13 07:39:55 +04:00
xmlSAXHandler xmlDefaultSAXHandler = {
1999-04-05 16:20:10 +04:00
internalSubset ,
isStandalone ,
hasInternalSubset ,
hasExternalSubset ,
1998-08-13 07:39:55 +04:00
resolveEntity ,
1999-04-05 16:20:10 +04:00
getEntity ,
entityDecl ,
1998-08-13 07:39:55 +04:00
notationDecl ,
1999-04-05 16:20:10 +04:00
attributeDecl ,
elementDecl ,
1998-08-13 07:39:55 +04:00
unparsedEntityDecl ,
setDocumentLocator ,
startDocument ,
endDocument ,
startElement ,
endElement ,
1999-04-05 16:20:10 +04:00
reference ,
1998-08-13 07:39:55 +04:00
characters ,
ignorableWhitespace ,
processingInstruction ,
1999-04-05 16:20:10 +04:00
comment ,
1998-08-13 07:39:55 +04:00
xmlParserWarning ,
xmlParserError ,
xmlParserError ,
} ;
1998-10-20 10:14:16 +04:00
/**
* xmlDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
xmlDefaultSAXHandlerInit ( void )
{
1999-04-05 16:20:10 +04:00
xmlDefaultSAXHandler . internalSubset = internalSubset ;
xmlDefaultSAXHandler . isStandalone = isStandalone ;
xmlDefaultSAXHandler . hasInternalSubset = hasInternalSubset ;
xmlDefaultSAXHandler . hasExternalSubset = hasExternalSubset ;
1998-08-13 07:39:55 +04:00
xmlDefaultSAXHandler . resolveEntity = resolveEntity ;
1999-04-05 16:20:10 +04:00
xmlDefaultSAXHandler . getEntity = getEntity ;
xmlDefaultSAXHandler . entityDecl = entityDecl ;
xmlDefaultSAXHandler . attributeDecl = attributeDecl ;
xmlDefaultSAXHandler . elementDecl = elementDecl ;
1998-08-13 07:39:55 +04: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 16:20:10 +04:00
xmlDefaultSAXHandler . reference = reference ;
1998-08-13 07:39:55 +04:00
xmlDefaultSAXHandler . characters = characters ;
xmlDefaultSAXHandler . ignorableWhitespace = ignorableWhitespace ;
xmlDefaultSAXHandler . processingInstruction = processingInstruction ;
1999-04-05 16:20:10 +04:00
xmlDefaultSAXHandler . comment = comment ;
1998-08-13 07:39:55 +04:00
xmlDefaultSAXHandler . warning = xmlParserWarning ;
xmlDefaultSAXHandler . error = xmlParserError ;
xmlDefaultSAXHandler . fatalError = xmlParserError ;
}
1999-07-05 20:50:46 +04:00
/*
* Default handler for HTML , builds the DOM tree
*/
xmlSAXHandler htmlDefaultSAXHandler = {
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
getEntity ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
setDocumentLocator ,
startDocument ,
endDocument ,
startElement ,
endElement ,
NULL ,
characters ,
ignorableWhitespace ,
NULL ,
comment ,
xmlParserWarning ,
xmlParserError ,
xmlParserError ,
} ;
/**
* htmlDefaultSAXHandlerInit :
*
* Initialize the default SAX handler
*/
void
htmlDefaultSAXHandlerInit ( void )
{
htmlDefaultSAXHandler . internalSubset = NULL ;
htmlDefaultSAXHandler . isStandalone = NULL ;
htmlDefaultSAXHandler . hasInternalSubset = NULL ;
htmlDefaultSAXHandler . hasExternalSubset = NULL ;
htmlDefaultSAXHandler . resolveEntity = NULL ;
htmlDefaultSAXHandler . getEntity = getEntity ;
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 ;
htmlDefaultSAXHandler . ignorableWhitespace = ignorableWhitespace ;
htmlDefaultSAXHandler . processingInstruction = NULL ;
htmlDefaultSAXHandler . comment = comment ;
htmlDefaultSAXHandler . warning = xmlParserWarning ;
htmlDefaultSAXHandler . error = xmlParserError ;
htmlDefaultSAXHandler . fatalError = xmlParserError ;
}