1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-28 00:21:53 +03:00

Bug fixes, improvement on ID/IDREF support, 1.6.2, no memleaks, Daniel

This commit is contained in:
Daniel Veillard
1999-09-08 21:35:25 +00:00
parent 72bd1001e2
commit c08a2c6fd4
19 changed files with 647 additions and 27 deletions

View File

@ -1,3 +1,15 @@
Wed Sep 8 22:46:14 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* HTMLparser.c : cleanup
* SAX.c valid.c valid.h: added ID/IDREF checking
* tree.c tree.h: extended doc structure for refs
* configure.in: 1.6.2
* parser.c: patched bug in SAX user arg call
* parserInternals.h: patched missing close in C++ wrapping
* testXPath.c xpath.c xpath.h: prepared for extensibility,
especially upcoming XPointer implementation.
* doc/xml.html: augmented, typo
Sat Sep 4 22:48:05 CEST 1999 Timur Bakeyev <mc@bat.ru> Sat Sep 4 22:48:05 CEST 1999 Timur Bakeyev <mc@bat.ru>
* doc/Makefile.am: replaced "install -d " with "mkinstalldirs" - * doc/Makefile.am: replaced "install -d " with "mkinstalldirs" -

View File

@ -15,7 +15,7 @@ mean that I'm on holliday or on the road.
The reasons I'm asking for an ask before commit policy is that I'm The reasons I'm asking for an ask before commit policy is that I'm
using a separate CVS base for unstable developments and if you commit using a separate CVS base for unstable developments and if you commit
a patch I didn't get, I may loose your change by mistake (it happened a patch I didn't get, I may loose your change by mistake (it happened
already once) and seriously complicatye my job of merging both bases. already once) and seriously complicates my job of merging both bases.
(The second base is at http://dev.w3.org/ under the XML module). (The second base is at http://dev.w3.org/ under the XML module).
thanks in advance for following the rule, thanks in advance for following the rule,

View File

@ -1133,6 +1133,8 @@ htmlNewDoc(const CHAR *URI, const CHAR *ExternalID) {
cur->encoding = NULL; cur->encoding = NULL;
cur->standalone = 1; cur->standalone = 1;
cur->compression = 0; cur->compression = 0;
cur->ids = NULL;
cur->refs = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
cur->vepv = NULL; cur->vepv = NULL;

7
SAX.c
View File

@ -492,10 +492,13 @@ startDocument(void *ctx)
void void
endDocument(void *ctx) endDocument(void *ctx)
{ {
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
#ifdef DEBUG_SAX #ifdef DEBUG_SAX
fprintf(stderr, "SAX.endDocument()\n"); fprintf(stderr, "SAX.endDocument()\n");
#endif #endif
if (ctxt->validate && ctxt->wellFormed &&
ctxt->myDoc && ctxt->myDoc->intSubset)
ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
} }
/** /**
@ -572,6 +575,8 @@ attribute(void *ctx, const CHAR *fullname, const CHAR *value)
*/ */
if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
} }
if (name != NULL) if (name != NULL)

View File

@ -5,7 +5,7 @@ AM_CONFIG_HEADER(config.h)
LIBXML_MAJOR_VERSION=1 LIBXML_MAJOR_VERSION=1
LIBXML_MINOR_VERSION=6 LIBXML_MINOR_VERSION=6
LIBXML_MICRO_VERSION=1 LIBXML_MICRO_VERSION=2
LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION
LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION

View File

@ -529,7 +529,7 @@ core.</p>
Model</em> this is an API for accessing XML or HTML structured documents. Model</em> this is an API for accessing XML or HTML structured documents.
Native support for DOM in Gnome is on the way (module gnome-dom), and it will Native support for DOM in Gnome is on the way (module gnome-dom), and it will
be based on gnome-xml. This will be a far cleaner interface to manipulate XML be based on gnome-xml. This will be a far cleaner interface to manipulate XML
files within Gnome since it won't expose the internal structure. DOM defiles a files within Gnome since it won't expose the internal structure. DOM defines a
set of IDL (or Java) interfaces allowing to traverse and manipulate a set of IDL (or Java) interfaces allowing to traverse and manipulate a
document. The DOM library will allow accessing and modifying "live" documents document. The DOM library will allow accessing and modifying "live" documents
presents on other programs like this:</p> presents on other programs like this:</p>
@ -747,6 +747,6 @@ base under gnome-xml/example</p>
<p><a href="mailto:Daniel.Veillard@w3.org">Daniel Veillard</a></p> <p><a href="mailto:Daniel.Veillard@w3.org">Daniel Veillard</a></p>
<p>$Id$</p> <p>$Id: xml.html,v 1.7 1999/09/04 18:27:23 veillard Exp $</p>
</body> </body>
</html> </html>

View File

@ -637,4 +637,7 @@ int inputPush (xmlParserCtxtPtr ctxt,
xmlParserInputPtr value); xmlParserInputPtr value);
xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt); xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_PARSER_INTERNALS_H__ */ #endif /* __XML_PARSER_INTERNALS_H__ */

View File

@ -210,6 +210,17 @@ typedef struct xmlID {
} xmlID; } xmlID;
typedef xmlID *xmlIDPtr; typedef xmlID *xmlIDPtr;
/*
* An XML IDREF instance.
*/
typedef struct xmlRef {
struct xmlRef *next; /* next Ref */
const CHAR *value; /* The Ref name */
xmlAttrPtr attr; /* The attribut holding it */
} xmlRef;
typedef xmlRef *xmlRefPtr;
/* /*
* A node in an XML tree. * A node in an XML tree.
*/ */
@ -253,6 +264,7 @@ typedef struct xmlDoc {
struct xmlNs *oldNs; /* Global namespace, the old way */ struct xmlNs *oldNs; /* Global namespace, the old way */
struct xmlNode *root; /* the document tree */ struct xmlNode *root; /* the document tree */
void *ids; /* Hash table for ID attributes if any */ void *ids; /* Hash table for ID attributes if any */
void *refs; /* Hash table for IDREFs attributes if any */
} _xmlDoc; } _xmlDoc;
typedef _xmlDoc xmlDoc; typedef _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr; typedef xmlDoc *xmlDocPtr;
@ -440,6 +452,12 @@ const CHAR * xmlNodeGetLang (xmlNodePtr cur);
void xmlNodeSetLang (xmlNodePtr cur, void xmlNodeSetLang (xmlNodePtr cur,
const CHAR *lang); const CHAR *lang);
/*
* Removing content.
*/
int xmlRemoveProp (xmlAttrPtr attr); /* TODO */
int xmlRemoveNode (xmlNodePtr node); /* TODO */
/* /*
* Internal, don't use * Internal, don't use
*/ */

View File

@ -88,6 +88,20 @@ typedef struct xmlIDTable {
} xmlIDTable; } xmlIDTable;
typedef xmlIDTable *xmlIDTablePtr; typedef xmlIDTable *xmlIDTablePtr;
/*
* ALl Refs attributes are stored in a table
* there is one table per document
*/
#define XML_MIN_REF_TABLE 32
typedef struct xmlRefTable {
int nb_refs; /* number of refs stored */
int max_refs; /* maximum number of refs */
xmlRefPtr *table; /* the table of refs */
} xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
/* Notation */ /* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt, xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
xmlDtdPtr dtd, xmlDtdPtr dtd,
@ -148,6 +162,17 @@ int xmlIsID (xmlDocPtr doc,
xmlNodePtr elem, xmlNodePtr elem,
xmlAttrPtr attr); xmlAttrPtr attr);
/* IDREFs */
xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
const CHAR *value,
xmlAttrPtr attr);
xmlRefTablePtr xmlCopyRefTable (xmlRefTablePtr table);
void xmlFreeRefTable (xmlRefTablePtr table);
int xmlIsRef (xmlDocPtr doc,
xmlNodePtr elem,
xmlAttrPtr attr);
/** /**
* The public function calls related to validity checking * The public function calls related to validity checking
*/ */
@ -181,6 +206,8 @@ int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
xmlNodePtr elem, xmlNodePtr elem,
xmlAttrPtr attr, xmlAttrPtr attr,
const CHAR *value); const CHAR *value);
int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
xmlDocPtr doc);
int xmlValidateNotationUse (xmlValidCtxtPtr ctxt, int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
xmlDocPtr doc, xmlDocPtr doc,
const CHAR *notationName); const CHAR *notationName);

View File

@ -14,6 +14,8 @@
#include "tree.h" #include "tree.h"
typedef struct xmlXPathParserContext *xmlXPathParserContextPtr;
/* /*
* A node-set (an unordered collection of nodes without duplicates) * A node-set (an unordered collection of nodes without duplicates)
*/ */
@ -37,6 +39,7 @@ typedef struct xmlNodeSet {
#define XPATH_BOOLEAN 2 #define XPATH_BOOLEAN 2
#define XPATH_NUMBER 3 #define XPATH_NUMBER 3
#define XPATH_STRING 4 #define XPATH_STRING 4
#define XPATH_USERS 5
typedef struct xmlXPathObject { typedef struct xmlXPathObject {
int type; int type;
@ -44,8 +47,66 @@ typedef struct xmlXPathObject {
int boolval; int boolval;
double floatval; double floatval;
CHAR *stringval; CHAR *stringval;
void *user;
} xmlXPathObject, *xmlXPathObjectPtr; } xmlXPathObject, *xmlXPathObjectPtr;
/*
* A conversion function is associated to a type and used to cast
* the new type to primitive values.
*/
typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
/*
* Extra type: a name and a conversion function.
*/
typedef struct xmlXPathType {
const CHAR *name; /* the type name */
xmlXPathConvertFunc func; /* the conversion function */
} xmlXPathType, *xmlXPathTypePtr;
/*
* Extra variable: a name and a value.
*/
typedef struct xmlXPathVariable {
const CHAR *name; /* the variable name */
xmlXPathObjectPtr value; /* the value */
} xmlXPathVariable, *xmlXPathVariablePtr;
/*
* an evaluation function, the parameters are on the context stack
*/
typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, int nargs);
/*
* Extra function: a name and a evaluation function.
*/
typedef struct xmlXPathFunct {
const CHAR *name; /* the function name */
xmlXPathEvalFunc func; /* the evaluation function */
} xmlXPathFunc, *xmlXPathFuncPtr;
/*
* An axis traversal function. To traverse an axis, the engine calls
* the first time with cur == NULL and repeat until the function returns
* NULL indicating the end of the axis traversal.
*/
typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr cur);
/*
* Extra axis: a name and an axis function.
*/
typedef struct xmlXPathAxis {
const CHAR *name; /* the axis name */
xmlXPathAxisFunc func; /* the search function */
} xmlXPathAxis, *xmlXPathAxisPtr;
/* /*
* Expression evaluation occurs with respect to a context. * Expression evaluation occurs with respect to a context.
* he context consists of: * he context consists of:
@ -60,10 +121,27 @@ typedef struct xmlXPathContext {
xmlDocPtr doc; /* The current document */ xmlDocPtr doc; /* The current document */
xmlNodePtr node; /* The current node */ xmlNodePtr node; /* The current node */
xmlNodeSetPtr nodelist; /* The current node list */ xmlNodeSetPtr nodelist; /* The current node list */
void *variables; /* TODO !!!! */
void *functions; /* TODO !!!! */ int nb_variables; /* number of defined variables */
int max_variables; /* max number of variables */
xmlXPathVariablePtr *variables; /* Array of defined variables */
int nb_types; /* number of defined types */
int max_types; /* max number of types */
xmlXPathTypePtr *types; /* Array of defined types */
int nb_funcs; /* number of defined funcs */
int max_funcs; /* max number of funcs */
xmlXPathFuncPtr *funcs; /* Array of defined funcs */
int nb_axis; /* number of defined axis */
int max_axis; /* max number of axis */
xmlXPathAxisPtr *axis; /* Array of defined axis */
/* Namespace traversal should be implemented with user */
xmlNsPtr *namespaces; /* The namespaces lookup */ xmlNsPtr *namespaces; /* The namespaces lookup */
int nsNr; /* the current Namespace index */ int nsNr; /* the current Namespace index */
void *user; /* user defined extra info */
} xmlXPathContext, *xmlXPathContextPtr; } xmlXPathContext, *xmlXPathContextPtr;
/* /*
@ -81,7 +159,7 @@ typedef struct xmlXPathParserContext {
int valueNr; /* number of values stacked */ int valueNr; /* number of values stacked */
int valueMax; /* max number of values stacked */ int valueMax; /* max number of values stacked */
xmlXPathObjectPtr *valueTab; /* stack of values */ xmlXPathObjectPtr *valueTab; /* stack of values */
} xmlXPathParserContext, *xmlXPathParserContextPtr; } xmlXPathParserContext;
/* /*
* An XPath function * An XPath function
@ -97,9 +175,26 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
* * * *
************************************************************************/ ************************************************************************/
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc, /**
void *variables, * Registering extensions to the expression language
void *functions); */
/* TODO */ int xmlXPathRegisterType (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathConvertFunc f);
/* TODO */ int xmlXPathRegisterAxis (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathAxisFunc f);
/* TODO */ int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathFunction f);
/* TODO */ int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathObject value);
/**
* Evaluation functions.
*/
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
void xmlXPathFreeContext (xmlXPathContextPtr ctxt); void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
xmlXPathObjectPtr xmlXPathEval (const CHAR *str, xmlXPathObjectPtr xmlXPathEval (const CHAR *str,
xmlXPathContextPtr ctxt); xmlXPathContextPtr ctxt);

View File

@ -3122,11 +3122,11 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
if (isParameter) { if (isParameter) {
if ((ctxt->sax != NULL) && if ((ctxt->sax != NULL) &&
(ctxt->sax->getParameterEntity != NULL)) (ctxt->sax->getParameterEntity != NULL))
cur = ctxt->sax->getParameterEntity(ctxt, name); cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
} else { } else {
if ((ctxt->sax != NULL) && if ((ctxt->sax != NULL) &&
(ctxt->sax->getEntity != NULL)) (ctxt->sax->getEntity != NULL))
cur = ctxt->sax->getEntity(ctxt, name); cur = ctxt->sax->getEntity(ctxt->userData, name);
} }
if (cur != NULL) { if (cur != NULL) {
if (cur->orig != NULL) if (cur->orig != NULL)

View File

@ -637,4 +637,7 @@ int inputPush (xmlParserCtxtPtr ctxt,
xmlParserInputPtr value); xmlParserInputPtr value);
xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt); xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_PARSER_INTERNALS_H__ */ #endif /* __XML_PARSER_INTERNALS_H__ */

View File

@ -125,7 +125,7 @@ void testXPath(const char *str) {
xmlXPathObjectPtr res; xmlXPathObjectPtr res;
xmlXPathContextPtr ctxt; xmlXPathContextPtr ctxt;
ctxt = xmlXPathNewContext(document, NULL, NULL); ctxt = xmlXPathNewContext(document);
if (expr) if (expr)
res = xmlXPathEvalExpression(BAD_CAST str, ctxt); res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
else else

2
tree.c
View File

@ -395,6 +395,7 @@ xmlNewDoc(const CHAR *version) {
cur->standalone = -1; cur->standalone = -1;
cur->compression = xmlCompressMode; cur->compression = xmlCompressMode;
cur->ids = NULL; cur->ids = NULL;
cur->refs = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
cur->vepv = NULL; cur->vepv = NULL;
@ -425,6 +426,7 @@ xmlFreeDoc(xmlDocPtr cur) {
if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset); if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset);
if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs); if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids); if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
memset(cur, -1, sizeof(xmlDoc)); memset(cur, -1, sizeof(xmlDoc));
xmlFree(cur); xmlFree(cur);
} }

18
tree.h
View File

@ -210,6 +210,17 @@ typedef struct xmlID {
} xmlID; } xmlID;
typedef xmlID *xmlIDPtr; typedef xmlID *xmlIDPtr;
/*
* An XML IDREF instance.
*/
typedef struct xmlRef {
struct xmlRef *next; /* next Ref */
const CHAR *value; /* The Ref name */
xmlAttrPtr attr; /* The attribut holding it */
} xmlRef;
typedef xmlRef *xmlRefPtr;
/* /*
* A node in an XML tree. * A node in an XML tree.
*/ */
@ -253,6 +264,7 @@ typedef struct xmlDoc {
struct xmlNs *oldNs; /* Global namespace, the old way */ struct xmlNs *oldNs; /* Global namespace, the old way */
struct xmlNode *root; /* the document tree */ struct xmlNode *root; /* the document tree */
void *ids; /* Hash table for ID attributes if any */ void *ids; /* Hash table for ID attributes if any */
void *refs; /* Hash table for IDREFs attributes if any */
} _xmlDoc; } _xmlDoc;
typedef _xmlDoc xmlDoc; typedef _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr; typedef xmlDoc *xmlDocPtr;
@ -440,6 +452,12 @@ const CHAR * xmlNodeGetLang (xmlNodePtr cur);
void xmlNodeSetLang (xmlNodePtr cur, void xmlNodeSetLang (xmlNodePtr cur,
const CHAR *lang); const CHAR *lang);
/*
* Removing content.
*/
int xmlRemoveProp (xmlAttrPtr attr); /* TODO */
int xmlRemoveNode (xmlNodePtr node); /* TODO */
/* /*
* Internal, don't use * Internal, don't use
*/ */

305
valid.c
View File

@ -1316,7 +1316,7 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
/************************************************************************ /************************************************************************
* * * *
* NOTATIONs * * IDs *
* * * *
************************************************************************/ ************************************************************************/
/** /**
@ -1549,6 +1549,228 @@ xmlGetID(xmlDocPtr doc, const CHAR *ID) {
return(NULL); return(NULL);
} }
/************************************************************************
* *
* 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
xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const CHAR *value,
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)
xmlFree((CHAR *) ref->value);
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
xmlGetRef(xmlDocPtr doc, const CHAR *Ref) {
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);
}
/************************************************************************ /************************************************************************
* * * *
* Routines for validity checking * * Routines for validity checking *
@ -2165,6 +2387,10 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlAddID(ctxt, doc, value, attr); xmlAddID(ctxt, doc, value, attr);
} }
if (attrDecl->type == XML_ATTRIBUTE_IDREF) {
xmlAddRef(ctxt, doc, value, attr);
}
/* Validity Constraint: Notation Attributes */ /* Validity Constraint: Notation Attributes */
if (attrDecl->type == XML_ATTRIBUTE_NOTATION) { if (attrDecl->type == XML_ATTRIBUTE_NOTATION) {
xmlEnumerationPtr tree = attrDecl->tree; xmlEnumerationPtr tree = attrDecl->tree;
@ -2610,9 +2836,75 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
int int
xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) { xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
xmlNodePtr child;
xmlAttrPtr attr;
CHAR *value;
int ret = 1;
/* TODO xmlValidateElement */
if (elem == NULL) return(0);
CHECK_DTD; CHECK_DTD;
return(1); 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)
free(value);
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);
} }
/** /**
@ -2630,6 +2922,7 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
int int
xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) { xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
/* TODO xmlValidateDtd */
return(1); return(1);
} }
@ -2640,7 +2933,7 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
* *
* Try to validate the document instance * Try to validate the document instance
* *
* basically it does the all the checks described by the * basically it does the all the checks described by the XML Rec
* i.e. validates the internal and external subset (if present) * i.e. validates the internal and external subset (if present)
* and validate the document tree. * and validate the document tree.
* *
@ -2649,8 +2942,12 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
int int
xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
int ret;
if (!xmlValidateRoot(ctxt, doc)) return(0); if (!xmlValidateRoot(ctxt, doc)) return(0);
return(1); ret = xmlValidateElement(ctxt, doc, doc->root);
ret &= xmlValidateDocumentFinal(ctxt, doc);
return(ret);
} }

27
valid.h
View File

@ -88,6 +88,20 @@ typedef struct xmlIDTable {
} xmlIDTable; } xmlIDTable;
typedef xmlIDTable *xmlIDTablePtr; typedef xmlIDTable *xmlIDTablePtr;
/*
* ALl Refs attributes are stored in a table
* there is one table per document
*/
#define XML_MIN_REF_TABLE 32
typedef struct xmlRefTable {
int nb_refs; /* number of refs stored */
int max_refs; /* maximum number of refs */
xmlRefPtr *table; /* the table of refs */
} xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
/* Notation */ /* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt, xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
xmlDtdPtr dtd, xmlDtdPtr dtd,
@ -148,6 +162,17 @@ int xmlIsID (xmlDocPtr doc,
xmlNodePtr elem, xmlNodePtr elem,
xmlAttrPtr attr); xmlAttrPtr attr);
/* IDREFs */
xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
xmlDocPtr doc,
const CHAR *value,
xmlAttrPtr attr);
xmlRefTablePtr xmlCopyRefTable (xmlRefTablePtr table);
void xmlFreeRefTable (xmlRefTablePtr table);
int xmlIsRef (xmlDocPtr doc,
xmlNodePtr elem,
xmlAttrPtr attr);
/** /**
* The public function calls related to validity checking * The public function calls related to validity checking
*/ */
@ -181,6 +206,8 @@ int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
xmlNodePtr elem, xmlNodePtr elem,
xmlAttrPtr attr, xmlAttrPtr attr,
const CHAR *value); const CHAR *value);
int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
xmlDocPtr doc);
int xmlValidateNotationUse (xmlValidCtxtPtr ctxt, int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
xmlDocPtr doc, xmlDocPtr doc,
const CHAR *notationName); const CHAR *notationName);

22
xpath.c
View File

@ -769,7 +769,7 @@ xmlXPathFreeObject(xmlXPathObjectPtr obj) {
* Returns the xmlXPathContext just allocated. * Returns the xmlXPathContext just allocated.
*/ */
xmlXPathContextPtr xmlXPathContextPtr
xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions) { xmlXPathNewContext(xmlDocPtr doc) {
xmlXPathContextPtr ret; xmlXPathContextPtr ret;
ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext)); ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
@ -779,9 +779,25 @@ xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions) {
} }
memset(ret, 0 , (size_t) sizeof(xmlXPathContext)); memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
ret->doc = doc; ret->doc = doc;
ret->variables = variables;
ret->functions = functions; ret->nb_variables = 0;
ret->max_variables = 0;
ret->variables = NULL;
ret->nb_types = 0;
ret->max_types = 0;
ret->types = NULL;
ret->nb_funcs = 0;
ret->max_funcs = 0;
ret->funcs = NULL;
ret->nb_axis = 0;
ret->max_axis = 0;
ret->axis = NULL;
ret->namespaces = NULL; ret->namespaces = NULL;
ret->user = NULL;
ret->nsNr = 0; ret->nsNr = 0;
return(ret); return(ret);
} }

107
xpath.h
View File

@ -14,6 +14,8 @@
#include "tree.h" #include "tree.h"
typedef struct xmlXPathParserContext *xmlXPathParserContextPtr;
/* /*
* A node-set (an unordered collection of nodes without duplicates) * A node-set (an unordered collection of nodes without duplicates)
*/ */
@ -37,6 +39,7 @@ typedef struct xmlNodeSet {
#define XPATH_BOOLEAN 2 #define XPATH_BOOLEAN 2
#define XPATH_NUMBER 3 #define XPATH_NUMBER 3
#define XPATH_STRING 4 #define XPATH_STRING 4
#define XPATH_USERS 5
typedef struct xmlXPathObject { typedef struct xmlXPathObject {
int type; int type;
@ -44,8 +47,66 @@ typedef struct xmlXPathObject {
int boolval; int boolval;
double floatval; double floatval;
CHAR *stringval; CHAR *stringval;
void *user;
} xmlXPathObject, *xmlXPathObjectPtr; } xmlXPathObject, *xmlXPathObjectPtr;
/*
* A conversion function is associated to a type and used to cast
* the new type to primitive values.
*/
typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
/*
* Extra type: a name and a conversion function.
*/
typedef struct xmlXPathType {
const CHAR *name; /* the type name */
xmlXPathConvertFunc func; /* the conversion function */
} xmlXPathType, *xmlXPathTypePtr;
/*
* Extra variable: a name and a value.
*/
typedef struct xmlXPathVariable {
const CHAR *name; /* the variable name */
xmlXPathObjectPtr value; /* the value */
} xmlXPathVariable, *xmlXPathVariablePtr;
/*
* an evaluation function, the parameters are on the context stack
*/
typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt, int nargs);
/*
* Extra function: a name and a evaluation function.
*/
typedef struct xmlXPathFunct {
const CHAR *name; /* the function name */
xmlXPathEvalFunc func; /* the evaluation function */
} xmlXPathFunc, *xmlXPathFuncPtr;
/*
* An axis traversal function. To traverse an axis, the engine calls
* the first time with cur == NULL and repeat until the function returns
* NULL indicating the end of the axis traversal.
*/
typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr cur);
/*
* Extra axis: a name and an axis function.
*/
typedef struct xmlXPathAxis {
const CHAR *name; /* the axis name */
xmlXPathAxisFunc func; /* the search function */
} xmlXPathAxis, *xmlXPathAxisPtr;
/* /*
* Expression evaluation occurs with respect to a context. * Expression evaluation occurs with respect to a context.
* he context consists of: * he context consists of:
@ -60,10 +121,27 @@ typedef struct xmlXPathContext {
xmlDocPtr doc; /* The current document */ xmlDocPtr doc; /* The current document */
xmlNodePtr node; /* The current node */ xmlNodePtr node; /* The current node */
xmlNodeSetPtr nodelist; /* The current node list */ xmlNodeSetPtr nodelist; /* The current node list */
void *variables; /* TODO !!!! */
void *functions; /* TODO !!!! */ int nb_variables; /* number of defined variables */
int max_variables; /* max number of variables */
xmlXPathVariablePtr *variables; /* Array of defined variables */
int nb_types; /* number of defined types */
int max_types; /* max number of types */
xmlXPathTypePtr *types; /* Array of defined types */
int nb_funcs; /* number of defined funcs */
int max_funcs; /* max number of funcs */
xmlXPathFuncPtr *funcs; /* Array of defined funcs */
int nb_axis; /* number of defined axis */
int max_axis; /* max number of axis */
xmlXPathAxisPtr *axis; /* Array of defined axis */
/* Namespace traversal should be implemented with user */
xmlNsPtr *namespaces; /* The namespaces lookup */ xmlNsPtr *namespaces; /* The namespaces lookup */
int nsNr; /* the current Namespace index */ int nsNr; /* the current Namespace index */
void *user; /* user defined extra info */
} xmlXPathContext, *xmlXPathContextPtr; } xmlXPathContext, *xmlXPathContextPtr;
/* /*
@ -81,7 +159,7 @@ typedef struct xmlXPathParserContext {
int valueNr; /* number of values stacked */ int valueNr; /* number of values stacked */
int valueMax; /* max number of values stacked */ int valueMax; /* max number of values stacked */
xmlXPathObjectPtr *valueTab; /* stack of values */ xmlXPathObjectPtr *valueTab; /* stack of values */
} xmlXPathParserContext, *xmlXPathParserContextPtr; } xmlXPathParserContext;
/* /*
* An XPath function * An XPath function
@ -97,9 +175,26 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
* * * *
************************************************************************/ ************************************************************************/
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc, /**
void *variables, * Registering extensions to the expression language
void *functions); */
/* TODO */ int xmlXPathRegisterType (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathConvertFunc f);
/* TODO */ int xmlXPathRegisterAxis (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathAxisFunc f);
/* TODO */ int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathFunction f);
/* TODO */ int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
const CHAR *name,
xmlXPathObject value);
/**
* Evaluation functions.
*/
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
void xmlXPathFreeContext (xmlXPathContextPtr ctxt); void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
xmlXPathObjectPtr xmlXPathEval (const CHAR *str, xmlXPathObjectPtr xmlXPathEval (const CHAR *str,
xmlXPathContextPtr ctxt); xmlXPathContextPtr ctxt);