1999-01-17 19:11:59 +00:00
/*
* valid . c : part of the code use to do the DTD handling and the validity
* checking
*
* See Copyright for the status of this software .
*
* Daniel . Veillard @ w3 . org
*/
1999-09-22 09:46:25 +00:00
# ifdef WIN32
1999-12-22 11:30:41 +00:00
# include "win32config.h"
1999-09-22 09:46:25 +00:00
# else
# include "config.h"
# endif
1999-01-17 19:11:59 +00:00
# include <stdio.h>
# include <string.h>
1999-09-22 09:46:25 +00:00
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
1999-09-02 22:04:43 +00:00
# include "xmlmemory.h"
1999-01-17 19:11:59 +00:00
# include "valid.h"
# include "parser.h"
1999-08-10 19:04:08 +00:00
# include "parserInternals.h"
1999-12-28 16:35:14 +00:00
/* TODO: use hash table for accesses to elem and attribute dedinitions */
1999-08-10 19:04:08 +00:00
# define VERROR \
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) ) ctxt - > error
# define VWARNING \
if ( ( ctxt ! = NULL ) & & ( ctxt - > warning ! = NULL ) ) ctxt - > warning
# define CHECK_DTD \
if ( doc = = NULL ) return ( 0 ) ; \
else if ( doc - > intSubset = = NULL ) return ( 0 )
1999-09-23 22:19:22 +00:00
xmlElementPtr xmlGetDtdElementDesc ( xmlDtdPtr dtd , const xmlChar * name ) ;
xmlAttributePtr xmlScanAttributeDecl ( xmlDtdPtr dtd , const xmlChar * elem ) ;
1999-01-17 19:11:59 +00:00
/****************************************************************
* *
* Util functions for data allocation / deallocation *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlNewElementContent :
* @ name : the subelement name or NULL
* @ type : the type of element content decl
*
* Allocate an element content structure .
*
1999-02-22 10:33:01 +00:00
* Returns NULL if not , othervise the new element content structure
1999-01-17 19:11:59 +00:00
*/
xmlElementContentPtr
1999-09-23 22:19:22 +00:00
xmlNewElementContent ( xmlChar * name , xmlElementContentType type ) {
1999-01-17 19:11:59 +00:00
xmlElementContentPtr ret ;
switch ( type ) {
case XML_ELEMENT_CONTENT_ELEMENT :
if ( name = = NULL ) {
fprintf ( stderr , " xmlNewElementContent : name == NULL ! \n " ) ;
}
break ;
case XML_ELEMENT_CONTENT_PCDATA :
case XML_ELEMENT_CONTENT_SEQ :
case XML_ELEMENT_CONTENT_OR :
if ( name ! = NULL ) {
fprintf ( stderr , " xmlNewElementContent : name != NULL ! \n " ) ;
}
break ;
default :
fprintf ( stderr , " xmlNewElementContent: unknown type %d \n " , type ) ;
exit ( 1 ) ;
}
1999-09-02 22:04:43 +00:00
ret = ( xmlElementContentPtr ) xmlMalloc ( sizeof ( xmlElementContent ) ) ;
1999-01-17 19:11:59 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlNewElementContent : out of memory! \n " ) ;
return ( NULL ) ;
}
ret - > type = type ;
ret - > ocur = XML_ELEMENT_CONTENT_ONCE ;
1999-01-31 22:15:06 +00:00
if ( name ! = NULL )
ret - > name = xmlStrdup ( name ) ;
else
ret - > name = NULL ;
1999-02-22 10:33:01 +00:00
ret - > c1 = ret - > c2 = NULL ;
1999-01-17 19:11:59 +00:00
return ( ret ) ;
}
1999-01-31 22:15:06 +00:00
/**
* xmlCopyElementContent :
* @ content : An element content pointer .
*
* Build a copy of an element content description .
*
1999-02-22 10:33:01 +00:00
* Returns the new xmlElementContentPtr or NULL in case of error .
1999-01-31 22:15:06 +00:00
*/
xmlElementContentPtr
1999-02-22 10:33:01 +00:00
xmlCopyElementContent ( xmlElementContentPtr cur ) {
xmlElementContentPtr ret ;
if ( cur = = NULL ) return ( NULL ) ;
1999-09-23 22:19:22 +00:00
ret = xmlNewElementContent ( ( xmlChar * ) cur - > name , cur - > type ) ;
1999-06-22 21:49:07 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlCopyElementContent : out of memory \n " ) ;
return ( NULL ) ;
}
ret - > ocur = cur - > ocur ;
if ( cur - > c1 ! = NULL ) ret - > c1 = xmlCopyElementContent ( cur - > c1 ) ;
if ( cur - > c2 ! = NULL ) ret - > c2 = xmlCopyElementContent ( cur - > c2 ) ;
1999-02-22 10:33:01 +00:00
return ( ret ) ;
1999-01-31 22:15:06 +00:00
}
1999-01-17 19:11:59 +00:00
/**
1999-02-01 12:18:54 +00:00
* xmlFreeElementContent :
* @ cur : the element content tree to free
1999-01-17 19:11:59 +00:00
*
* Free an element content structure . This is a recursive call !
*/
void
xmlFreeElementContent ( xmlElementContentPtr cur ) {
1999-02-22 10:33:01 +00:00
if ( cur = = NULL ) return ;
if ( cur - > c1 ! = NULL ) xmlFreeElementContent ( cur - > c1 ) ;
if ( cur - > c2 ! = NULL ) xmlFreeElementContent ( cur - > c2 ) ;
1999-09-23 22:19:22 +00:00
if ( cur - > name ! = NULL ) xmlFree ( ( xmlChar * ) cur - > name ) ;
1999-02-22 10:33:01 +00:00
memset ( cur , - 1 , sizeof ( xmlElementContent ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( cur ) ;
1999-01-17 19:11:59 +00:00
}
1999-02-01 12:18:54 +00:00
/**
* xmlDumpElementContent :
1999-04-21 20:12:07 +00:00
* @ buf : An XML buffer
1999-02-01 12:18:54 +00:00
* @ content : An element table
* @ glob : 1 if one must print the englobing parenthesis , 0 otherwise
*
* This will dump the content of the element table as an XML DTD definition
*/
void
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( xmlBufferPtr buf , xmlElementContentPtr content , int glob ) {
1999-02-01 12:18:54 +00:00
if ( content = = NULL ) return ;
1999-04-21 20:12:07 +00:00
if ( glob ) xmlBufferWriteChar ( buf , " ( " ) ;
1999-02-01 12:18:54 +00:00
switch ( content - > type ) {
case XML_ELEMENT_CONTENT_PCDATA :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " #PCDATA " ) ;
1999-02-01 12:18:54 +00:00
break ;
case XML_ELEMENT_CONTENT_ELEMENT :
1999-04-21 20:12:07 +00:00
xmlBufferWriteCHAR ( buf , content - > name ) ;
1999-02-01 12:18:54 +00:00
break ;
case XML_ELEMENT_CONTENT_SEQ :
if ( ( content - > c1 - > type = = XML_ELEMENT_CONTENT_OR ) | |
( content - > c1 - > type = = XML_ELEMENT_CONTENT_SEQ ) )
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c1 , 1 ) ;
1999-02-01 12:18:54 +00:00
else
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c1 , 0 ) ;
xmlBufferWriteChar ( buf , " , " ) ;
1999-02-01 12:18:54 +00:00
if ( content - > c2 - > type = = XML_ELEMENT_CONTENT_OR )
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c2 , 1 ) ;
1999-02-01 12:18:54 +00:00
else
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c2 , 0 ) ;
1999-02-01 12:18:54 +00:00
break ;
case XML_ELEMENT_CONTENT_OR :
if ( ( content - > c1 - > type = = XML_ELEMENT_CONTENT_OR ) | |
( content - > c1 - > type = = XML_ELEMENT_CONTENT_SEQ ) )
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c1 , 1 ) ;
1999-02-01 12:18:54 +00:00
else
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c1 , 0 ) ;
xmlBufferWriteChar ( buf , " | " ) ;
1999-02-01 12:18:54 +00:00
if ( content - > c2 - > type = = XML_ELEMENT_CONTENT_SEQ )
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c2 , 1 ) ;
1999-02-01 12:18:54 +00:00
else
1999-04-21 20:12:07 +00:00
xmlDumpElementContent ( buf , content - > c2 , 0 ) ;
1999-02-01 12:18:54 +00:00
break ;
default :
fprintf ( stderr , " xmlDumpElementContent: unknown type %d \n " ,
content - > type ) ;
}
if ( glob )
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " ) " ) ;
1999-02-01 12:18:54 +00:00
switch ( content - > ocur ) {
case XML_ELEMENT_CONTENT_ONCE :
break ;
case XML_ELEMENT_CONTENT_OPT :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " ? " ) ;
1999-02-01 12:18:54 +00:00
break ;
case XML_ELEMENT_CONTENT_MULT :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " * " ) ;
1999-02-01 12:18:54 +00:00
break ;
case XML_ELEMENT_CONTENT_PLUS :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " + " ) ;
1999-02-01 12:18:54 +00:00
break ;
}
}
1999-08-10 19:04:08 +00:00
/**
* xmlSprintfElementContent :
* @ buf : an output buffer
* @ content : An element table
* @ glob : 1 if one must print the englobing parenthesis , 0 otherwise
*
* This will dump the content of the element content definition
* Intended just for the debug routine
*/
void
xmlSprintfElementContent ( char * buf , xmlElementContentPtr content , int glob ) {
if ( content = = NULL ) return ;
if ( glob ) strcat ( buf , " ( " ) ;
switch ( content - > type ) {
case XML_ELEMENT_CONTENT_PCDATA :
strcat ( buf , " #PCDATA " ) ;
break ;
case XML_ELEMENT_CONTENT_ELEMENT :
1999-08-29 21:02:19 +00:00
strcat ( buf , ( char * ) content - > name ) ;
1999-08-10 19:04:08 +00:00
break ;
case XML_ELEMENT_CONTENT_SEQ :
if ( ( content - > c1 - > type = = XML_ELEMENT_CONTENT_OR ) | |
( content - > c1 - > type = = XML_ELEMENT_CONTENT_SEQ ) )
xmlSprintfElementContent ( buf , content - > c1 , 1 ) ;
else
xmlSprintfElementContent ( buf , content - > c1 , 0 ) ;
strcat ( buf , " , " ) ;
if ( content - > c2 - > type = = XML_ELEMENT_CONTENT_OR )
xmlSprintfElementContent ( buf , content - > c2 , 1 ) ;
else
xmlSprintfElementContent ( buf , content - > c2 , 0 ) ;
break ;
case XML_ELEMENT_CONTENT_OR :
if ( ( content - > c1 - > type = = XML_ELEMENT_CONTENT_OR ) | |
( content - > c1 - > type = = XML_ELEMENT_CONTENT_SEQ ) )
xmlSprintfElementContent ( buf , content - > c1 , 1 ) ;
else
xmlSprintfElementContent ( buf , content - > c1 , 0 ) ;
strcat ( buf , " | " ) ;
if ( content - > c2 - > type = = XML_ELEMENT_CONTENT_SEQ )
xmlSprintfElementContent ( buf , content - > c2 , 1 ) ;
else
xmlSprintfElementContent ( buf , content - > c2 , 0 ) ;
break ;
}
if ( glob )
strcat ( buf , " ) " ) ;
switch ( content - > ocur ) {
case XML_ELEMENT_CONTENT_ONCE :
break ;
case XML_ELEMENT_CONTENT_OPT :
strcat ( buf , " ? " ) ;
break ;
case XML_ELEMENT_CONTENT_MULT :
strcat ( buf , " * " ) ;
break ;
case XML_ELEMENT_CONTENT_PLUS :
strcat ( buf , " + " ) ;
break ;
}
}
1999-01-17 19:11:59 +00:00
/****************************************************************
* *
* Registration of DTD declarations *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-01-31 22:15:06 +00:00
/**
* xmlCreateElementTable :
*
* create and initialize an empty element hash table .
*
1999-02-22 10:33:01 +00:00
* Returns the xmlElementTablePtr just created or NULL in case of error .
1999-01-31 22:15:06 +00:00
*/
xmlElementTablePtr
xmlCreateElementTable ( void ) {
xmlElementTablePtr ret ;
ret = ( xmlElementTablePtr )
1999-09-02 22:04:43 +00:00
xmlMalloc ( sizeof ( xmlElementTable ) ) ;
1999-01-31 22:15:06 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateElementTable : xmlMalloc(%ld) failed \n " ,
1999-07-05 16:50:46 +00:00
( long ) sizeof ( xmlElementTable ) ) ;
1999-01-31 22:15:06 +00:00
return ( NULL ) ;
}
1999-02-22 10:33:01 +00:00
ret - > max_elements = XML_MIN_ELEMENT_TABLE ;
1999-01-31 22:15:06 +00:00
ret - > nb_elements = 0 ;
1999-08-10 19:04:08 +00:00
ret - > table = ( xmlElementPtr * )
1999-09-02 22:04:43 +00:00
xmlMalloc ( ret - > max_elements * sizeof ( xmlElementPtr ) ) ;
1999-01-31 22:15:06 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateElementTable : xmlMalloc(%ld) failed \n " ,
1999-07-05 16:50:46 +00:00
ret - > max_elements * ( long ) sizeof ( xmlElement ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-01-31 22:15:06 +00:00
return ( NULL ) ;
}
return ( ret ) ;
}
1999-01-17 19:11:59 +00:00
/**
* xmlAddElementDecl :
1999-10-08 09:40:39 +00:00
* @ ctxt : the validation context
1999-02-22 10:33:01 +00:00
* @ dtd : pointer to the DTD
1999-01-17 19:11:59 +00:00
* @ name : the entity name
1999-02-22 10:33:01 +00:00
* @ type : the element type
* @ content : the element content tree or NULL
1999-01-17 19:11:59 +00:00
*
* Register a new element declaration
*
1999-02-22 10:33:01 +00:00
* Returns NULL if not , othervise the entity
1999-01-17 19:11:59 +00:00
*/
xmlElementPtr
1999-09-23 22:19:22 +00:00
xmlAddElementDecl ( xmlValidCtxtPtr ctxt , xmlDtdPtr dtd , const xmlChar * name ,
1999-11-12 17:02:31 +00:00
xmlElementTypeVal type , xmlElementContentPtr content ) {
1999-01-31 22:15:06 +00:00
xmlElementPtr ret , cur ;
xmlElementTablePtr table ;
int i ;
1999-01-17 19:11:59 +00:00
if ( dtd = = NULL ) {
fprintf ( stderr , " xmlAddElementDecl: dtd == NULL \n " ) ;
return ( NULL ) ;
}
if ( name = = NULL ) {
fprintf ( stderr , " xmlAddElementDecl: name == NULL \n " ) ;
return ( NULL ) ;
}
switch ( type ) {
case XML_ELEMENT_TYPE_EMPTY :
if ( content ! = NULL ) {
fprintf ( stderr ,
" xmlAddElementDecl: content != NULL for EMPTY \n " ) ;
return ( NULL ) ;
}
break ;
case XML_ELEMENT_TYPE_ANY :
if ( content ! = NULL ) {
fprintf ( stderr ,
" xmlAddElementDecl: content != NULL for ANY \n " ) ;
return ( NULL ) ;
}
break ;
case XML_ELEMENT_TYPE_MIXED :
if ( content = = NULL ) {
fprintf ( stderr ,
" xmlAddElementDecl: content == NULL for MIXED \n " ) ;
return ( NULL ) ;
}
break ;
case XML_ELEMENT_TYPE_ELEMENT :
if ( content = = NULL ) {
fprintf ( stderr ,
" xmlAddElementDecl: content == NULL for ELEMENT \n " ) ;
return ( NULL ) ;
}
break ;
default :
fprintf ( stderr , " xmlAddElementDecl: unknown type %d \n " , type ) ;
return ( NULL ) ;
}
1999-01-31 22:15:06 +00:00
/*
* Create the Element table if needed .
*/
table = dtd - > elements ;
if ( table = = NULL )
table = dtd - > elements = xmlCreateElementTable ( ) ;
if ( table = = NULL ) {
fprintf ( stderr , " xmlAddElementDecl: Table creation failed! \n " ) ;
return ( NULL ) ;
}
1999-01-17 19:11:59 +00:00
/*
* Validity Check :
* Search the DTD for previous declarations of the ELEMENT
*/
1999-01-31 22:15:06 +00:00
for ( i = 0 ; i < table - > nb_elements ; i + + ) {
1999-08-10 19:04:08 +00:00
cur = table - > table [ i ] ;
1999-01-31 22:15:06 +00:00
if ( ! xmlStrcmp ( cur - > name , name ) ) {
/*
* The element is already defined in this Dtd .
*/
1999-08-10 19:04:08 +00:00
VERROR ( ctxt - > userData , " Redefinition of element %s \n " , name ) ;
1999-01-31 22:15:06 +00:00
return ( NULL ) ;
}
}
1999-01-17 19:11:59 +00:00
/*
1999-01-31 22:15:06 +00:00
* Grow the table , if needed .
1999-01-17 19:11:59 +00:00
*/
1999-01-31 22:15:06 +00:00
if ( table - > nb_elements > = table - > max_elements ) {
/*
* need more elements .
*/
table - > max_elements * = 2 ;
1999-08-10 19:04:08 +00:00
table - > table = ( xmlElementPtr * )
1999-09-02 22:04:43 +00:00
xmlRealloc ( table - > table , table - > max_elements * sizeof ( xmlElementPtr ) ) ;
1999-08-10 19:04:08 +00:00
if ( table - > table = = NULL ) {
1999-01-31 22:15:06 +00:00
fprintf ( stderr , " xmlAddElementDecl: out of memory \n " ) ;
return ( NULL ) ;
}
1999-01-17 19:11:59 +00:00
}
1999-09-02 22:04:43 +00:00
ret = ( xmlElementPtr ) xmlMalloc ( sizeof ( xmlElement ) ) ;
1999-08-10 19:04:08 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlAddElementDecl: out of memory \n " ) ;
return ( NULL ) ;
}
table - > table [ table - > nb_elements ] = ret ;
1999-01-31 22:15:06 +00:00
/*
* fill the structure .
*/
1999-01-17 19:11:59 +00:00
ret - > type = type ;
ret - > name = xmlStrdup ( name ) ;
1999-06-22 21:49:07 +00:00
ret - > content = xmlCopyElementContent ( content ) ;
1999-08-10 19:04:08 +00:00
ret - > attributes = xmlScanAttributeDecl ( dtd , name ) ;
1999-01-31 22:15:06 +00:00
table - > nb_elements + + ;
1999-01-17 19:11:59 +00:00
1999-01-31 22:15:06 +00:00
return ( ret ) ;
}
1999-01-17 19:11:59 +00:00
1999-01-31 22:15:06 +00:00
/**
* xmlFreeElement :
* @ elem : An element
*
* Deallocate the memory used by an element definition
*/
void
xmlFreeElement ( xmlElementPtr elem ) {
if ( elem = = NULL ) return ;
xmlFreeElementContent ( elem - > content ) ;
if ( elem - > name ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) elem - > name ) ;
1999-01-31 22:15:06 +00:00
memset ( elem , - 1 , sizeof ( xmlElement ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( elem ) ;
1999-01-31 22:15:06 +00:00
}
/**
* xmlFreeElementTable :
* @ table : An element table
*
1999-02-22 10:33:01 +00:00
* Deallocate the memory used by an element hash table .
1999-01-31 22:15:06 +00:00
*/
void
xmlFreeElementTable ( xmlElementTablePtr table ) {
int i ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_elements ; i + + ) {
1999-08-10 19:04:08 +00:00
xmlFreeElement ( table - > table [ i ] ) ;
1999-01-31 22:15:06 +00:00
}
1999-09-02 22:04:43 +00:00
xmlFree ( table - > table ) ;
xmlFree ( table ) ;
1999-01-31 22:15:06 +00:00
}
/**
* xmlCopyElementTable :
* @ table : An element table
*
* Build a copy of an element table .
*
1999-02-22 10:33:01 +00:00
* Returns the new xmlElementTablePtr or NULL in case of error .
1999-01-31 22:15:06 +00:00
*/
xmlElementTablePtr
xmlCopyElementTable ( xmlElementTablePtr table ) {
xmlElementTablePtr ret ;
xmlElementPtr cur , ent ;
int i ;
1999-09-02 22:04:43 +00:00
ret = ( xmlElementTablePtr ) xmlMalloc ( sizeof ( xmlElementTable ) ) ;
1999-01-31 22:15:06 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlCopyElementTable: out of memory ! \n " ) ;
return ( NULL ) ;
}
1999-09-02 22:04:43 +00:00
ret - > table = ( xmlElementPtr * ) xmlMalloc ( table - > max_elements *
1999-08-10 19:04:08 +00:00
sizeof ( xmlElementPtr ) ) ;
1999-01-31 22:15:06 +00:00
if ( ret - > table = = NULL ) {
fprintf ( stderr , " xmlCopyElementTable: out of memory ! \n " ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-01-31 22:15:06 +00:00
return ( NULL ) ;
}
ret - > max_elements = table - > max_elements ;
ret - > nb_elements = table - > nb_elements ;
for ( i = 0 ; i < ret - > nb_elements ; i + + ) {
1999-09-02 22:04:43 +00:00
cur = ( xmlElementPtr ) xmlMalloc ( sizeof ( xmlElement ) ) ;
1999-08-10 19:04:08 +00:00
if ( cur = = NULL ) {
fprintf ( stderr , " xmlCopyElementTable: out of memory ! \n " ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
xmlFree ( ret - > table ) ;
1999-08-10 19:04:08 +00:00
return ( NULL ) ;
}
ret - > table [ i ] = cur ;
ent = table - > table [ i ] ;
1999-01-31 22:15:06 +00:00
cur - > type = ent - > type ;
if ( ent - > name ! = NULL )
cur - > name = xmlStrdup ( ent - > name ) ;
else
cur - > name = NULL ;
cur - > content = xmlCopyElementContent ( ent - > content ) ;
1999-12-28 16:35:14 +00:00
/* TODO : rebuild the attribute list on the copy */
1999-08-10 19:04:08 +00:00
cur - > attributes = NULL ;
1999-01-31 22:15:06 +00:00
}
1999-01-17 19:11:59 +00:00
return ( ret ) ;
}
1999-01-31 22:15:06 +00:00
/**
* xmlDumpElementTable :
1999-06-02 17:44:04 +00:00
* @ buf : the XML buffer output
1999-01-31 22:15:06 +00:00
* @ table : An element table
*
* This will dump the content of the element table as an XML DTD definition
*/
void
1999-04-21 20:12:07 +00:00
xmlDumpElementTable ( xmlBufferPtr buf , xmlElementTablePtr table ) {
1999-01-31 22:15:06 +00:00
int i ;
xmlElementPtr cur ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_elements ; i + + ) {
1999-08-10 19:04:08 +00:00
cur = table - > table [ i ] ;
1999-01-31 22:15:06 +00:00
switch ( cur - > type ) {
case XML_ELEMENT_TYPE_EMPTY :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " <!ELEMENT " ) ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
xmlBufferWriteChar ( buf , " EMPTY> \n " ) ;
1999-01-31 22:15:06 +00:00
break ;
case XML_ELEMENT_TYPE_ANY :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " <!ELEMENT " ) ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
xmlBufferWriteChar ( buf , " ANY> \n " ) ;
1999-01-31 22:15:06 +00:00
break ;
case XML_ELEMENT_TYPE_MIXED :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " <!ELEMENT " ) ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
xmlBufferWriteChar ( buf , " " ) ;
xmlDumpElementContent ( buf , cur - > content , 1 ) ;
xmlBufferWriteChar ( buf , " > \n " ) ;
1999-01-31 22:15:06 +00:00
break ;
case XML_ELEMENT_TYPE_ELEMENT :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " <!ELEMENT " ) ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
xmlBufferWriteChar ( buf , " " ) ;
xmlDumpElementContent ( buf , cur - > content , 1 ) ;
xmlBufferWriteChar ( buf , " > \n " ) ;
1999-01-31 22:15:06 +00:00
break ;
default :
fprintf ( stderr ,
" xmlDumpElementTable: internal: unknown type %d \n " ,
cur - > type ) ;
}
}
}
1999-02-22 10:33:01 +00:00
/**
* xmlCreateEnumeration :
* @ name : the enumeration name or NULL
*
* create and initialize an enumeration attribute node .
*
* Returns the xmlEnumerationPtr just created or NULL in case
* of error .
*/
xmlEnumerationPtr
1999-09-23 22:19:22 +00:00
xmlCreateEnumeration ( xmlChar * name ) {
1999-02-22 10:33:01 +00:00
xmlEnumerationPtr ret ;
1999-09-02 22:04:43 +00:00
ret = ( xmlEnumerationPtr ) xmlMalloc ( sizeof ( xmlEnumeration ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateEnumeration : xmlMalloc(%ld) failed \n " ,
1999-07-05 16:50:46 +00:00
( long ) sizeof ( xmlEnumeration ) ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
if ( name ! = NULL )
ret - > name = xmlStrdup ( name ) ;
else
ret - > name = NULL ;
ret - > next = NULL ;
return ( ret ) ;
}
/**
* xmlFreeEnumeration :
* @ cur : the tree to free .
*
* free an enumeration attribute node ( recursive ) .
*/
void
xmlFreeEnumeration ( xmlEnumerationPtr cur ) {
if ( cur = = NULL ) return ;
if ( cur - > next ! = NULL ) xmlFreeEnumeration ( cur - > next ) ;
1999-09-23 22:19:22 +00:00
if ( cur - > name ! = NULL ) xmlFree ( ( xmlChar * ) cur - > name ) ;
1999-02-22 10:33:01 +00:00
memset ( cur , - 1 , sizeof ( xmlEnumeration ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( cur ) ;
1999-02-22 10:33:01 +00:00
}
/**
* xmlCopyEnumeration :
* @ cur : the tree to copy .
*
* Copy an enumeration attribute node ( recursive ) .
*
* Returns the xmlEnumerationPtr just created or NULL in case
* of error .
*/
xmlEnumerationPtr
xmlCopyEnumeration ( xmlEnumerationPtr cur ) {
xmlEnumerationPtr ret ;
if ( cur = = NULL ) return ( NULL ) ;
1999-09-23 22:19:22 +00:00
ret = xmlCreateEnumeration ( ( xmlChar * ) cur - > name ) ;
1999-02-22 10:33:01 +00:00
if ( cur - > next ! = NULL ) ret - > next = xmlCopyEnumeration ( cur - > next ) ;
else ret - > next = NULL ;
return ( ret ) ;
}
1999-08-10 19:04:08 +00:00
/**
* xmlDumpEnumeration :
* @ buf : the XML buffer output
* @ enum : An enumeration
*
* This will dump the content of the enumeration
*/
void
xmlDumpEnumeration ( xmlBufferPtr buf , xmlEnumerationPtr cur ) {
if ( cur = = NULL ) return ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
if ( cur - > next = = NULL )
xmlBufferWriteChar ( buf , " ) " ) ;
else {
xmlBufferWriteChar ( buf , " | " ) ;
xmlDumpEnumeration ( buf , cur - > next ) ;
}
}
1999-02-22 10:33:01 +00:00
/**
* xmlCreateAttributeTable :
*
* create and initialize an empty attribute hash table .
*
* Returns the xmlAttributeTablePtr just created or NULL in case
* of error .
*/
xmlAttributeTablePtr
xmlCreateAttributeTable ( void ) {
xmlAttributeTablePtr ret ;
ret = ( xmlAttributeTablePtr )
1999-09-02 22:04:43 +00:00
xmlMalloc ( sizeof ( xmlAttributeTable ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateAttributeTable : xmlMalloc(%ld) failed \n " ,
1999-07-05 16:50:46 +00:00
( long ) sizeof ( xmlAttributeTable ) ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
ret - > max_attributes = XML_MIN_ATTRIBUTE_TABLE ;
ret - > nb_attributes = 0 ;
1999-08-10 19:04:08 +00:00
ret - > table = ( xmlAttributePtr * )
1999-09-02 22:04:43 +00:00
xmlMalloc ( ret - > max_attributes * sizeof ( xmlAttributePtr ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateAttributeTable : xmlMalloc(%ld) failed \n " ,
1999-08-10 19:04:08 +00:00
ret - > max_attributes * ( long ) sizeof ( xmlAttributePtr ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
return ( ret ) ;
}
1999-08-10 19:04:08 +00:00
/**
* xmlScanAttributeDecl :
* @ dtd : pointer to the DTD
* @ elem : the element name
*
* When inserting a new element scan the DtD for existing attributes
* for taht element and initialize the Attribute chain
*
* Returns the pointer to the first attribute decl in the chain ,
* possibly NULL .
*/
xmlAttributePtr
1999-09-23 22:19:22 +00:00
xmlScanAttributeDecl ( xmlDtdPtr dtd , const xmlChar * elem ) {
1999-08-10 19:04:08 +00:00
xmlAttributePtr ret = NULL ;
xmlAttributeTablePtr table ;
int i ;
if ( dtd = = NULL ) {
fprintf ( stderr , " xmlScanAttributeDecl: dtd == NULL \n " ) ;
return ( NULL ) ;
}
if ( elem = = NULL ) {
fprintf ( stderr , " xmlScanAttributeDecl: elem == NULL \n " ) ;
return ( NULL ) ;
}
table = dtd - > attributes ;
if ( table = = NULL )
return ( NULL ) ;
for ( i = 0 ; i < table - > nb_attributes ; i + + ) {
if ( ! xmlStrcmp ( table - > table [ i ] - > elem , elem ) ) {
table - > table [ i ] - > next = ret ;
ret = table - > table [ i ] ;
}
}
return ( ret ) ;
}
/**
* xmlScanIDAttributeDecl :
* @ ctxt : the validation context
* @ elem : the element name
*
* Veryfy that the element don ' t have too many ID attributes
* declared .
*
* Returns the number of ID attributes found .
*/
int
xmlScanIDAttributeDecl ( xmlValidCtxtPtr ctxt , xmlElementPtr elem ) {
xmlAttributePtr cur ;
int ret = 0 ;
if ( elem = = NULL ) return ( 0 ) ;
cur = elem - > attributes ;
while ( cur ! = NULL ) {
if ( cur - > type = = XML_ATTRIBUTE_ID ) {
ret + + ;
if ( ret > 1 )
VERROR ( ctxt - > userData ,
" Element %s has too may ID attributes defined : %s \n " ,
elem - > name , cur - > name ) ;
}
cur = cur - > next ;
}
return ( ret ) ;
}
1999-02-22 10:33:01 +00:00
/**
* xmlAddAttributeDecl :
1999-08-10 19:04:08 +00:00
* @ ctxt : the validation context
1999-02-22 10:33:01 +00:00
* @ dtd : pointer to the DTD
* @ elem : the element name
* @ name : the attribute name
* @ type : the attribute type
* @ def : the attribute default type
* @ defaultValue : the attribute default value
* @ tree : if it ' s an enumeration , the associated list
*
* Register a new attribute declaration
*
* Returns NULL if not , othervise the entity
*/
xmlAttributePtr
1999-09-23 22:19:22 +00:00
xmlAddAttributeDecl ( xmlValidCtxtPtr ctxt , xmlDtdPtr dtd , const xmlChar * elem ,
const xmlChar * name , xmlAttributeType type ,
xmlAttributeDefault def , const xmlChar * defaultValue ,
1999-08-30 11:23:51 +00:00
xmlEnumerationPtr tree ) {
1999-02-22 10:33:01 +00:00
xmlAttributePtr ret , cur ;
xmlAttributeTablePtr table ;
1999-08-10 19:04:08 +00:00
xmlElementPtr elemDef ;
1999-12-12 13:03:50 +00:00
xmlChar * rname ;
xmlChar * ns ;
1999-02-22 10:33:01 +00:00
int i ;
if ( dtd = = NULL ) {
fprintf ( stderr , " xmlAddAttributeDecl: dtd == NULL \n " ) ;
return ( NULL ) ;
}
if ( name = = NULL ) {
fprintf ( stderr , " xmlAddAttributeDecl: name == NULL \n " ) ;
return ( NULL ) ;
}
if ( elem = = NULL ) {
fprintf ( stderr , " xmlAddAttributeDecl: elem == NULL \n " ) ;
return ( NULL ) ;
}
1999-08-29 21:02:19 +00:00
/*
* Check the type and possibly the default value .
*/
1999-02-22 10:33:01 +00:00
switch ( type ) {
case XML_ATTRIBUTE_CDATA :
break ;
case XML_ATTRIBUTE_ID :
break ;
case XML_ATTRIBUTE_IDREF :
break ;
case XML_ATTRIBUTE_IDREFS :
break ;
case XML_ATTRIBUTE_ENTITY :
break ;
case XML_ATTRIBUTE_ENTITIES :
break ;
case XML_ATTRIBUTE_NMTOKEN :
break ;
case XML_ATTRIBUTE_NMTOKENS :
break ;
case XML_ATTRIBUTE_ENUMERATION :
break ;
case XML_ATTRIBUTE_NOTATION :
break ;
default :
fprintf ( stderr , " xmlAddAttributeDecl: unknown type %d \n " , type ) ;
return ( NULL ) ;
}
1999-08-29 21:02:19 +00:00
if ( ( defaultValue ! = NULL ) & &
( ! xmlValidateAttributeValue ( type , defaultValue ) ) ) {
VERROR ( ctxt - > userData , " Attribute %s on %s: invalid default value \n " ,
elem , name , defaultValue ) ;
defaultValue = NULL ;
}
1999-02-22 10:33:01 +00:00
/*
* Create the Attribute table if needed .
*/
table = dtd - > attributes ;
if ( table = = NULL )
table = dtd - > attributes = xmlCreateAttributeTable ( ) ;
if ( table = = NULL ) {
fprintf ( stderr , " xmlAddAttributeDecl: Table creation failed! \n " ) ;
return ( NULL ) ;
}
1999-12-12 13:03:50 +00:00
/*
* Split the full name into a namespace prefix and the tag name
*/
rname = xmlSplitQName ( name , & ns ) ;
1999-02-22 10:33:01 +00:00
/*
* Validity Check :
* Search the DTD for previous declarations of the ATTLIST
*/
for ( i = 0 ; i < table - > nb_attributes ; i + + ) {
1999-08-10 19:04:08 +00:00
cur = table - > table [ i ] ;
1999-12-12 13:03:50 +00:00
if ( ( ns ! = NULL ) & & ( cur - > prefix = = NULL ) ) continue ;
if ( ( ns = = NULL ) & & ( cur - > prefix ! = NULL ) ) continue ;
if ( ( ! xmlStrcmp ( cur - > name , rname ) ) & & ( ! xmlStrcmp ( cur - > elem , elem ) ) & &
( ( ns = = NULL ) | | ( ! xmlStrcmp ( cur - > prefix , ns ) ) ) ) {
1999-02-22 10:33:01 +00:00
/*
* The attribute is already defined in this Dtd .
*/
1999-08-29 21:02:19 +00:00
VERROR ( ctxt - > userData , " Attribute %s on %s: already defined \n " ,
elem , name ) ;
1999-02-22 10:33:01 +00:00
}
}
/*
* Grow the table , if needed .
*/
if ( table - > nb_attributes > = table - > max_attributes ) {
/*
* need more attributes .
*/
table - > max_attributes * = 2 ;
1999-08-10 19:04:08 +00:00
table - > table = ( xmlAttributePtr * )
1999-09-02 22:04:43 +00:00
xmlRealloc ( table - > table , table - > max_attributes *
1999-08-10 19:04:08 +00:00
sizeof ( xmlAttributePtr ) ) ;
if ( table - > table = = NULL ) {
1999-02-22 10:33:01 +00:00
fprintf ( stderr , " xmlAddAttributeDecl: out of memory \n " ) ;
return ( NULL ) ;
}
}
1999-09-02 22:04:43 +00:00
ret = ( xmlAttributePtr ) xmlMalloc ( sizeof ( xmlAttribute ) ) ;
1999-08-10 19:04:08 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlAddAttributeDecl: out of memory \n " ) ;
return ( NULL ) ;
}
table - > table [ table - > nb_attributes ] = ret ;
1999-02-22 10:33:01 +00:00
/*
* fill the structure .
*/
ret - > type = type ;
1999-12-12 13:03:50 +00:00
ret - > name = rname ;
ret - > prefix = ns ;
1999-02-22 10:33:01 +00:00
ret - > elem = xmlStrdup ( elem ) ;
ret - > def = def ;
ret - > tree = tree ;
if ( defaultValue ! = NULL )
ret - > defaultValue = xmlStrdup ( defaultValue ) ;
else
ret - > defaultValue = NULL ;
1999-08-10 19:04:08 +00:00
elemDef = xmlGetDtdElementDesc ( dtd , elem ) ;
if ( elemDef ! = NULL ) {
if ( ( type = = XML_ATTRIBUTE_ID ) & &
( xmlScanIDAttributeDecl ( NULL , elemDef ) ! = 0 ) )
VERROR ( ctxt - > userData ,
" Element %s has too may ID attributes defined : %s \n " ,
elem , name ) ;
ret - > next = elemDef - > attributes ;
elemDef - > attributes = ret ;
}
1999-02-22 10:33:01 +00:00
table - > nb_attributes + + ;
return ( ret ) ;
}
/**
* xmlFreeAttribute :
* @ elem : An attribute
*
* Deallocate the memory used by an attribute definition
*/
void
xmlFreeAttribute ( xmlAttributePtr attr ) {
if ( attr = = NULL ) return ;
if ( attr - > tree ! = NULL )
xmlFreeEnumeration ( attr - > tree ) ;
if ( attr - > elem ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) attr - > elem ) ;
1999-02-22 10:33:01 +00:00
if ( attr - > name ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) attr - > name ) ;
1999-02-22 10:33:01 +00:00
if ( attr - > defaultValue ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) attr - > defaultValue ) ;
1999-12-12 13:03:50 +00:00
if ( attr - > prefix ! = NULL )
xmlFree ( ( xmlChar * ) attr - > prefix ) ;
1999-02-22 10:33:01 +00:00
memset ( attr , - 1 , sizeof ( xmlAttribute ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( attr ) ;
1999-02-22 10:33:01 +00:00
}
/**
* xmlFreeAttributeTable :
* @ table : An attribute table
*
* Deallocate the memory used by an entities hash table .
*/
void
xmlFreeAttributeTable ( xmlAttributeTablePtr table ) {
int i ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_attributes ; i + + ) {
1999-08-10 19:04:08 +00:00
xmlFreeAttribute ( table - > table [ i ] ) ;
1999-02-22 10:33:01 +00:00
}
1999-09-02 22:04:43 +00:00
xmlFree ( table - > table ) ;
xmlFree ( table ) ;
1999-02-22 10:33:01 +00:00
}
/**
* xmlCopyAttributeTable :
* @ table : An attribute table
*
* Build a copy of an attribute table .
*
* Returns the new xmlAttributeTablePtr or NULL in case of error .
*/
xmlAttributeTablePtr
xmlCopyAttributeTable ( xmlAttributeTablePtr table ) {
xmlAttributeTablePtr ret ;
xmlAttributePtr cur , attr ;
int i ;
1999-09-02 22:04:43 +00:00
ret = ( xmlAttributeTablePtr ) xmlMalloc ( sizeof ( xmlAttributeTable ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlCopyAttributeTable: out of memory ! \n " ) ;
return ( NULL ) ;
}
1999-09-02 22:04:43 +00:00
ret - > table = ( xmlAttributePtr * ) xmlMalloc ( table - > max_attributes *
1999-08-10 19:04:08 +00:00
sizeof ( xmlAttributePtr ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret - > table = = NULL ) {
fprintf ( stderr , " xmlCopyAttributeTable: out of memory ! \n " ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
ret - > max_attributes = table - > max_attributes ;
ret - > nb_attributes = table - > nb_attributes ;
for ( i = 0 ; i < ret - > nb_attributes ; i + + ) {
1999-08-10 19:04:08 +00:00
attr = table - > table [ i ] ;
1999-09-02 22:04:43 +00:00
cur = ( xmlAttributePtr ) xmlMalloc ( sizeof ( xmlAttribute ) ) ;
1999-08-10 19:04:08 +00:00
if ( cur = = NULL ) {
fprintf ( stderr , " xmlCopyAttributeTable: out of memory ! \n " ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
xmlFree ( ret - > table ) ;
1999-08-10 19:04:08 +00:00
return ( NULL ) ;
}
ret - > table [ i ] = cur ;
1999-02-22 10:33:01 +00:00
cur - > type = attr - > type ;
cur - > def = attr - > def ;
cur - > tree = xmlCopyEnumeration ( attr - > tree ) ;
if ( attr - > elem ! = NULL )
cur - > elem = xmlStrdup ( attr - > elem ) ;
else
cur - > elem = NULL ;
if ( attr - > name ! = NULL )
cur - > name = xmlStrdup ( attr - > name ) ;
else
cur - > name = NULL ;
if ( attr - > defaultValue ! = NULL )
cur - > defaultValue = xmlStrdup ( attr - > defaultValue ) ;
else
cur - > defaultValue = NULL ;
1999-08-10 19:04:08 +00:00
/* NEED to rebuild the next chain !!!!!! */
1999-02-22 10:33:01 +00:00
}
return ( ret ) ;
}
/**
* xmlDumpAttributeTable :
1999-06-02 17:44:04 +00:00
* @ buf : the XML buffer output
1999-02-22 10:33:01 +00:00
* @ table : An attribute table
*
* This will dump the content of the attribute table as an XML DTD definition
*/
void
1999-04-21 20:12:07 +00:00
xmlDumpAttributeTable ( xmlBufferPtr buf , xmlAttributeTablePtr table ) {
1999-02-22 10:33:01 +00:00
int i ;
xmlAttributePtr cur ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_attributes ; i + + ) {
1999-08-10 19:04:08 +00:00
cur = table - > table [ i ] ;
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " <!ATTLIST " ) ;
xmlBufferWriteCHAR ( buf , cur - > elem ) ;
xmlBufferWriteChar ( buf , " " ) ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
1999-02-22 10:33:01 +00:00
switch ( cur - > type ) {
case XML_ATTRIBUTE_CDATA :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " CDATA " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_ID :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " ID " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_IDREF :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " IDREF " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_IDREFS :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " IDREFS " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_ENTITY :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " ENTITY " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_ENTITIES :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " ENTITIES " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_NMTOKEN :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " NMTOKEN " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_NMTOKENS :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " NMTOKENS " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_ENUMERATION :
1999-08-10 19:04:08 +00:00
xmlBufferWriteChar ( buf , " ( " ) ;
xmlDumpEnumeration ( buf , cur - > tree ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_NOTATION :
1999-08-10 19:04:08 +00:00
xmlBufferWriteChar ( buf , " NOTATION ( " ) ;
xmlDumpEnumeration ( buf , cur - > tree ) ;
1999-02-22 10:33:01 +00:00
break ;
default :
fprintf ( stderr ,
" xmlDumpAttributeTable: internal: unknown type %d \n " ,
cur - > type ) ;
}
switch ( cur - > def ) {
case XML_ATTRIBUTE_NONE :
break ;
case XML_ATTRIBUTE_REQUIRED :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " #REQUIRED " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_IMPLIED :
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " #IMPLIED " ) ;
1999-02-22 10:33:01 +00:00
break ;
case XML_ATTRIBUTE_FIXED :
1999-08-10 19:04:08 +00:00
xmlBufferWriteChar ( buf , " #FIXED " ) ;
1999-02-22 10:33:01 +00:00
break ;
default :
fprintf ( stderr ,
" xmlDumpAttributeTable: internal: unknown default %d \n " ,
cur - > def ) ;
}
1999-08-10 19:04:08 +00:00
if ( cur - > defaultValue ! = NULL ) {
xmlBufferWriteChar ( buf , " " ) ;
xmlBufferWriteQuotedString ( buf , cur - > defaultValue ) ;
}
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " > \n " ) ;
1999-02-22 10:33:01 +00:00
}
}
/************************************************************************
* *
* NOTATIONs *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlCreateNotationTable :
*
* create and initialize an empty notation hash table .
*
* Returns the xmlNotationTablePtr just created or NULL in case
* of error .
*/
xmlNotationTablePtr
xmlCreateNotationTable ( void ) {
xmlNotationTablePtr ret ;
ret = ( xmlNotationTablePtr )
1999-09-02 22:04:43 +00:00
xmlMalloc ( sizeof ( xmlNotationTable ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateNotationTable : xmlMalloc(%ld) failed \n " ,
1999-07-05 16:50:46 +00:00
( long ) sizeof ( xmlNotationTable ) ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
ret - > max_notations = XML_MIN_NOTATION_TABLE ;
ret - > nb_notations = 0 ;
1999-08-10 19:04:08 +00:00
ret - > table = ( xmlNotationPtr * )
1999-09-02 22:04:43 +00:00
xmlMalloc ( ret - > max_notations * sizeof ( xmlNotationPtr ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateNotationTable : xmlMalloc(%ld) failed \n " ,
1999-07-05 16:50:46 +00:00
ret - > max_notations * ( long ) sizeof ( xmlNotation ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlAddNotationDecl :
* @ dtd : pointer to the DTD
1999-08-10 19:04:08 +00:00
* @ ctxt : the validation context
1999-02-22 10:33:01 +00:00
* @ name : the entity name
* @ PublicID : the public identifier or NULL
* @ SystemID : the system identifier or NULL
*
* Register a new notation declaration
*
* Returns NULL if not , othervise the entity
*/
xmlNotationPtr
1999-09-23 22:19:22 +00:00
xmlAddNotationDecl ( xmlValidCtxtPtr ctxt , xmlDtdPtr dtd , const xmlChar * name ,
const xmlChar * PublicID , const xmlChar * SystemID ) {
1999-02-22 10:33:01 +00:00
xmlNotationPtr ret , cur ;
xmlNotationTablePtr table ;
int i ;
if ( dtd = = NULL ) {
fprintf ( stderr , " xmlAddNotationDecl: dtd == NULL \n " ) ;
return ( NULL ) ;
}
if ( name = = NULL ) {
fprintf ( stderr , " xmlAddNotationDecl: name == NULL \n " ) ;
return ( NULL ) ;
}
if ( ( PublicID = = NULL ) & & ( SystemID = = NULL ) ) {
fprintf ( stderr , " xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID \n " ) ;
}
/*
* Create the Notation table if needed .
*/
table = dtd - > notations ;
if ( table = = NULL )
table = dtd - > notations = xmlCreateNotationTable ( ) ;
if ( table = = NULL ) {
fprintf ( stderr , " xmlAddNotationDecl: Table creation failed! \n " ) ;
return ( NULL ) ;
}
/*
* Validity Check :
* Search the DTD for previous declarations of the ATTLIST
*/
for ( i = 0 ; i < table - > nb_notations ; i + + ) {
1999-08-10 19:04:08 +00:00
cur = table - > table [ i ] ;
1999-02-22 10:33:01 +00:00
if ( ! xmlStrcmp ( cur - > name , name ) ) {
/*
* The notation is already defined in this Dtd .
*/
fprintf ( stderr ,
" xmlAddNotationDecl: %s already defined \n " , name ) ;
}
}
/*
* Grow the table , if needed .
*/
if ( table - > nb_notations > = table - > max_notations ) {
/*
* need more notations .
*/
table - > max_notations * = 2 ;
1999-08-10 19:04:08 +00:00
table - > table = ( xmlNotationPtr * )
1999-09-02 22:04:43 +00:00
xmlRealloc ( table - > table , table - > max_notations *
1999-08-10 19:04:08 +00:00
sizeof ( xmlNotationPtr ) ) ;
if ( table - > table = = NULL ) {
1999-02-22 10:33:01 +00:00
fprintf ( stderr , " xmlAddNotationDecl: out of memory \n " ) ;
return ( NULL ) ;
}
}
1999-09-02 22:04:43 +00:00
ret = ( xmlNotationPtr ) xmlMalloc ( sizeof ( xmlNotation ) ) ;
1999-08-10 19:04:08 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlAddNotationDecl: out of memory \n " ) ;
return ( NULL ) ;
}
table - > table [ table - > nb_notations ] = ret ;
1999-02-22 10:33:01 +00:00
/*
* fill the structure .
*/
ret - > name = xmlStrdup ( name ) ;
if ( SystemID ! = NULL )
ret - > SystemID = xmlStrdup ( SystemID ) ;
else
ret - > SystemID = NULL ;
if ( PublicID ! = NULL )
ret - > PublicID = xmlStrdup ( PublicID ) ;
else
ret - > PublicID = NULL ;
table - > nb_notations + + ;
return ( ret ) ;
}
/**
* xmlFreeNotation :
* @ not : A notation
*
* Deallocate the memory used by an notation definition
*/
void
xmlFreeNotation ( xmlNotationPtr nota ) {
if ( nota = = NULL ) return ;
if ( nota - > name ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) nota - > name ) ;
1999-02-22 10:33:01 +00:00
if ( nota - > PublicID ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) nota - > PublicID ) ;
1999-02-22 10:33:01 +00:00
if ( nota - > SystemID ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) nota - > SystemID ) ;
1999-02-22 10:33:01 +00:00
memset ( nota , - 1 , sizeof ( xmlNotation ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( nota ) ;
1999-02-22 10:33:01 +00:00
}
/**
* xmlFreeNotationTable :
* @ table : An notation table
*
* Deallocate the memory used by an entities hash table .
*/
void
xmlFreeNotationTable ( xmlNotationTablePtr table ) {
int i ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_notations ; i + + ) {
1999-08-10 19:04:08 +00:00
xmlFreeNotation ( table - > table [ i ] ) ;
1999-02-22 10:33:01 +00:00
}
1999-09-02 22:04:43 +00:00
xmlFree ( table - > table ) ;
xmlFree ( table ) ;
1999-02-22 10:33:01 +00:00
}
/**
* xmlCopyNotationTable :
* @ table : A notation table
*
* Build a copy of a notation table .
*
* Returns the new xmlNotationTablePtr or NULL in case of error .
*/
xmlNotationTablePtr
xmlCopyNotationTable ( xmlNotationTablePtr table ) {
xmlNotationTablePtr ret ;
xmlNotationPtr cur , nota ;
int i ;
1999-09-02 22:04:43 +00:00
ret = ( xmlNotationTablePtr ) xmlMalloc ( sizeof ( xmlNotationTable ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlCopyNotationTable: out of memory ! \n " ) ;
return ( NULL ) ;
}
1999-09-02 22:04:43 +00:00
ret - > table = ( xmlNotationPtr * ) xmlMalloc ( table - > max_notations *
1999-08-10 19:04:08 +00:00
sizeof ( xmlNotationPtr ) ) ;
1999-02-22 10:33:01 +00:00
if ( ret - > table = = NULL ) {
fprintf ( stderr , " xmlCopyNotationTable: out of memory ! \n " ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-02-22 10:33:01 +00:00
return ( NULL ) ;
}
ret - > max_notations = table - > max_notations ;
ret - > nb_notations = table - > nb_notations ;
for ( i = 0 ; i < ret - > nb_notations ; i + + ) {
1999-09-02 22:04:43 +00:00
cur = ( xmlNotationPtr ) xmlMalloc ( sizeof ( xmlNotation ) ) ;
1999-08-10 19:04:08 +00:00
if ( cur = = NULL ) {
fprintf ( stderr , " xmlCopyNotationTable: out of memory ! \n " ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
xmlFree ( ret - > table ) ;
1999-08-10 19:04:08 +00:00
return ( NULL ) ;
}
ret - > table [ i ] = cur ;
nota = table - > table [ i ] ;
1999-02-22 10:33:01 +00:00
if ( nota - > name ! = NULL )
cur - > name = xmlStrdup ( nota - > name ) ;
else
cur - > name = NULL ;
if ( nota - > PublicID ! = NULL )
cur - > PublicID = xmlStrdup ( nota - > PublicID ) ;
else
cur - > PublicID = NULL ;
if ( nota - > SystemID ! = NULL )
cur - > SystemID = xmlStrdup ( nota - > SystemID ) ;
else
cur - > SystemID = NULL ;
}
return ( ret ) ;
}
/**
* xmlDumpNotationTable :
1999-06-02 17:44:04 +00:00
* @ buf : the XML buffer output
1999-02-22 10:33:01 +00:00
* @ table : A notation table
*
* This will dump the content of the notation table as an XML DTD definition
*/
void
1999-04-21 20:12:07 +00:00
xmlDumpNotationTable ( xmlBufferPtr buf , xmlNotationTablePtr table ) {
1999-02-22 10:33:01 +00:00
int i ;
xmlNotationPtr cur ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_notations ; i + + ) {
1999-08-10 19:04:08 +00:00
cur = table - > table [ i ] ;
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " <!NOTATION " ) ;
xmlBufferWriteCHAR ( buf , cur - > name ) ;
1999-02-22 10:33:01 +00:00
if ( cur - > PublicID ! = NULL ) {
1999-06-02 17:44:04 +00:00
xmlBufferWriteChar ( buf , " PUBLIC " ) ;
xmlBufferWriteQuotedString ( buf , cur - > PublicID ) ;
1999-02-22 10:33:01 +00:00
if ( cur - > SystemID ! = NULL ) {
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " " ) ;
xmlBufferWriteCHAR ( buf , cur - > SystemID ) ;
1999-02-22 10:33:01 +00:00
}
} else {
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " SYSTEM " ) ;
xmlBufferWriteCHAR ( buf , cur - > SystemID ) ;
1999-02-22 10:33:01 +00:00
}
1999-04-21 20:12:07 +00:00
xmlBufferWriteChar ( buf , " > \n " ) ;
1999-02-22 10:33:01 +00:00
}
}
1999-08-10 19:04:08 +00:00
1999-08-15 23:32:28 +00:00
/************************************************************************
* *
1999-09-08 21:35:25 +00:00
* IDs *
1999-08-15 23:32:28 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlCreateIDTable :
*
* create and initialize an empty id hash table .
*
* Returns the xmlIDTablePtr just created or NULL in case
* of error .
*/
xmlIDTablePtr
xmlCreateIDTable ( void ) {
xmlIDTablePtr ret ;
ret = ( xmlIDTablePtr )
1999-09-02 22:04:43 +00:00
xmlMalloc ( sizeof ( xmlIDTable ) ) ;
1999-08-15 23:32:28 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateIDTable : xmlMalloc(%ld) failed \n " ,
1999-08-15 23:32:28 +00:00
( long ) sizeof ( xmlIDTable ) ) ;
return ( NULL ) ;
}
ret - > max_ids = XML_MIN_NOTATION_TABLE ;
ret - > nb_ids = 0 ;
ret - > table = ( xmlIDPtr * )
1999-09-02 22:04:43 +00:00
xmlMalloc ( ret - > max_ids * sizeof ( xmlIDPtr ) ) ;
1999-08-15 23:32:28 +00:00
if ( ret = = NULL ) {
1999-09-02 22:04:43 +00:00
fprintf ( stderr , " xmlCreateIDTable : xmlMalloc(%ld) failed \n " ,
1999-08-15 23:32:28 +00:00
ret - > max_ids * ( long ) sizeof ( xmlID ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( ret ) ;
1999-08-15 23:32:28 +00:00
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlAddID :
* @ ctxt : the validation context
* @ doc : pointer to the document
* @ value : the value name
* @ attr : the attribute holding the ID
*
* Register a new id declaration
*
* Returns NULL if not , othervise the new xmlIDPtr
*/
xmlIDPtr
1999-09-23 22:19:22 +00:00
xmlAddID ( xmlValidCtxtPtr ctxt , xmlDocPtr doc , const xmlChar * value ,
1999-08-15 23:32:28 +00:00
xmlAttrPtr attr ) {
xmlIDPtr ret , cur ;
xmlIDTablePtr table ;
int i ;
if ( doc = = NULL ) {
fprintf ( stderr , " xmlAddIDDecl: doc == NULL \n " ) ;
return ( NULL ) ;
}
if ( value = = NULL ) {
fprintf ( stderr , " xmlAddIDDecl: value == NULL \n " ) ;
return ( NULL ) ;
}
if ( attr = = NULL ) {
fprintf ( stderr , " xmlAddIDDecl: attr == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Create the ID table if needed .
*/
table = doc - > ids ;
if ( table = = NULL )
table = doc - > ids = xmlCreateIDTable ( ) ;
if ( table = = NULL ) {
fprintf ( stderr , " xmlAddID: Table creation failed! \n " ) ;
return ( NULL ) ;
}
/*
* Validity Check :
* Search the DTD for previous declarations of the ATTLIST
*/
for ( i = 0 ; i < table - > nb_ids ; i + + ) {
cur = table - > table [ i ] ;
if ( ! xmlStrcmp ( cur - > value , value ) ) {
/*
* The id is already defined in this Dtd .
*/
VERROR ( ctxt - > userData , " ID %s already defined \n " , value ) ;
return ( NULL ) ;
}
}
/*
* Grow the table , if needed .
*/
if ( table - > nb_ids > = table - > max_ids ) {
/*
* need more ids .
*/
table - > max_ids * = 2 ;
table - > table = ( xmlIDPtr * )
1999-09-02 22:04:43 +00:00
xmlRealloc ( table - > table , table - > max_ids *
1999-08-15 23:32:28 +00:00
sizeof ( xmlIDPtr ) ) ;
if ( table - > table = = NULL ) {
fprintf ( stderr , " xmlAddID: out of memory \n " ) ;
return ( NULL ) ;
}
}
1999-09-02 22:04:43 +00:00
ret = ( xmlIDPtr ) xmlMalloc ( sizeof ( xmlID ) ) ;
1999-08-15 23:32:28 +00:00
if ( ret = = NULL ) {
fprintf ( stderr , " xmlAddID: out of memory \n " ) ;
return ( NULL ) ;
}
table - > table [ table - > nb_ids ] = ret ;
/*
* fill the structure .
*/
ret - > value = xmlStrdup ( value ) ;
ret - > attr = attr ;
table - > nb_ids + + ;
return ( ret ) ;
}
/**
* xmlFreeID :
* @ not : A id
*
* Deallocate the memory used by an id definition
*/
void
xmlFreeID ( xmlIDPtr id ) {
if ( id = = NULL ) return ;
if ( id - > value ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) id - > value ) ;
1999-08-15 23:32:28 +00:00
memset ( id , - 1 , sizeof ( xmlID ) ) ;
1999-09-02 22:04:43 +00:00
xmlFree ( id ) ;
1999-08-15 23:32:28 +00:00
}
/**
* xmlFreeIDTable :
* @ table : An id table
*
* Deallocate the memory used by an ID hash table .
*/
void
xmlFreeIDTable ( xmlIDTablePtr table ) {
int i ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_ids ; i + + ) {
xmlFreeID ( table - > table [ i ] ) ;
}
1999-09-02 22:04:43 +00:00
xmlFree ( table - > table ) ;
xmlFree ( table ) ;
1999-08-15 23:32:28 +00:00
}
/**
* xmlIsID
* @ doc : the document
* @ elem : the element carrying the attribute
* @ attr : the attribute
*
* Determine whether an attribute is of type ID . In case we have Dtd ( s )
* then this is simple , otherwise we use an heuristic : name ID ( upper
* or lowercase ) .
*
* Returns 0 or 1 depending on the lookup result
*/
int
xmlIsID ( xmlDocPtr doc , xmlNodePtr elem , xmlAttrPtr attr ) {
if ( ( doc - > intSubset = = NULL ) & & ( doc - > extSubset = = NULL ) ) {
if ( ( ( attr - > name [ 0 ] = = ' I ' ) | | ( attr - > name [ 0 ] = = ' i ' ) ) & &
( ( attr - > name [ 1 ] = = ' D ' ) | | ( attr - > name [ 1 ] = = ' d ' ) ) & &
( attr - > name [ 2 ] = = 0 ) ) return ( 1 ) ;
} else {
xmlAttributePtr attrDecl ;
attrDecl = xmlGetDtdAttrDesc ( doc - > intSubset , elem - > name , attr - > name ) ;
if ( ( attrDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
attrDecl = xmlGetDtdAttrDesc ( doc - > extSubset , elem - > name ,
attr - > name ) ;
1999-08-29 21:02:19 +00:00
if ( ( attrDecl ! = NULL ) & & ( attrDecl - > type = = XML_ATTRIBUTE_ID ) )
1999-08-15 23:32:28 +00:00
return ( 1 ) ;
}
return ( 0 ) ;
}
1999-08-29 21:02:19 +00:00
/**
* xmlGetID :
* @ doc : pointer to the document
* @ ID : the ID value
*
* Search the attribute declaring the given ID
*
* Returns NULL if not found , otherwise the xmlAttrPtr defining the ID
*/
xmlAttrPtr
1999-09-23 22:19:22 +00:00
xmlGetID ( xmlDocPtr doc , const xmlChar * ID ) {
1999-08-29 21:02:19 +00:00
xmlIDPtr cur ;
xmlIDTablePtr table ;
int i ;
if ( doc = = NULL ) {
fprintf ( stderr , " xmlGetID: doc == NULL \n " ) ;
return ( NULL ) ;
}
if ( ID = = NULL ) {
fprintf ( stderr , " xmlGetID: ID == NULL \n " ) ;
return ( NULL ) ;
}
table = doc - > ids ;
if ( table = = NULL )
return ( NULL ) ;
/*
* Search the ID list .
*/
for ( i = 0 ; i < table - > nb_ids ; i + + ) {
cur = table - > table [ i ] ;
if ( ! xmlStrcmp ( cur - > value , ID ) ) {
return ( cur - > attr ) ;
}
}
return ( NULL ) ;
}
1999-09-08 21:35:25 +00:00
/************************************************************************
* *
* Refs *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlCreateRefTable :
*
* create and initialize an empty ref hash table .
*
* Returns the xmlRefTablePtr just created or NULL in case
* of error .
*/
xmlRefTablePtr
xmlCreateRefTable ( void ) {
xmlRefTablePtr ret ;
ret = ( xmlRefTablePtr )
xmlMalloc ( sizeof ( xmlRefTable ) ) ;
if ( ret = = NULL ) {
fprintf ( stderr , " xmlCreateRefTable : xmlMalloc(%ld) failed \n " ,
( long ) sizeof ( xmlRefTable ) ) ;
return ( NULL ) ;
}
ret - > max_refs = XML_MIN_NOTATION_TABLE ;
ret - > nb_refs = 0 ;
ret - > table = ( xmlRefPtr * )
xmlMalloc ( ret - > max_refs * sizeof ( xmlRefPtr ) ) ;
if ( ret = = NULL ) {
fprintf ( stderr , " xmlCreateRefTable : xmlMalloc(%ld) failed \n " ,
ret - > max_refs * ( long ) sizeof ( xmlRef ) ) ;
xmlFree ( ret ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlAddRef :
* @ ctxt : the validation context
* @ doc : pointer to the document
* @ value : the value name
* @ attr : the attribute holding the Ref
*
* Register a new ref declaration
*
* Returns NULL if not , othervise the new xmlRefPtr
*/
xmlRefPtr
1999-09-23 22:19:22 +00:00
xmlAddRef ( xmlValidCtxtPtr ctxt , xmlDocPtr doc , const xmlChar * value ,
1999-09-08 21:35:25 +00:00
xmlAttrPtr attr ) {
xmlRefPtr ret ;
xmlRefTablePtr table ;
if ( doc = = NULL ) {
fprintf ( stderr , " xmlAddRefDecl: doc == NULL \n " ) ;
return ( NULL ) ;
}
if ( value = = NULL ) {
fprintf ( stderr , " xmlAddRefDecl: value == NULL \n " ) ;
return ( NULL ) ;
}
if ( attr = = NULL ) {
fprintf ( stderr , " xmlAddRefDecl: attr == NULL \n " ) ;
return ( NULL ) ;
}
/*
* Create the Ref table if needed .
*/
table = doc - > refs ;
if ( table = = NULL )
table = doc - > refs = xmlCreateRefTable ( ) ;
if ( table = = NULL ) {
fprintf ( stderr , " xmlAddRef: Table creation failed! \n " ) ;
return ( NULL ) ;
}
/*
* Grow the table , if needed .
*/
if ( table - > nb_refs > = table - > max_refs ) {
/*
* need more refs .
*/
table - > max_refs * = 2 ;
table - > table = ( xmlRefPtr * )
xmlRealloc ( table - > table , table - > max_refs *
sizeof ( xmlRefPtr ) ) ;
if ( table - > table = = NULL ) {
fprintf ( stderr , " xmlAddRef: out of memory \n " ) ;
return ( NULL ) ;
}
}
ret = ( xmlRefPtr ) xmlMalloc ( sizeof ( xmlRef ) ) ;
if ( ret = = NULL ) {
fprintf ( stderr , " xmlAddRef: out of memory \n " ) ;
return ( NULL ) ;
}
table - > table [ table - > nb_refs ] = ret ;
/*
* fill the structure .
*/
ret - > value = xmlStrdup ( value ) ;
ret - > attr = attr ;
table - > nb_refs + + ;
return ( ret ) ;
}
/**
* xmlFreeRef :
* @ not : A ref
*
* Deallocate the memory used by an ref definition
*/
void
xmlFreeRef ( xmlRefPtr ref ) {
if ( ref = = NULL ) return ;
if ( ref - > value ! = NULL )
1999-09-23 22:19:22 +00:00
xmlFree ( ( xmlChar * ) ref - > value ) ;
1999-09-08 21:35:25 +00:00
memset ( ref , - 1 , sizeof ( xmlRef ) ) ;
xmlFree ( ref ) ;
}
/**
* xmlFreeRefTable :
* @ table : An ref table
*
* Deallocate the memory used by an Ref hash table .
*/
void
xmlFreeRefTable ( xmlRefTablePtr table ) {
int i ;
if ( table = = NULL ) return ;
for ( i = 0 ; i < table - > nb_refs ; i + + ) {
xmlFreeRef ( table - > table [ i ] ) ;
}
xmlFree ( table - > table ) ;
xmlFree ( table ) ;
}
/**
* xmlIsRef
* @ doc : the document
* @ elem : the element carrying the attribute
* @ attr : the attribute
*
* Determine whether an attribute is of type Ref . In case we have Dtd ( s )
* then this is simple , otherwise we use an heuristic : name Ref ( upper
* or lowercase ) .
*
* Returns 0 or 1 depending on the lookup result
*/
int
xmlIsRef ( xmlDocPtr doc , xmlNodePtr elem , xmlAttrPtr attr ) {
if ( ( doc - > intSubset = = NULL ) & & ( doc - > extSubset = = NULL ) ) {
return ( 0 ) ;
/*******************
if ( ( ( attr - > name [ 0 ] = = ' I ' ) | | ( attr - > name [ 0 ] = = ' i ' ) ) & &
( ( attr - > name [ 1 ] = = ' D ' ) | | ( attr - > name [ 1 ] = = ' d ' ) ) & &
( attr - > name [ 2 ] = = 0 ) ) return ( 1 ) ;
* * * * * * * * * * * * * * * * * * */
} else {
xmlAttributePtr attrDecl ;
attrDecl = xmlGetDtdAttrDesc ( doc - > intSubset , elem - > name , attr - > name ) ;
if ( ( attrDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
attrDecl = xmlGetDtdAttrDesc ( doc - > extSubset , elem - > name ,
attr - > name ) ;
if ( ( attrDecl ! = NULL ) & & ( attrDecl - > type = = XML_ATTRIBUTE_IDREF ) )
return ( 1 ) ;
}
return ( 0 ) ;
}
/**
* xmlGetRef :
* @ doc : pointer to the document
* @ Ref : the Ref value
*
* Search the attribute declaring the given Ref
*
* Returns NULL if not found , otherwise the xmlAttrPtr defining the Ref
*/
xmlAttrPtr
1999-09-23 22:19:22 +00:00
xmlGetRef ( xmlDocPtr doc , const xmlChar * Ref ) {
1999-09-08 21:35:25 +00:00
xmlRefPtr cur ;
xmlRefTablePtr table ;
int i ;
if ( doc = = NULL ) {
fprintf ( stderr , " xmlGetRef: doc == NULL \n " ) ;
return ( NULL ) ;
}
if ( Ref = = NULL ) {
fprintf ( stderr , " xmlGetRef: Ref == NULL \n " ) ;
return ( NULL ) ;
}
table = doc - > refs ;
if ( table = = NULL )
return ( NULL ) ;
/*
* Search the Ref list .
*/
for ( i = 0 ; i < table - > nb_refs ; i + + ) {
cur = table - > table [ i ] ;
if ( ! xmlStrcmp ( cur - > value , Ref ) ) {
return ( cur - > attr ) ;
}
}
return ( NULL ) ;
}
1999-08-10 19:04:08 +00:00
/************************************************************************
* *
* Routines for validity checking *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlGetDtdElementDesc :
* @ dtd : a pointer to the DtD to search
* @ name : the element name
*
* Search the Dtd for the description of this element
*
* returns the xmlElementPtr if found or NULL
*/
xmlElementPtr
1999-09-23 22:19:22 +00:00
xmlGetDtdElementDesc ( xmlDtdPtr dtd , const xmlChar * name ) {
1999-08-10 19:04:08 +00:00
xmlElementTablePtr table ;
xmlElementPtr cur ;
int i ;
if ( dtd = = NULL ) return ( NULL ) ;
if ( dtd - > elements = = NULL ) return ( NULL ) ;
table = dtd - > elements ;
for ( i = 0 ; i < table - > nb_elements ; i + + ) {
cur = table - > table [ i ] ;
if ( ! xmlStrcmp ( cur - > name , name ) )
return ( cur ) ;
}
return ( NULL ) ;
}
/**
* xmlGetDtdAttrDesc :
* @ dtd : a pointer to the DtD to search
* @ elem : the element name
* @ name : the attribute name
*
* Search the Dtd for the description of this attribute on
* this element .
*
* returns the xmlAttributePtr if found or NULL
*/
xmlAttributePtr
1999-09-23 22:19:22 +00:00
xmlGetDtdAttrDesc ( xmlDtdPtr dtd , const xmlChar * elem , const xmlChar * name ) {
1999-08-10 19:04:08 +00:00
xmlAttributeTablePtr table ;
xmlAttributePtr cur ;
int i ;
if ( dtd = = NULL ) return ( NULL ) ;
if ( dtd - > attributes = = NULL ) return ( NULL ) ;
table = dtd - > attributes ;
for ( i = 0 ; i < table - > nb_attributes ; i + + ) {
cur = table - > table [ i ] ;
if ( ( ! xmlStrcmp ( cur - > name , name ) ) & &
( ! xmlStrcmp ( cur - > elem , elem ) ) )
return ( cur ) ;
}
return ( NULL ) ;
}
/**
* xmlGetDtdNotationDesc :
* @ dtd : a pointer to the DtD to search
* @ name : the notation name
*
* Search the Dtd for the description of this notation
*
* returns the xmlNotationPtr if found or NULL
*/
xmlNotationPtr
1999-09-23 22:19:22 +00:00
xmlGetDtdNotationDesc ( xmlDtdPtr dtd , const xmlChar * name ) {
1999-08-10 19:04:08 +00:00
xmlNotationTablePtr table ;
xmlNotationPtr cur ;
int i ;
if ( dtd = = NULL ) return ( NULL ) ;
if ( dtd - > notations = = NULL ) return ( NULL ) ;
table = dtd - > notations ;
for ( i = 0 ; i < table - > nb_notations ; i + + ) {
cur = table - > table [ i ] ;
if ( ! xmlStrcmp ( cur - > name , name ) )
return ( cur ) ;
}
return ( NULL ) ;
}
1999-08-29 21:02:19 +00:00
/**
* xmlValidateNotationUse :
* @ ctxt : the validation context
* @ doc : the document
* @ notationName : the notation name to check
*
* Validate that the given mame match a notation declaration .
* - [ VC : Notation Declared ]
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateNotationUse ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ,
1999-09-23 22:19:22 +00:00
const xmlChar * notationName ) {
1999-08-29 21:02:19 +00:00
xmlNotationPtr notaDecl ;
if ( ( doc = = NULL ) | | ( doc - > intSubset = = NULL ) ) return ( - 1 ) ;
notaDecl = xmlGetDtdNotationDesc ( doc - > intSubset , notationName ) ;
if ( ( notaDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
notaDecl = xmlGetDtdNotationDesc ( doc - > extSubset , notationName ) ;
if ( notaDecl = = NULL ) {
VERROR ( ctxt - > userData , " NOTATION %s is not declared \n " ,
notationName ) ;
return ( 0 ) ;
}
return ( 1 ) ;
}
1999-08-10 19:04:08 +00:00
/**
* xmlIsMixedElement
* @ doc : the document
* @ name : the element name
*
* Search in the DtDs whether an element accept Mixed content ( or ANY )
* basically if it is supposed to accept text childs
*
* returns 0 if no , 1 if yes , and - 1 if no element description is available
*/
int
1999-09-23 22:19:22 +00:00
xmlIsMixedElement ( xmlDocPtr doc , const xmlChar * name ) {
1999-08-10 19:04:08 +00:00
xmlElementPtr elemDecl ;
if ( ( doc = = NULL ) | | ( doc - > intSubset = = NULL ) ) return ( - 1 ) ;
elemDecl = xmlGetDtdElementDesc ( doc - > intSubset , name ) ;
if ( ( elemDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
elemDecl = xmlGetDtdElementDesc ( doc - > extSubset , name ) ;
if ( elemDecl = = NULL ) return ( - 1 ) ;
switch ( elemDecl - > type ) {
case XML_ELEMENT_TYPE_ELEMENT :
return ( 0 ) ;
case XML_ELEMENT_TYPE_EMPTY :
/*
* return 1 for EMPTY since we want VC error to pop up
* on < empty > < / empty > for example
*/
case XML_ELEMENT_TYPE_ANY :
case XML_ELEMENT_TYPE_MIXED :
return ( 1 ) ;
}
return ( 1 ) ;
}
/**
* xmlValidateNameValue :
* @ value : an Name value
*
* Validate that the given value match Name production
*
* returns 1 if valid or 0 otherwise
*/
int
1999-09-23 22:19:22 +00:00
xmlValidateNameValue ( const xmlChar * value ) {
const xmlChar * cur ;
1999-08-10 19:04:08 +00:00
if ( value = = NULL ) return ( 0 ) ;
cur = value ;
if ( ! IS_LETTER ( * cur ) & & ( * cur ! = ' _ ' ) & &
( * cur ! = ' : ' ) ) {
return ( 0 ) ;
}
while ( ( IS_LETTER ( * cur ) ) | | ( IS_DIGIT ( * cur ) ) | |
( * cur = = ' . ' ) | | ( * cur = = ' - ' ) | |
( * cur = = ' _ ' ) | | ( * cur = = ' : ' ) | |
( IS_COMBINING ( * cur ) ) | |
( IS_EXTENDER ( * cur ) ) )
cur + + ;
if ( * cur ! = 0 ) return ( 0 ) ;
return ( 1 ) ;
}
/**
* xmlValidateNamesValue :
* @ value : an Names value
*
* Validate that the given value match Names production
*
* returns 1 if valid or 0 otherwise
*/
int
1999-09-23 22:19:22 +00:00
xmlValidateNamesValue ( const xmlChar * value ) {
const xmlChar * cur ;
1999-08-10 19:04:08 +00:00
if ( value = = NULL ) return ( 0 ) ;
cur = value ;
if ( ! IS_LETTER ( * cur ) & & ( * cur ! = ' _ ' ) & &
( * cur ! = ' : ' ) ) {
return ( 0 ) ;
}
while ( ( IS_LETTER ( * cur ) ) | | ( IS_DIGIT ( * cur ) ) | |
( * cur = = ' . ' ) | | ( * cur = = ' - ' ) | |
( * cur = = ' _ ' ) | | ( * cur = = ' : ' ) | |
( IS_COMBINING ( * cur ) ) | |
( IS_EXTENDER ( * cur ) ) )
cur + + ;
while ( IS_BLANK ( * cur ) ) {
while ( IS_BLANK ( * cur ) ) cur + + ;
if ( ! IS_LETTER ( * cur ) & & ( * cur ! = ' _ ' ) & &
( * cur ! = ' : ' ) ) {
return ( 0 ) ;
}
while ( ( IS_LETTER ( * cur ) ) | | ( IS_DIGIT ( * cur ) ) | |
( * cur = = ' . ' ) | | ( * cur = = ' - ' ) | |
( * cur = = ' _ ' ) | | ( * cur = = ' : ' ) | |
( IS_COMBINING ( * cur ) ) | |
( IS_EXTENDER ( * cur ) ) )
cur + + ;
}
if ( * cur ! = 0 ) return ( 0 ) ;
return ( 1 ) ;
}
/**
* xmlValidateNmtokenValue :
* @ value : an Mntoken value
*
* Validate that the given value match Nmtoken production
*
* [ VC : Name Token ]
*
* returns 1 if valid or 0 otherwise
*/
int
1999-09-23 22:19:22 +00:00
xmlValidateNmtokenValue ( const xmlChar * value ) {
const xmlChar * cur ;
1999-08-10 19:04:08 +00:00
if ( value = = NULL ) return ( 0 ) ;
cur = value ;
if ( ! IS_LETTER ( * cur ) & & ! IS_DIGIT ( * cur ) & &
( * cur ! = ' . ' ) & & ( * cur ! = ' - ' ) & &
( * cur ! = ' _ ' ) & & ( * cur ! = ' : ' ) & &
( ! IS_COMBINING ( * cur ) ) & &
( ! IS_EXTENDER ( * cur ) ) )
return ( 0 ) ;
while ( ( IS_LETTER ( * cur ) ) | | ( IS_DIGIT ( * cur ) ) | |
( * cur = = ' . ' ) | | ( * cur = = ' - ' ) | |
( * cur = = ' _ ' ) | | ( * cur = = ' : ' ) | |
( IS_COMBINING ( * cur ) ) | |
( IS_EXTENDER ( * cur ) ) )
cur + + ;
if ( * cur ! = 0 ) return ( 0 ) ;
return ( 1 ) ;
}
/**
* xmlValidateNmtokensValue :
* @ value : an Mntokens value
*
* Validate that the given value match Nmtokens production
*
* [ VC : Name Token ]
*
* returns 1 if valid or 0 otherwise
*/
int
1999-09-23 22:19:22 +00:00
xmlValidateNmtokensValue ( const xmlChar * value ) {
const xmlChar * cur ;
1999-08-10 19:04:08 +00:00
if ( value = = NULL ) return ( 0 ) ;
cur = value ;
if ( ! IS_LETTER ( * cur ) & & ! IS_DIGIT ( * cur ) & &
( * cur ! = ' . ' ) & & ( * cur ! = ' - ' ) & &
( * cur ! = ' _ ' ) & & ( * cur ! = ' : ' ) & &
( ! IS_COMBINING ( * cur ) ) & &
( ! IS_EXTENDER ( * cur ) ) )
return ( 0 ) ;
while ( ( IS_LETTER ( * cur ) ) | | ( IS_DIGIT ( * cur ) ) | |
( * cur = = ' . ' ) | | ( * cur = = ' - ' ) | |
( * cur = = ' _ ' ) | | ( * cur = = ' : ' ) | |
( IS_COMBINING ( * cur ) ) | |
( IS_EXTENDER ( * cur ) ) )
cur + + ;
while ( IS_BLANK ( * cur ) ) {
while ( IS_BLANK ( * cur ) ) cur + + ;
if ( ! IS_LETTER ( * cur ) & & ! IS_DIGIT ( * cur ) & &
( * cur ! = ' . ' ) & & ( * cur ! = ' - ' ) & &
( * cur ! = ' _ ' ) & & ( * cur ! = ' : ' ) & &
( ! IS_COMBINING ( * cur ) ) & &
( ! IS_EXTENDER ( * cur ) ) )
return ( 0 ) ;
while ( ( IS_LETTER ( * cur ) ) | | ( IS_DIGIT ( * cur ) ) | |
( * cur = = ' . ' ) | | ( * cur = = ' - ' ) | |
( * cur = = ' _ ' ) | | ( * cur = = ' : ' ) | |
( IS_COMBINING ( * cur ) ) | |
( IS_EXTENDER ( * cur ) ) )
cur + + ;
}
if ( * cur ! = 0 ) return ( 0 ) ;
return ( 1 ) ;
}
/**
* xmlValidateNotationDecl :
1999-08-29 21:02:19 +00:00
* @ ctxt : the validation context
1999-08-10 19:04:08 +00:00
* @ doc : a document instance
* @ nota : a notation definition
*
* Try to validate a single notation definition
* basically it does the following checks as described by the
* XML - 1.0 recommendation :
* - it seems that no validity constraing exist on notation declarations
* But this function get called anyway . . .
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateNotationDecl ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ,
xmlNotationPtr nota ) {
int ret = 1 ;
return ( ret ) ;
}
/**
* xmlValidateAttributeValue :
* @ type : an attribute type
* @ value : an attribute value
*
* Validate that the given attribute value match the proper production
*
* [ VC : ID ]
* Values of type ID must match the Name production . . . .
*
* [ VC : IDREF ]
* Values of type IDREF must match the Name production , and values
* of type IDREFS must match Names . . .
*
* [ VC : Entity Name ]
* Values of type ENTITY must match the Name production , values
* of type ENTITIES must match Names . . .
*
* [ VC : Name Token ]
* Values of type NMTOKEN must match the Nmtoken production ; values
* of type NMTOKENS must match Nmtokens .
*
* returns 1 if valid or 0 otherwise
*/
int
1999-09-23 22:19:22 +00:00
xmlValidateAttributeValue ( xmlAttributeType type , const xmlChar * value ) {
1999-08-10 19:04:08 +00:00
switch ( type ) {
case XML_ATTRIBUTE_ENTITIES :
1999-08-29 21:02:19 +00:00
case XML_ATTRIBUTE_IDREFS :
1999-08-10 19:04:08 +00:00
return ( xmlValidateNamesValue ( value ) ) ;
1999-08-29 21:02:19 +00:00
case XML_ATTRIBUTE_ENTITY :
1999-08-10 19:04:08 +00:00
case XML_ATTRIBUTE_IDREF :
case XML_ATTRIBUTE_ID :
case XML_ATTRIBUTE_NOTATION :
return ( xmlValidateNameValue ( value ) ) ;
case XML_ATTRIBUTE_NMTOKENS :
case XML_ATTRIBUTE_ENUMERATION :
return ( xmlValidateNmtokensValue ( value ) ) ;
case XML_ATTRIBUTE_NMTOKEN :
return ( xmlValidateNmtokenValue ( value ) ) ;
case XML_ATTRIBUTE_CDATA :
break ;
}
return ( 1 ) ;
}
/**
* xmlValidateAttributeDecl :
1999-08-29 21:02:19 +00:00
* @ ctxt : the validation context
1999-08-10 19:04:08 +00:00
* @ doc : a document instance
* @ attr : an attribute definition
*
* Try to validate a single attribute definition
* basically it does the following checks as described by the
* XML - 1.0 recommendation :
* - [ VC : Attribute Default Legal ]
* - [ VC : Enumeration ]
* - [ VC : ID Attribute Default ]
*
* The ID / IDREF uniqueness and matching are done separately
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateAttributeDecl ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ,
xmlAttributePtr attr ) {
int ret = 1 ;
int val ;
CHECK_DTD ;
if ( attr = = NULL ) return ( 1 ) ;
/* Attribute Default Legal */
/* Enumeration */
if ( attr - > defaultValue ! = NULL ) {
val = xmlValidateAttributeValue ( attr - > type , attr - > defaultValue ) ;
if ( val = = 0 ) {
VERROR ( ctxt - > userData ,
" Syntax of default value for attribute %s on %s is not valid \n " ,
attr - > name , attr - > elem ) ;
}
ret & = val ;
}
/* ID Attribute Default */
if ( ( attr - > type = = XML_ATTRIBUTE_ID ) & &
( attr - > def ! = XML_ATTRIBUTE_IMPLIED ) & &
( attr - > def ! = XML_ATTRIBUTE_REQUIRED ) ) {
VERROR ( ctxt - > userData ,
" ID attribute %s on %s is not valid must be #IMPLIED or #REQUIRED \n " ,
attr - > name , attr - > elem ) ;
ret = 0 ;
}
1999-08-29 21:02:19 +00:00
/* One ID per Element Type */
1999-08-10 19:04:08 +00:00
if ( ( attr - > type = = XML_ATTRIBUTE_ID ) & & ( doc - > extSubset ! = NULL ) ) {
int nbId = 0 ;
/* the trick is taht we parse DtD as their own internal subset */
xmlElementPtr elem = xmlGetDtdElementDesc ( doc - > extSubset ,
attr - > elem ) ;
if ( elem ! = NULL ) {
nbId = xmlScanIDAttributeDecl ( NULL , elem ) ;
}
if ( nbId > = 1 )
VERROR ( ctxt - > userData ,
" Element %s has ID attribute defined in the external subset : %s \n " ,
attr - > elem , attr - > name ) ;
}
return ( ret ) ;
}
/**
* xmlValidateElementDecl :
* @ ctxt : the validation context
* @ doc : a document instance
* @ elem : an element definition
*
* Try to validate a single element definition
* basically it does the following checks as described by the
* XML - 1.0 recommendation :
* - [ VC : One ID per Element Type ]
* - [ VC : No Duplicate Types ]
* - [ VC : Unique Element Type Declaration ]
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateElementDecl ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ,
xmlElementPtr elem ) {
int ret = 1 ;
xmlElementPtr tst ;
CHECK_DTD ;
if ( elem = = NULL ) return ( 1 ) ;
/* No Duplicate Types */
if ( elem - > type = = XML_ELEMENT_TYPE_MIXED ) {
xmlElementContentPtr cur , next ;
1999-09-23 22:19:22 +00:00
const xmlChar * name ;
1999-08-10 19:04:08 +00:00
cur = elem - > content ;
while ( cur ! = NULL ) {
if ( cur - > type ! = XML_ELEMENT_CONTENT_OR ) break ;
if ( cur - > c1 = = NULL ) break ;
if ( cur - > c1 - > type = = XML_ELEMENT_CONTENT_ELEMENT ) {
name = cur - > c1 - > name ;
next = cur - > c2 ;
while ( next ! = NULL ) {
if ( next - > type = = XML_ELEMENT_CONTENT_ELEMENT ) {
if ( ! xmlStrcmp ( next - > name , name ) ) {
VERROR ( ctxt - > userData ,
" Definition of %s has duplicate references of %s \n " ,
elem - > name , name ) ;
ret = 0 ;
}
break ;
}
if ( next - > c1 = = NULL ) break ;
if ( next - > c1 - > type ! = XML_ELEMENT_CONTENT_ELEMENT ) break ;
if ( ! xmlStrcmp ( next - > c1 - > name , name ) ) {
VERROR ( ctxt - > userData ,
" Definition of %s has duplicate references of %s \n " ,
elem - > name , name ) ;
ret = 0 ;
}
next = next - > c2 ;
}
}
cur = cur - > c2 ;
}
}
/* VC: Unique Element Type Declaration */
tst = xmlGetDtdElementDesc ( doc - > intSubset , elem - > name ) ;
if ( ( tst ! = NULL ) & & ( tst ! = elem ) ) {
VERROR ( ctxt - > userData , " Redefinition of element %s \n " ,
elem - > name ) ;
ret = 0 ;
}
tst = xmlGetDtdElementDesc ( doc - > extSubset , elem - > name ) ;
if ( ( tst ! = NULL ) & & ( tst ! = elem ) ) {
VERROR ( ctxt - > userData , " Redefinition of element %s \n " ,
elem - > name ) ;
ret = 0 ;
}
/* One ID per Element Type */
if ( xmlScanIDAttributeDecl ( ctxt , elem ) > 1 ) {
ret = 0 ;
}
return ( ret ) ;
}
/**
* xmlValidateOneAttribute :
* @ ctxt : the validation context
* @ doc : a document instance
* @ elem : an element instance
* @ attr : an attribute instance
1999-10-08 09:40:39 +00:00
* @ value : the attribute value ( without entities processing )
1999-08-10 19:04:08 +00:00
*
* Try to validate a single attribute for an element
* basically it * does the following checks as described by the
* XML - 1.0 recommendation :
* - [ VC : Attribute Value Type ]
* - [ VC : Fixed Attribute Default ]
* - [ VC : Entity Name ]
* - [ VC : Name Token ]
* - [ VC : ID ]
* - [ VC : IDREF ]
* - [ VC : Entity Name ]
* - [ VC : Notation Attributes ]
*
* The ID / IDREF uniqueness and matching are done separately
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateOneAttribute ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ,
1999-09-23 22:19:22 +00:00
xmlNodePtr elem , xmlAttrPtr attr , const xmlChar * value ) {
1999-08-29 21:02:19 +00:00
/* xmlElementPtr elemDecl; */
1999-08-10 19:04:08 +00:00
xmlAttributePtr attrDecl ;
int val ;
int ret = 1 ;
CHECK_DTD ;
if ( ( elem = = NULL ) | | ( elem - > name = = NULL ) ) return ( 0 ) ;
if ( ( attr = = NULL ) | | ( attr - > name = = NULL ) ) return ( 0 ) ;
attrDecl = xmlGetDtdAttrDesc ( doc - > intSubset , elem - > name , attr - > name ) ;
if ( ( attrDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
attrDecl = xmlGetDtdAttrDesc ( doc - > extSubset , elem - > name , attr - > name ) ;
/* Validity Constraint: Attribute Value Type */
if ( attrDecl = = NULL ) {
VERROR ( ctxt - > userData ,
" No declaration for attribute %s on element %s \n " ,
attr - > name , elem - > name ) ;
return ( 0 ) ;
}
val = xmlValidateAttributeValue ( attrDecl - > type , value ) ;
if ( val = = 0 ) {
VERROR ( ctxt - > userData ,
" Syntax of value for attribute %s on %s is not valid \n " ,
attr - > name , elem - > name ) ;
ret = 0 ;
}
1999-08-29 21:02:19 +00:00
/* Validity Constraint: ID uniqueness */
if ( attrDecl - > type = = XML_ATTRIBUTE_ID ) {
xmlAddID ( ctxt , doc , value , attr ) ;
}
1999-09-08 21:35:25 +00:00
if ( attrDecl - > type = = XML_ATTRIBUTE_IDREF ) {
xmlAddRef ( ctxt , doc , value , attr ) ;
}
1999-08-10 19:04:08 +00:00
/* Validity Constraint: Notation Attributes */
if ( attrDecl - > type = = XML_ATTRIBUTE_NOTATION ) {
xmlEnumerationPtr tree = attrDecl - > tree ;
xmlNotationPtr nota ;
/* First check that the given NOTATION was declared */
nota = xmlGetDtdNotationDesc ( doc - > intSubset , value ) ;
if ( nota = = NULL )
nota = xmlGetDtdNotationDesc ( doc - > extSubset , value ) ;
if ( nota = = NULL ) {
VERROR ( ctxt - > userData ,
" Value \" %s \" for attribute %s on %s is not a declared Notation \n " ,
value , attr - > name , elem - > name ) ;
ret = 0 ;
}
/* Second, verify that it's among the list */
while ( tree ! = NULL ) {
if ( ! xmlStrcmp ( tree - > name , value ) ) break ;
tree = tree - > next ;
}
if ( tree = = NULL ) {
VERROR ( ctxt - > userData ,
" Value \" %s \" for attribute %s on %s is among the enumerated notations \n " ,
value , attr - > name , elem - > name ) ;
ret = 0 ;
}
}
/* Validity Constraint: Enumeration */
if ( attrDecl - > type = = XML_ATTRIBUTE_ENUMERATION ) {
xmlEnumerationPtr tree = attrDecl - > tree ;
while ( tree ! = NULL ) {
if ( ! xmlStrcmp ( tree - > name , value ) ) break ;
tree = tree - > next ;
}
if ( tree = = NULL ) {
VERROR ( ctxt - > userData ,
" Value \" %s \" for attribute %s on %s is among the enumerated set \n " ,
value , attr - > name , elem - > name ) ;
ret = 0 ;
}
}
/* Fixed Attribute Default */
if ( ( attrDecl - > def = = XML_ATTRIBUTE_FIXED ) & &
( xmlStrcmp ( attrDecl - > defaultValue , value ) ) ) {
VERROR ( ctxt - > userData ,
" Value for attribute %s on %s must be \" %s \" \n " ,
attr - > name , elem - > name , attrDecl - > defaultValue ) ;
ret = 0 ;
}
1999-08-29 21:02:19 +00:00
/********
1999-08-10 19:04:08 +00:00
elemDecl = xmlGetDtdElementDesc ( doc - > intSubset , elem - > name ) ;
if ( ( elemDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
elemDecl = xmlGetDtdElementDesc ( doc - > extSubset , elem - > name ) ;
if ( elemDecl = = NULL ) {
return ( 0 ) ;
}
1999-08-29 21:02:19 +00:00
* * * * * * * */
1999-08-10 19:04:08 +00:00
return ( ret ) ;
}
int xmlValidateElementTypeElement ( xmlValidCtxtPtr ctxt , xmlNodePtr * child ,
xmlElementContentPtr cont ) ;
/**
* xmlValidateElementTypeExpr :
* @ ctxt : the validation context
* @ child : pointer to the child list
* @ cont : pointer to the content declaration
*
* Try to validate the content of an element of type element
* but don ' t handle the occurence factor
*
* returns 1 if valid or 0 and - 1 if PCDATA stuff is found ,
* also update child value in - situ .
*/
int
xmlValidateElementTypeExpr ( xmlValidCtxtPtr ctxt , xmlNodePtr * child ,
xmlElementContentPtr cont ) {
xmlNodePtr cur ;
int ret = 1 ;
if ( cont = = NULL ) return ( - 1 ) ;
while ( * child ! = NULL ) {
if ( ( * child ) - > type = = XML_PI_NODE ) {
* child = ( * child ) - > next ;
continue ;
}
if ( ( * child ) - > type = = XML_COMMENT_NODE ) {
* child = ( * child ) - > next ;
continue ;
}
else if ( ( * child ) - > type ! = XML_ELEMENT_NODE ) {
return ( - 1 ) ;
}
break ;
}
switch ( cont - > type ) {
case XML_ELEMENT_CONTENT_PCDATA :
/* Internal error !!! */
fprintf ( stderr , " Internal: MIXED struct bad \n " ) ;
return ( - 1 ) ;
case XML_ELEMENT_CONTENT_ELEMENT :
if ( * child = = NULL ) return ( 0 ) ;
ret = ( ! xmlStrcmp ( ( * child ) - > name , cont - > name ) ) ;
if ( ret = = 1 )
* child = ( * child ) - > next ;
return ( ret ) ;
case XML_ELEMENT_CONTENT_OR :
cur = * child ;
ret = xmlValidateElementTypeElement ( ctxt , child , cont - > c1 ) ;
if ( ret = = - 1 ) return ( - 1 ) ;
if ( ret = = 1 ) {
return ( 1 ) ;
}
/* rollback and retry the other path */
* child = cur ;
ret = xmlValidateElementTypeElement ( ctxt , child , cont - > c2 ) ;
if ( ret = = - 1 ) return ( - 1 ) ;
if ( ret = = 0 ) {
* child = cur ;
return ( 0 ) ;
}
return ( 1 ) ;
case XML_ELEMENT_CONTENT_SEQ :
cur = * child ;
ret = xmlValidateElementTypeElement ( ctxt , child , cont - > c1 ) ;
if ( ret = = - 1 ) return ( - 1 ) ;
if ( ret = = 0 ) {
* child = cur ;
return ( 0 ) ;
}
ret = xmlValidateElementTypeElement ( ctxt , child , cont - > c2 ) ;
if ( ret = = - 1 ) return ( - 1 ) ;
if ( ret = = 0 ) {
* child = cur ;
return ( 0 ) ;
}
return ( 1 ) ;
}
return ( ret ) ;
}
/**
* xmlValidateElementTypeElement :
* @ ctxt : the validation context
* @ child : pointer to the child list
* @ cont : pointer to the content declaration
*
* Try to validate the content of an element of type element
* yeah , Yet Another Regexp Implementation , and recursive
*
* returns 1 if valid or 0 and - 1 if PCDATA stuff is found ,
* also update child and content values in - situ .
*/
int
xmlValidateElementTypeElement ( xmlValidCtxtPtr ctxt , xmlNodePtr * child ,
xmlElementContentPtr cont ) {
xmlNodePtr cur ;
int ret = 1 ;
if ( cont = = NULL ) return ( - 1 ) ;
while ( * child ! = NULL ) {
if ( ( * child ) - > type = = XML_PI_NODE ) {
* child = ( * child ) - > next ;
continue ;
}
if ( ( * child ) - > type = = XML_COMMENT_NODE ) {
* child = ( * child ) - > next ;
continue ;
}
else if ( ( * child ) - > type ! = XML_ELEMENT_NODE ) {
return ( - 1 ) ;
}
break ;
}
cur = * child ;
ret = xmlValidateElementTypeExpr ( ctxt , child , cont ) ;
if ( ret = = - 1 ) return ( - 1 ) ;
switch ( cont - > ocur ) {
case XML_ELEMENT_CONTENT_ONCE :
if ( ret = = 1 ) {
return ( 1 ) ;
}
* child = cur ;
return ( 0 ) ;
case XML_ELEMENT_CONTENT_OPT :
if ( ret = = 0 ) {
* child = cur ;
return ( 1 ) ;
}
break ;
case XML_ELEMENT_CONTENT_MULT :
if ( ret = = 0 ) {
* child = cur ;
break ;
}
/* no break on purpose */
case XML_ELEMENT_CONTENT_PLUS :
if ( ret = = 0 ) {
* child = cur ;
return ( 0 ) ;
}
do {
cur = * child ;
ret = xmlValidateElementTypeExpr ( ctxt , child , cont ) ;
} while ( ret = = 1 ) ;
if ( ret = = - 1 ) return ( - 1 ) ;
* child = cur ;
break ;
}
while ( * child ! = NULL ) {
if ( ( * child ) - > type = = XML_PI_NODE ) {
* child = ( * child ) - > next ;
continue ;
}
if ( ( * child ) - > type = = XML_COMMENT_NODE ) {
* child = ( * child ) - > next ;
continue ;
}
else if ( ( * child ) - > type ! = XML_ELEMENT_NODE ) {
return ( - 1 ) ;
}
break ;
}
return ( 1 ) ;
}
/**
* xmlSprintfElementChilds :
* @ buf : an output buffer
* @ content : An element
* @ glob : 1 if one must print the englobing parenthesis , 0 otherwise
*
* This will dump the list of childs to the buffer
* Intended just for the debug routine
*/
void
xmlSprintfElementChilds ( char * buf , xmlNodePtr node , int glob ) {
xmlNodePtr cur ;
if ( node = = NULL ) return ;
if ( glob ) strcat ( buf , " ( " ) ;
cur = node - > childs ;
while ( cur ! = NULL ) {
switch ( cur - > type ) {
case XML_ELEMENT_NODE :
1999-08-29 21:02:19 +00:00
strcat ( buf , ( char * ) cur - > name ) ;
1999-08-10 19:04:08 +00:00
if ( cur - > next ! = NULL )
strcat ( buf , " " ) ;
break ;
case XML_TEXT_NODE :
case XML_CDATA_SECTION_NODE :
case XML_ENTITY_REF_NODE :
strcat ( buf , " CDATA " ) ;
if ( cur - > next ! = NULL )
strcat ( buf , " " ) ;
break ;
case XML_ATTRIBUTE_NODE :
case XML_DOCUMENT_NODE :
1999-10-14 09:10:25 +00:00
case XML_HTML_DOCUMENT_NODE :
1999-08-10 19:04:08 +00:00
case XML_DOCUMENT_TYPE_NODE :
case XML_DOCUMENT_FRAG_NODE :
case XML_NOTATION_NODE :
strcat ( buf , " ??? " ) ;
if ( cur - > next ! = NULL )
strcat ( buf , " " ) ;
break ;
case XML_ENTITY_NODE :
case XML_PI_NODE :
case XML_COMMENT_NODE :
break ;
}
cur = cur - > next ;
}
if ( glob ) strcat ( buf , " ) " ) ;
}
/**
* xmlValidateOneElement :
* @ ctxt : the validation context
* @ doc : a document instance
* @ elem : an element instance
*
* Try to validate a single element and it ' s attributes ,
* basically it does the following checks as described by the
* XML - 1.0 recommendation :
* - [ VC : Element Valid ]
* - [ VC : Required Attribute ]
* Then call xmlValidateOneAttribute ( ) for each attribute present .
*
* The ID / IDREF checkings are done separately
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateOneElement ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ,
xmlNodePtr elem ) {
xmlElementPtr elemDecl ;
xmlElementContentPtr cont ;
1999-12-28 16:35:14 +00:00
xmlAttributePtr attr ;
1999-08-10 19:04:08 +00:00
xmlNodePtr child ;
int ret = 1 ;
1999-09-23 22:19:22 +00:00
const xmlChar * name ;
1999-08-10 19:04:08 +00:00
CHECK_DTD ;
1999-12-15 19:08:24 +00:00
if ( elem = = NULL ) return ( 0 ) ;
if ( elem - > type = = XML_TEXT_NODE ) {
}
switch ( elem - > type ) {
case XML_ATTRIBUTE_NODE :
VERROR ( ctxt - > userData ,
" Attribute element not expected here \n " ) ;
return ( 0 ) ;
case XML_TEXT_NODE :
if ( elem - > childs ! = NULL ) {
VERROR ( ctxt - > userData , " Text element has childs ! \n " ) ;
return ( 0 ) ;
}
if ( elem - > properties ! = NULL ) {
VERROR ( ctxt - > userData , " Text element has attributes ! \n " ) ;
return ( 0 ) ;
}
if ( elem - > ns ! = NULL ) {
VERROR ( ctxt - > userData , " Text element has namespace ! \n " ) ;
return ( 0 ) ;
}
if ( elem - > ns ! = NULL ) {
VERROR ( ctxt - > userData ,
" Text element carries namespace definitions ! \n " ) ;
return ( 0 ) ;
}
if ( elem - > content = = NULL ) {
VERROR ( ctxt - > userData ,
" Text element has no content ! \n " ) ;
return ( 0 ) ;
}
return ( 1 ) ;
case XML_CDATA_SECTION_NODE :
case XML_ENTITY_REF_NODE :
case XML_PI_NODE :
case XML_COMMENT_NODE :
return ( 1 ) ;
case XML_ENTITY_NODE :
VERROR ( ctxt - > userData ,
" Entity element not expected here \n " ) ;
return ( 0 ) ;
case XML_NOTATION_NODE :
VERROR ( ctxt - > userData ,
" Notation element not expected here \n " ) ;
return ( 0 ) ;
case XML_DOCUMENT_NODE :
case XML_DOCUMENT_TYPE_NODE :
case XML_DOCUMENT_FRAG_NODE :
VERROR ( ctxt - > userData ,
" Document element not expected here \n " ) ;
return ( 0 ) ;
case XML_HTML_DOCUMENT_NODE :
VERROR ( ctxt - > userData ,
" \n " ) ;
return ( 0 ) ;
case XML_ELEMENT_NODE :
break ;
default :
VERROR ( ctxt - > userData ,
" unknown element type %d \n " , elem - > type ) ;
return ( 0 ) ;
}
if ( elem - > name = = NULL ) return ( 0 ) ;
1999-08-10 19:04:08 +00:00
elemDecl = xmlGetDtdElementDesc ( doc - > intSubset , elem - > name ) ;
if ( ( elemDecl = = NULL ) & & ( doc - > extSubset ! = NULL ) )
elemDecl = xmlGetDtdElementDesc ( doc - > extSubset , elem - > name ) ;
if ( elemDecl = = NULL ) {
VERROR ( ctxt - > userData , " No declaration for element %s \n " ,
elem - > name ) ;
return ( 0 ) ;
}
/* Check taht the element content matches the definition */
switch ( elemDecl - > type ) {
case XML_ELEMENT_TYPE_EMPTY :
if ( elem - > childs ! = NULL ) {
VERROR ( ctxt - > userData ,
" Element %s was declared EMPTY this one has content \n " ,
elem - > name ) ;
ret = 0 ;
}
break ;
case XML_ELEMENT_TYPE_ANY :
/* I don't think anything is required then */
break ;
case XML_ELEMENT_TYPE_MIXED :
/* Hum, this start to get messy */
child = elem - > childs ;
while ( child ! = NULL ) {
if ( child - > type = = XML_ELEMENT_NODE ) {
name = child - > name ;
cont = elemDecl - > content ;
while ( cont ! = NULL ) {
if ( cont - > type = = XML_ELEMENT_CONTENT_ELEMENT ) {
if ( ! xmlStrcmp ( cont - > name , name ) ) break ;
} else if ( ( cont - > type = = XML_ELEMENT_CONTENT_OR ) & &
( cont - > c1 ! = NULL ) & &
( cont - > c1 - > type = = XML_ELEMENT_CONTENT_ELEMENT ) ) {
if ( ! xmlStrcmp ( cont - > c1 - > name , name ) ) break ;
} else if ( ( cont - > type ! = XML_ELEMENT_CONTENT_OR ) | |
( cont - > c1 = = NULL ) | |
( cont - > c1 - > type ! = XML_ELEMENT_CONTENT_PCDATA ) ) {
/* Internal error !!! */
fprintf ( stderr , " Internal: MIXED struct bad \n " ) ;
break ;
}
cont = cont - > c2 ;
}
if ( cont = = NULL ) {
VERROR ( ctxt - > userData ,
" Element %s is not declared in %s list of possible childs \n " ,
name , elem - > name ) ;
ret = 0 ;
}
}
child = child - > next ;
}
break ;
case XML_ELEMENT_TYPE_ELEMENT :
child = elem - > childs ;
cont = elemDecl - > content ;
ret = xmlValidateElementTypeElement ( ctxt , & child , cont ) ;
if ( ( ret = = 0 ) | | ( child ! = NULL ) ) {
char expr [ 1000 ] ;
char list [ 2000 ] ;
expr [ 0 ] = 0 ;
xmlSprintfElementContent ( expr , cont , 1 ) ;
list [ 0 ] = 0 ;
xmlSprintfElementChilds ( list , elem , 1 ) ;
VERROR ( ctxt - > userData ,
" Element %s content doesn't follow the Dtd \n Expecting %s, got %s \n " ,
elem - > name , expr , list ) ;
ret = 0 ;
}
break ;
}
1999-12-28 16:35:14 +00:00
/* [ VC: Required Attribute ] */
attr = elemDecl - > attributes ;
while ( attr ! = NULL ) {
if ( attr - > def = = XML_ATTRIBUTE_REQUIRED ) {
xmlAttrPtr attrib ;
int qualified = - 1 ;
attrib = elem - > properties ;
while ( attrib ! = NULL ) {
if ( ! xmlStrcmp ( attrib - > name , attr - > name ) ) {
if ( attr - > prefix ! = NULL ) {
xmlNsPtr nameSpace = attrib - > ns ;
if ( nameSpace = = NULL )
nameSpace = elem - > ns ;
/*
* qualified names handling is problematic , having a
* different prefix should be possible but DTDs don ' t
* allow to define the URI instead of the prefix : - (
*/
if ( nameSpace = = NULL ) {
if ( qualified < 0 )
qualified = 0 ;
} else if ( xmlStrcmp ( nameSpace - > prefix , attr - > prefix ) ) {
if ( qualified < 1 )
qualified = 1 ;
} else
goto found ;
} else {
/*
* We should allow applications to define namespaces
* for their application even if the DTD doesn ' t
* carry one , otherwise , basically we would always
* break .
*/
goto found ;
}
}
attrib = attrib - > next ;
}
if ( qualified = = - 1 ) {
if ( attr - > prefix = = NULL ) {
VERROR ( ctxt - > userData ,
" Element %s doesn't carry attribute %s \n " ,
elem - > name , attr - > name ) ;
} else {
VERROR ( ctxt - > userData ,
" Element %s doesn't carry attribute %s:%s \n " ,
elem - > name , attr - > prefix , attr - > name ) ;
}
} else if ( qualified = = 0 ) {
VWARNING ( ctxt - > userData ,
" Element %s required attribute %s:%s has no prefix \n " ,
elem - > name , attr - > prefix , attr - > name ) ;
} else if ( qualified = = 1 ) {
VWARNING ( ctxt - > userData ,
" Element %s required attribute %s:%s has different prefix \n " ,
elem - > name , attr - > prefix , attr - > name ) ;
}
}
found :
attr = attr - > next ;
}
1999-08-10 19:04:08 +00:00
return ( ret ) ;
}
/**
* xmlValidateRoot :
* @ ctxt : the validation context
* @ doc : a document instance
*
* Try to validate a the root element
* basically it does the following check as described by the
* XML - 1.0 recommendation :
* - [ VC : Root Element Type ]
* it doesn ' t try to recurse or apply other check to the element
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateRoot ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ) {
1999-12-15 19:08:24 +00:00
xmlNodePtr root ;
1999-08-10 19:04:08 +00:00
if ( doc = = NULL ) return ( 0 ) ;
if ( ( doc - > intSubset = = NULL ) | |
( doc - > intSubset - > name = = NULL ) ) {
VERROR ( ctxt - > userData , " Not valid: no DtD found \n " ) ;
return ( 0 ) ;
}
1999-12-15 19:08:24 +00:00
root = xmlDocGetRootElement ( doc ) ;
if ( ( root = = NULL ) | | ( root - > name = = NULL ) ) {
1999-08-10 19:04:08 +00:00
VERROR ( ctxt - > userData , " Not valid: no root element \n " ) ;
return ( 0 ) ;
}
1999-12-15 19:08:24 +00:00
if ( xmlStrcmp ( doc - > intSubset - > name , root - > name ) ) {
1999-08-10 19:04:08 +00:00
VERROR ( ctxt - > userData ,
1999-12-15 19:08:24 +00:00
" Not valid: root and DtD name do not match '%s' and '%s' \n " ,
root - > name , doc - > intSubset - > name ) ;
1999-08-10 19:04:08 +00:00
return ( 0 ) ;
}
return ( 1 ) ;
}
/**
* xmlValidateElement :
* @ ctxt : the validation context
* @ doc : a document instance
* @ elem : an element instance
*
* Try to validate the subtree under an element
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateElement ( xmlValidCtxtPtr ctxt , xmlDocPtr doc , xmlNodePtr elem ) {
1999-09-08 21:35:25 +00:00
xmlNodePtr child ;
xmlAttrPtr attr ;
1999-09-23 22:19:22 +00:00
xmlChar * value ;
1999-09-08 21:35:25 +00:00
int ret = 1 ;
if ( elem = = NULL ) return ( 0 ) ;
1999-08-10 19:04:08 +00:00
CHECK_DTD ;
1999-09-08 21:35:25 +00:00
ret & = xmlValidateOneElement ( ctxt , doc , elem ) ;
attr = elem - > properties ;
while ( attr ! = NULL ) {
value = xmlNodeListGetString ( doc , attr - > val , 0 ) ;
ret & = xmlValidateOneAttribute ( ctxt , doc , elem , attr , value ) ;
if ( value ! = NULL )
1999-12-15 19:08:24 +00:00
xmlFree ( value ) ;
1999-09-08 21:35:25 +00:00
attr = attr - > next ;
}
child = elem - > childs ;
while ( child ! = NULL ) {
ret & = xmlValidateElement ( ctxt , doc , child ) ;
child = child - > next ;
}
return ( ret ) ;
}
/**
* xmlValidateDocumentFinal :
* @ ctxt : the validation context
* @ doc : a document instance
*
* Does the final step for the document validation once all the
* incremental validation steps have been completed
*
* basically it does the following checks described by the XML Rec
*
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateDocumentFinal ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ) {
int ret = 1 , i ;
xmlRefTablePtr table ;
xmlAttrPtr id ;
if ( doc = = NULL ) {
fprintf ( stderr , " xmlValidateDocumentFinal: doc == NULL \n " ) ;
return ( 0 ) ;
}
/*
* Get the refs table
*/
table = doc - > refs ;
if ( table ! = NULL ) {
for ( i = 0 ; i < table - > nb_refs ; i + + ) {
id = xmlGetID ( doc , table - > table [ i ] - > value ) ;
if ( id = = NULL ) {
VERROR ( ctxt - > userData ,
" IDREF attribute %s reference an unknown ID '%s' \n " ,
table - > table [ i ] - > attr - > name , table - > table [ i ] - > value ) ;
ret = 0 ;
}
}
}
return ( ret ) ;
1999-08-10 19:04:08 +00:00
}
/**
* xmlValidateDtd :
* @ ctxt : the validation context
* @ doc : a document instance
* @ dtd : a dtd instance
*
1999-12-15 19:08:24 +00:00
* Try to validate the document against the dtd instance
1999-08-10 19:04:08 +00:00
*
* basically it does check all the definitions in the DtD .
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateDtd ( xmlValidCtxtPtr ctxt , xmlDocPtr doc , xmlDtdPtr dtd ) {
1999-12-15 19:08:24 +00:00
int ret ;
xmlDtdPtr oldExt ;
xmlNodePtr root ;
if ( dtd = = NULL ) return ( 0 ) ;
if ( doc = = NULL ) return ( 0 ) ;
oldExt = doc - > extSubset ;
doc - > extSubset = dtd ;
ret = xmlValidateRoot ( ctxt , doc ) ;
if ( ret = = 0 ) {
doc - > extSubset = oldExt ;
return ( ret ) ;
}
root = xmlDocGetRootElement ( doc ) ;
ret = xmlValidateElement ( ctxt , doc , root ) ;
ret & = xmlValidateDocumentFinal ( ctxt , doc ) ;
doc - > extSubset = oldExt ;
return ( ret ) ;
1999-08-10 19:04:08 +00:00
}
/**
* xmlValidateDocument :
* @ ctxt : the validation context
* @ doc : a document instance
*
* Try to validate the document instance
*
1999-09-08 21:35:25 +00:00
* basically it does the all the checks described by the XML Rec
1999-08-10 19:04:08 +00:00
* i . e . validates the internal and external subset ( if present )
* and validate the document tree .
*
* returns 1 if valid or 0 otherwise
*/
int
xmlValidateDocument ( xmlValidCtxtPtr ctxt , xmlDocPtr doc ) {
1999-09-08 21:35:25 +00:00
int ret ;
1999-12-15 19:08:24 +00:00
xmlNodePtr root ;
if ( ( doc - > intSubset = = NULL ) & & ( doc - > extSubset = = NULL ) )
return ( 0 ) ;
if ( ( doc - > intSubset ! = NULL ) & & ( ( doc - > intSubset - > SystemID ! = NULL ) | |
( doc - > intSubset - > ExternalID ! = NULL ) ) & & ( doc - > extSubset = = NULL ) ) {
doc - > extSubset = xmlParseDTD ( doc - > intSubset - > ExternalID ,
doc - > intSubset - > SystemID ) ;
if ( doc - > extSubset = = NULL ) {
if ( doc - > intSubset - > SystemID ! = NULL ) {
VERROR ( ctxt - > userData ,
" Could not load the external subset '%s' \n " ,
doc - > intSubset - > SystemID ) ;
} else {
VERROR ( ctxt - > userData ,
" Could not load the external subset '%s' \n " ,
doc - > intSubset - > ExternalID ) ;
}
return ( 0 ) ;
}
}
1999-09-08 21:35:25 +00:00
1999-08-10 19:04:08 +00:00
if ( ! xmlValidateRoot ( ctxt , doc ) ) return ( 0 ) ;
1999-12-15 19:08:24 +00:00
root = xmlDocGetRootElement ( doc ) ;
ret = xmlValidateElement ( ctxt , doc , root ) ;
1999-09-08 21:35:25 +00:00
ret & = xmlValidateDocumentFinal ( ctxt , doc ) ;
return ( ret ) ;
1999-08-10 19:04:08 +00:00
}
1999-10-14 09:10:25 +00:00
/************************************************************************
* *
* Routines for dynamic validation editing *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlValidGetPotentialChildren :
* @ ctree : an element content tree
* @ list : an array to store the list of child names
* @ len : a pointer to the number of element in the list
* @ max : the size of the array
*
* Build / extend a list of potential children allowed by the content tree
*
* returns the number of element in the list , or - 1 in case of error .
*/
int
xmlValidGetPotentialChildren ( xmlElementContent * ctree , const xmlChar * * list ,
int * len , int max ) {
int i ;
if ( ( ctree = = NULL ) | | ( list = = NULL ) | | ( len = = NULL ) )
return ( - 1 ) ;
if ( * len > = max ) return ( * len ) ;
switch ( ctree - > type ) {
case XML_ELEMENT_CONTENT_PCDATA :
for ( i = 0 ; i < * len ; i + + )
1999-11-24 18:04:22 +00:00
if ( ! xmlStrcmp ( BAD_CAST " #PCDATA " , list [ i ] ) ) return ( * len ) ;
list [ ( * len ) + + ] = BAD_CAST " #PCDATA " ;
1999-10-14 09:10:25 +00:00
break ;
case XML_ELEMENT_CONTENT_ELEMENT :
for ( i = 0 ; i < * len ; i + + )
if ( ! xmlStrcmp ( ctree - > name , list [ i ] ) ) return ( * len ) ;
list [ ( * len ) + + ] = ctree - > name ;
break ;
case XML_ELEMENT_CONTENT_SEQ :
xmlValidGetPotentialChildren ( ctree - > c1 , list , len , max ) ;
xmlValidGetPotentialChildren ( ctree - > c2 , list , len , max ) ;
break ;
case XML_ELEMENT_CONTENT_OR :
xmlValidGetPotentialChildren ( ctree - > c1 , list , len , max ) ;
xmlValidGetPotentialChildren ( ctree - > c2 , list , len , max ) ;
break ;
}
return ( * len ) ;
}
/**
* xmlValidGetValidElements :
* @ prev : an element to insert after
* @ next : an element to insert next
* @ list : an array to store the list of child names
* @ max : the size of the array
*
* This function returns the list of authorized children to insert
* within an existing tree while respecting the validity constraints
* forced by the Dtd . The insertion point is defined using @ prev and
* @ next in the following ways :
* to insert before ' node ' : xmlValidGetValidElements ( node - > prev , node , . . .
* to insert next ' node ' : xmlValidGetValidElements ( node , node - > next , . . .
* to replace ' node ' : xmlValidGetValidElements ( node - > prev , node - > next , . . .
* to prepend a child to ' node ' : xmlValidGetValidElements ( NULL , node - > childs ,
* to append a child to ' node ' : xmlValidGetValidElements ( node - > last , NULL , . . .
*
* pointers to the element names are inserted at the beginning of the array
* and do not need to be freed .
*
* returns the number of element in the list , or - 1 in case of error . If
* the function returns the value @ max the caller is invited to grow the
* receiving array and retry .
*/
int
xmlValidGetValidElements ( xmlNode * prev , xmlNode * next , const xmlChar * * list ,
int max ) {
int nb_valid_elements = 0 ;
const xmlChar * elements [ 256 ] ;
int nb_elements = 0 , i ;
xmlNode * ref_node ;
xmlNode * parent ;
xmlNode * test_node ;
xmlNode * prev_next ;
xmlNode * next_prev ;
xmlNode * parent_childs ;
xmlNode * parent_last ;
xmlElement * element_desc ;
if ( prev = = NULL & & next = = NULL )
return ( - 1 ) ;
if ( list = = NULL ) return ( - 1 ) ;
if ( max < = 0 ) return ( - 1 ) ;
nb_valid_elements = 0 ;
ref_node = prev ? prev : next ;
parent = ref_node - > parent ;
/*
* Retrieves the parent element declaration
*/
element_desc = xmlGetDtdElementDesc ( parent - > doc - > intSubset ,
parent - > name ) ;
if ( ( element_desc = = NULL ) & & ( parent - > doc - > extSubset ! = NULL ) )
element_desc = xmlGetDtdElementDesc ( parent - > doc - > extSubset ,
parent - > name ) ;
if ( element_desc = = NULL ) return ( - 1 ) ;
/*
* Do a backup of the current tree structure
*/
prev_next = prev ? prev - > next : NULL ;
next_prev = next ? next - > prev : NULL ;
parent_childs = parent - > childs ;
parent_last = parent - > last ;
/*
* Creates a dummy node and insert it into the tree
*/
1999-11-24 18:04:22 +00:00
test_node = xmlNewNode ( NULL , BAD_CAST " <!dummy?> " ) ;
1999-10-14 09:10:25 +00:00
test_node - > doc = ref_node - > doc ;
test_node - > parent = parent ;
test_node - > prev = prev ;
test_node - > next = next ;
if ( prev ) prev - > next = test_node ;
else parent - > childs = test_node ;
if ( next ) next - > prev = test_node ;
else parent - > last = test_node ;
/*
* Insert each potential child node and check if the parent is
* still valid
*/
nb_elements = xmlValidGetPotentialChildren ( element_desc - > content ,
elements , & nb_elements , 256 ) ;
for ( i = 0 ; i < nb_elements ; i + + ) {
test_node - > name = elements [ i ] ;
if ( xmlValidateOneElement ( NULL , parent - > doc , parent ) ) {
int j ;
for ( j = 0 ; j < nb_valid_elements ; j + + )
if ( ! xmlStrcmp ( elements [ i ] , list [ j ] ) ) break ;
list [ nb_valid_elements + + ] = elements [ i ] ;
if ( nb_valid_elements > = max ) break ;
}
}
/*
* Restore the tree structure
*/
if ( prev ) prev - > next = prev_next ;
if ( next ) next - > prev = next_prev ;
parent - > childs = parent_childs ;
parent - > last = parent_last ;
return ( nb_valid_elements ) ;
}