mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-02-05 05:47:00 +03:00
Bug fixes, improvement on ID/IDREF support, 1.6.2, no memleaks, Daniel
This commit is contained in:
parent
72bd1001e2
commit
c08a2c6fd4
12
ChangeLog
12
ChangeLog
@ -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>
|
||||
|
||||
* doc/Makefile.am: replaced "install -d " with "mkinstalldirs" -
|
||||
|
2
HACKING
2
HACKING
@ -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
|
||||
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
|
||||
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).
|
||||
|
||||
thanks in advance for following the rule,
|
||||
|
@ -1133,6 +1133,8 @@ htmlNewDoc(const CHAR *URI, const CHAR *ExternalID) {
|
||||
cur->encoding = NULL;
|
||||
cur->standalone = 1;
|
||||
cur->compression = 0;
|
||||
cur->ids = NULL;
|
||||
cur->refs = NULL;
|
||||
#ifndef XML_WITHOUT_CORBA
|
||||
cur->_private = NULL;
|
||||
cur->vepv = NULL;
|
||||
|
7
SAX.c
7
SAX.c
@ -492,10 +492,13 @@ startDocument(void *ctx)
|
||||
void
|
||||
endDocument(void *ctx)
|
||||
{
|
||||
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
|
||||
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
||||
#ifdef DEBUG_SAX
|
||||
fprintf(stderr, "SAX.endDocument()\n");
|
||||
#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))
|
||||
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)
|
||||
|
@ -5,7 +5,7 @@ AM_CONFIG_HEADER(config.h)
|
||||
|
||||
LIBXML_MAJOR_VERSION=1
|
||||
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_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION
|
||||
|
||||
|
@ -529,7 +529,7 @@ core.</p>
|
||||
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
|
||||
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
|
||||
document. The DOM library will allow accessing and modifying "live" documents
|
||||
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>$Id$</p>
|
||||
<p>$Id: xml.html,v 1.7 1999/09/04 18:27:23 veillard Exp $</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -637,4 +637,7 @@ int inputPush (xmlParserCtxtPtr ctxt,
|
||||
xmlParserInputPtr value);
|
||||
xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __XML_PARSER_INTERNALS_H__ */
|
||||
|
@ -210,6 +210,17 @@ typedef struct xmlID {
|
||||
} xmlID;
|
||||
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.
|
||||
*/
|
||||
@ -253,6 +264,7 @@ typedef struct xmlDoc {
|
||||
struct xmlNs *oldNs; /* Global namespace, the old way */
|
||||
struct xmlNode *root; /* the document tree */
|
||||
void *ids; /* Hash table for ID attributes if any */
|
||||
void *refs; /* Hash table for IDREFs attributes if any */
|
||||
} _xmlDoc;
|
||||
typedef _xmlDoc xmlDoc;
|
||||
typedef xmlDoc *xmlDocPtr;
|
||||
@ -440,6 +452,12 @@ const CHAR * xmlNodeGetLang (xmlNodePtr cur);
|
||||
void xmlNodeSetLang (xmlNodePtr cur,
|
||||
const CHAR *lang);
|
||||
|
||||
/*
|
||||
* Removing content.
|
||||
*/
|
||||
int xmlRemoveProp (xmlAttrPtr attr); /* TODO */
|
||||
int xmlRemoveNode (xmlNodePtr node); /* TODO */
|
||||
|
||||
/*
|
||||
* Internal, don't use
|
||||
*/
|
||||
|
@ -88,6 +88,20 @@ typedef struct xmlIDTable {
|
||||
} xmlIDTable;
|
||||
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 */
|
||||
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
|
||||
xmlDtdPtr dtd,
|
||||
@ -148,6 +162,17 @@ int xmlIsID (xmlDocPtr doc,
|
||||
xmlNodePtr elem,
|
||||
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
|
||||
*/
|
||||
@ -181,6 +206,8 @@ int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
|
||||
xmlNodePtr elem,
|
||||
xmlAttrPtr attr,
|
||||
const CHAR *value);
|
||||
int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
|
||||
xmlDocPtr doc);
|
||||
int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
|
||||
xmlDocPtr doc,
|
||||
const CHAR *notationName);
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
typedef struct xmlXPathParserContext *xmlXPathParserContextPtr;
|
||||
|
||||
/*
|
||||
* A node-set (an unordered collection of nodes without duplicates)
|
||||
*/
|
||||
@ -37,6 +39,7 @@ typedef struct xmlNodeSet {
|
||||
#define XPATH_BOOLEAN 2
|
||||
#define XPATH_NUMBER 3
|
||||
#define XPATH_STRING 4
|
||||
#define XPATH_USERS 5
|
||||
|
||||
typedef struct xmlXPathObject {
|
||||
int type;
|
||||
@ -44,8 +47,66 @@ typedef struct xmlXPathObject {
|
||||
int boolval;
|
||||
double floatval;
|
||||
CHAR *stringval;
|
||||
void *user;
|
||||
} 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.
|
||||
* he context consists of:
|
||||
@ -60,10 +121,27 @@ typedef struct xmlXPathContext {
|
||||
xmlDocPtr doc; /* The current document */
|
||||
xmlNodePtr node; /* The current node */
|
||||
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 */
|
||||
int nsNr; /* the current Namespace index */
|
||||
void *user; /* user defined extra info */
|
||||
} xmlXPathContext, *xmlXPathContextPtr;
|
||||
|
||||
/*
|
||||
@ -81,7 +159,7 @@ typedef struct xmlXPathParserContext {
|
||||
int valueNr; /* number of values stacked */
|
||||
int valueMax; /* max number of values stacked */
|
||||
xmlXPathObjectPtr *valueTab; /* stack of values */
|
||||
} xmlXPathParserContext, *xmlXPathParserContextPtr;
|
||||
} xmlXPathParserContext;
|
||||
|
||||
/*
|
||||
* An XPath function
|
||||
@ -97,9 +175,26 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc,
|
||||
void *variables,
|
||||
void *functions);
|
||||
/**
|
||||
* Registering extensions to the expression language
|
||||
*/
|
||||
/* 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);
|
||||
xmlXPathObjectPtr xmlXPathEval (const CHAR *str,
|
||||
xmlXPathContextPtr ctxt);
|
||||
|
4
parser.c
4
parser.c
@ -3122,11 +3122,11 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
|
||||
if (isParameter) {
|
||||
if ((ctxt->sax != NULL) &&
|
||||
(ctxt->sax->getParameterEntity != NULL))
|
||||
cur = ctxt->sax->getParameterEntity(ctxt, name);
|
||||
cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
|
||||
} else {
|
||||
if ((ctxt->sax != NULL) &&
|
||||
(ctxt->sax->getEntity != NULL))
|
||||
cur = ctxt->sax->getEntity(ctxt, name);
|
||||
cur = ctxt->sax->getEntity(ctxt->userData, name);
|
||||
}
|
||||
if (cur != NULL) {
|
||||
if (cur->orig != NULL)
|
||||
|
@ -637,4 +637,7 @@ int inputPush (xmlParserCtxtPtr ctxt,
|
||||
xmlParserInputPtr value);
|
||||
xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __XML_PARSER_INTERNALS_H__ */
|
||||
|
@ -125,7 +125,7 @@ void testXPath(const char *str) {
|
||||
xmlXPathObjectPtr res;
|
||||
xmlXPathContextPtr ctxt;
|
||||
|
||||
ctxt = xmlXPathNewContext(document, NULL, NULL);
|
||||
ctxt = xmlXPathNewContext(document);
|
||||
if (expr)
|
||||
res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
|
||||
else
|
||||
|
2
tree.c
2
tree.c
@ -395,6 +395,7 @@ xmlNewDoc(const CHAR *version) {
|
||||
cur->standalone = -1;
|
||||
cur->compression = xmlCompressMode;
|
||||
cur->ids = NULL;
|
||||
cur->refs = NULL;
|
||||
#ifndef XML_WITHOUT_CORBA
|
||||
cur->_private = NULL;
|
||||
cur->vepv = NULL;
|
||||
@ -425,6 +426,7 @@ xmlFreeDoc(xmlDocPtr cur) {
|
||||
if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset);
|
||||
if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
|
||||
if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
|
||||
if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
|
||||
memset(cur, -1, sizeof(xmlDoc));
|
||||
xmlFree(cur);
|
||||
}
|
||||
|
18
tree.h
18
tree.h
@ -210,6 +210,17 @@ typedef struct xmlID {
|
||||
} xmlID;
|
||||
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.
|
||||
*/
|
||||
@ -253,6 +264,7 @@ typedef struct xmlDoc {
|
||||
struct xmlNs *oldNs; /* Global namespace, the old way */
|
||||
struct xmlNode *root; /* the document tree */
|
||||
void *ids; /* Hash table for ID attributes if any */
|
||||
void *refs; /* Hash table for IDREFs attributes if any */
|
||||
} _xmlDoc;
|
||||
typedef _xmlDoc xmlDoc;
|
||||
typedef xmlDoc *xmlDocPtr;
|
||||
@ -440,6 +452,12 @@ const CHAR * xmlNodeGetLang (xmlNodePtr cur);
|
||||
void xmlNodeSetLang (xmlNodePtr cur,
|
||||
const CHAR *lang);
|
||||
|
||||
/*
|
||||
* Removing content.
|
||||
*/
|
||||
int xmlRemoveProp (xmlAttrPtr attr); /* TODO */
|
||||
int xmlRemoveNode (xmlNodePtr node); /* TODO */
|
||||
|
||||
/*
|
||||
* Internal, don't use
|
||||
*/
|
||||
|
305
valid.c
305
valid.c
@ -1316,7 +1316,7 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* NOTATIONs *
|
||||
* IDs *
|
||||
* *
|
||||
************************************************************************/
|
||||
/**
|
||||
@ -1549,6 +1549,228 @@ xmlGetID(xmlDocPtr doc, const CHAR *ID) {
|
||||
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 *
|
||||
@ -2165,6 +2387,10 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
|
||||
xmlAddID(ctxt, doc, value, attr);
|
||||
}
|
||||
|
||||
if (attrDecl->type == XML_ATTRIBUTE_IDREF) {
|
||||
xmlAddRef(ctxt, doc, value, attr);
|
||||
}
|
||||
|
||||
/* Validity Constraint: Notation Attributes */
|
||||
if (attrDecl->type == XML_ATTRIBUTE_NOTATION) {
|
||||
xmlEnumerationPtr tree = attrDecl->tree;
|
||||
@ -2610,9 +2836,75 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
|
||||
|
||||
int
|
||||
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;
|
||||
|
||||
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
|
||||
xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
|
||||
/* TODO xmlValidateDtd */
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -2640,7 +2933,7 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
|
||||
*
|
||||
* 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)
|
||||
* and validate the document tree.
|
||||
*
|
||||
@ -2649,8 +2942,12 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
|
||||
|
||||
int
|
||||
xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
|
||||
int ret;
|
||||
|
||||
if (!xmlValidateRoot(ctxt, doc)) return(0);
|
||||
|
||||
return(1);
|
||||
ret = xmlValidateElement(ctxt, doc, doc->root);
|
||||
ret &= xmlValidateDocumentFinal(ctxt, doc);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
27
valid.h
27
valid.h
@ -88,6 +88,20 @@ typedef struct xmlIDTable {
|
||||
} xmlIDTable;
|
||||
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 */
|
||||
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
|
||||
xmlDtdPtr dtd,
|
||||
@ -148,6 +162,17 @@ int xmlIsID (xmlDocPtr doc,
|
||||
xmlNodePtr elem,
|
||||
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
|
||||
*/
|
||||
@ -181,6 +206,8 @@ int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
|
||||
xmlNodePtr elem,
|
||||
xmlAttrPtr attr,
|
||||
const CHAR *value);
|
||||
int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
|
||||
xmlDocPtr doc);
|
||||
int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
|
||||
xmlDocPtr doc,
|
||||
const CHAR *notationName);
|
||||
|
22
xpath.c
22
xpath.c
@ -769,7 +769,7 @@ xmlXPathFreeObject(xmlXPathObjectPtr obj) {
|
||||
* Returns the xmlXPathContext just allocated.
|
||||
*/
|
||||
xmlXPathContextPtr
|
||||
xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions) {
|
||||
xmlXPathNewContext(xmlDocPtr doc) {
|
||||
xmlXPathContextPtr ret;
|
||||
|
||||
ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
|
||||
@ -779,9 +779,25 @@ xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions) {
|
||||
}
|
||||
memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
|
||||
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->user = NULL;
|
||||
ret->nsNr = 0;
|
||||
return(ret);
|
||||
}
|
||||
|
107
xpath.h
107
xpath.h
@ -14,6 +14,8 @@
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
typedef struct xmlXPathParserContext *xmlXPathParserContextPtr;
|
||||
|
||||
/*
|
||||
* A node-set (an unordered collection of nodes without duplicates)
|
||||
*/
|
||||
@ -37,6 +39,7 @@ typedef struct xmlNodeSet {
|
||||
#define XPATH_BOOLEAN 2
|
||||
#define XPATH_NUMBER 3
|
||||
#define XPATH_STRING 4
|
||||
#define XPATH_USERS 5
|
||||
|
||||
typedef struct xmlXPathObject {
|
||||
int type;
|
||||
@ -44,8 +47,66 @@ typedef struct xmlXPathObject {
|
||||
int boolval;
|
||||
double floatval;
|
||||
CHAR *stringval;
|
||||
void *user;
|
||||
} 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.
|
||||
* he context consists of:
|
||||
@ -60,10 +121,27 @@ typedef struct xmlXPathContext {
|
||||
xmlDocPtr doc; /* The current document */
|
||||
xmlNodePtr node; /* The current node */
|
||||
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 */
|
||||
int nsNr; /* the current Namespace index */
|
||||
void *user; /* user defined extra info */
|
||||
} xmlXPathContext, *xmlXPathContextPtr;
|
||||
|
||||
/*
|
||||
@ -81,7 +159,7 @@ typedef struct xmlXPathParserContext {
|
||||
int valueNr; /* number of values stacked */
|
||||
int valueMax; /* max number of values stacked */
|
||||
xmlXPathObjectPtr *valueTab; /* stack of values */
|
||||
} xmlXPathParserContext, *xmlXPathParserContextPtr;
|
||||
} xmlXPathParserContext;
|
||||
|
||||
/*
|
||||
* An XPath function
|
||||
@ -97,9 +175,26 @@ typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc,
|
||||
void *variables,
|
||||
void *functions);
|
||||
/**
|
||||
* Registering extensions to the expression language
|
||||
*/
|
||||
/* 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);
|
||||
xmlXPathObjectPtr xmlXPathEval (const CHAR *str,
|
||||
xmlXPathContextPtr ctxt);
|
||||
|
Loading…
x
Reference in New Issue
Block a user