1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

Speed, conformance testing, more parsing, general improvements, Daniel.

This commit is contained in:
Daniel Veillard
1999-01-17 19:11:59 +00:00
parent 3c2c2ce4af
commit 39a1f9a3a7
21 changed files with 1397 additions and 202 deletions

View File

@ -1,3 +1,12 @@
Sun Jan 17 20:06:36 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* parser.c, tree.[ch] : more work toward conformance testing,
added a last element to accelerate parsing of very flat structures
started working on internal subset Element content declaration.
* valid.[ch] : first cut at adding code toward validation.
* previous changes had also small impact on most files, especially
the conformance testing using James Clark test suite.
Sun Jan 17 14:45:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org> Sun Jan 17 14:45:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* test/* : updated the examples, most of them were not well * test/* : updated the examples, most of them were not well

View File

@ -16,7 +16,8 @@ libxml_la_SOURCES = \
error.h \ error.h \
parser.c \ parser.c \
debugXML.c \ debugXML.c \
tree.c tree.c \
valid.c
xmlincdir = $(includedir)/gnome-xml xmlincdir = $(includedir)/gnome-xml
xmlinc_HEADERS = \ xmlinc_HEADERS = \
@ -24,7 +25,8 @@ xmlinc_HEADERS = \
encoding.h \ encoding.h \
parser.h \ parser.h \
debugXML.h \ debugXML.h \
tree.h tree.h \
valid.h
DEPS = $(top_builddir)/libxml.la DEPS = $(top_builddir)/libxml.la
LDADDS = $(top_builddir)/libxml.la @Z_LIBS@ LDADDS = $(top_builddir)/libxml.la @Z_LIBS@

2
SAX.c
View File

@ -1,6 +1,8 @@
/* /*
* SAX.c : Default SAX handler to build a tree. * SAX.c : Default SAX handler to build a tree.
* *
* See Copyright for the status of this software.
*
* Daniel Veillard <Daniel.Veillard@w3.org> * Daniel Veillard <Daniel.Veillard@w3.org>
*/ */

View File

@ -2,6 +2,8 @@
* debugXML.c : This is a set of routines used for debugging the tree * debugXML.c : This is a set of routines used for debugging the tree
* produced by the XML parser. * produced by the XML parser.
* *
* See Copyright for the status of this software.
*
* Daniel Veillard <Daniel.Veillard@w3.org> * Daniel Veillard <Daniel.Veillard@w3.org>
*/ */

View File

@ -16,8 +16,6 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$
*
* Daniel.Veillard@w3.org * Daniel.Veillard@w3.org
*/ */

View File

@ -17,8 +17,6 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$
*
* Daniel.Veillard@w3.org * Daniel.Veillard@w3.org
*/ */

View File

@ -3,7 +3,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#include <stdio.h> #include <stdio.h>
@ -186,14 +186,15 @@ xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) { const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
xmlEntitiesTablePtr table; xmlEntitiesTablePtr table;
if (doc->dtd == NULL) { if (doc->extSubset == NULL) {
fprintf(stderr, "xmlAddDtdEntity: document without Dtd !\n"); fprintf(stderr,
"xmlAddDtdEntity: document without external subset !\n");
return; return;
} }
table = (xmlEntitiesTablePtr) doc->dtd->entities; table = (xmlEntitiesTablePtr) doc->extSubset->entities;
if (table == NULL) { if (table == NULL) {
table = xmlCreateEntitiesTable(); table = xmlCreateEntitiesTable();
doc->dtd->entities = table; doc->extSubset->entities = table;
} }
xmlAddEntity(table, name, type, ExternalID, SystemID, content); xmlAddEntity(table, name, type, ExternalID, SystemID, content);
} }
@ -214,12 +215,22 @@ xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) { const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
xmlEntitiesTablePtr table; xmlEntitiesTablePtr table;
table = (xmlEntitiesTablePtr) doc->entities; if (doc == NULL) {
fprintf(stderr,
"xmlAddDocEntity: document is NULL !\n");
return;
}
if (doc->intSubset == NULL) {
fprintf(stderr,
"xmlAddDtdEntity: document without internal subset !\n");
return;
}
table = (xmlEntitiesTablePtr) doc->intSubset->entities;
if (table == NULL) { if (table == NULL) {
table = xmlCreateEntitiesTable(); table = xmlCreateEntitiesTable();
doc->entities = table; doc->intSubset->entities = table;
} }
xmlAddEntity(doc->entities, name, type, ExternalID, SystemID, content); xmlAddEntity(table, name, type, ExternalID, SystemID, content);
} }
/** /**
@ -238,8 +249,8 @@ xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
xmlEntityPtr cur; xmlEntityPtr cur;
xmlEntitiesTablePtr table; xmlEntitiesTablePtr table;
if ((doc->dtd != NULL) && (doc->dtd->entities != NULL)) { if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
table = (xmlEntitiesTablePtr) doc->dtd->entities; table = (xmlEntitiesTablePtr) doc->extSubset->entities;
for (i = 0;i < table->nb_entities;i++) { for (i = 0;i < table->nb_entities;i++) {
cur = &table->table[i]; cur = &table->table[i];
if (!xmlStrcmp(cur->name, name)) return(cur); if (!xmlStrcmp(cur->name, name)) return(cur);
@ -265,8 +276,8 @@ xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
xmlEntityPtr cur; xmlEntityPtr cur;
xmlEntitiesTablePtr table; xmlEntitiesTablePtr table;
if (doc->entities != NULL) { if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
table = (xmlEntitiesTablePtr) doc->entities; table = (xmlEntitiesTablePtr) doc->intSubset->entities;
for (i = 0;i < table->nb_entities;i++) { for (i = 0;i < table->nb_entities;i++) {
cur = &table->table[i]; cur = &table->table[i];
if (!xmlStrcmp(cur->name, name)) return(cur); if (!xmlStrcmp(cur->name, name)) return(cur);

View File

@ -3,7 +3,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifndef __XML_ENTITIES_H__ #ifndef __XML_ENTITIES_H__

View File

@ -1,6 +1,8 @@
/* /*
* error.c: module displaying/handling XML parser errors * error.c: module displaying/handling XML parser errors
* *
* See Copyright for the status of this software.
*
* Daniel Veillard <Daniel.Veillard@w3.org> * Daniel Veillard <Daniel.Veillard@w3.org>
*/ */

View File

@ -17,8 +17,6 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$
*
* Daniel.Veillard@w3.org * Daniel.Veillard@w3.org
*/ */

View File

@ -3,7 +3,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifndef __XML_ENTITIES_H__ #ifndef __XML_ENTITIES_H__

View File

@ -3,7 +3,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifndef __XML_PARSER_H__ #ifndef __XML_PARSER_H__
@ -46,6 +46,7 @@ typedef struct xmlParserNodeInfoSeq {
typedef struct xmlParserCtxt { typedef struct xmlParserCtxt {
struct xmlSAXHandler *sax; /* The SAX handler */ struct xmlSAXHandler *sax; /* The SAX handler */
xmlDocPtr doc; /* the document being built */ xmlDocPtr doc; /* the document being built */
int wellFormed; /* is the document well formed */
/* Input stream stack */ /* Input stream stack */
xmlParserInputPtr input; /* Current input stream */ xmlParserInputPtr input; /* Current input stream */
@ -131,15 +132,8 @@ extern xmlSAXHandler xmlDefaultSAXHandler;
#include "entities.h" #include "entities.h"
/* /*
* Interfaces * CHAR handling
*/ */
extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
extern xmlDocPtr xmlParseDoc(CHAR *cur);
extern xmlDocPtr xmlParseMemory(char *buffer, int size);
extern xmlDocPtr xmlParseFile(const char *filename);
extern xmlDocPtr xmlSAXParseDoc(xmlSAXHandlerPtr sax, CHAR *cur);
extern xmlDocPtr xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer, int size);
extern xmlDocPtr xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename);
extern CHAR *xmlStrdup(const CHAR *input); extern CHAR *xmlStrdup(const CHAR *input);
extern CHAR *xmlStrndup(const CHAR *input, int n); extern CHAR *xmlStrndup(const CHAR *input, int n);
extern CHAR *xmlStrchr(const CHAR *str, CHAR val); extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
@ -149,6 +143,29 @@ extern int xmlStrlen(const CHAR *str);
extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add); extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add);
extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len); extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len);
/*
* Interfaces
*/
extern xmlDocPtr xmlParseDoc(CHAR *cur);
extern xmlDocPtr xmlParseMemory(char *buffer, int size);
extern xmlDocPtr xmlParseFile(const char *filename);
/*
* Recovery mode
*/
extern xmlDocPtr xmlRecoverDoc(CHAR *cur);
extern xmlDocPtr xmlRecoverMemory(char *buffer, int size);
extern xmlDocPtr xmlRecoverFile(const char *filename);
/*
* Internal routines
*/
extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
extern xmlDocPtr xmlSAXParseDoc(xmlSAXHandlerPtr sax, CHAR *cur, int recovery);
extern xmlDocPtr xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer,
int size, int recovery);
extern xmlDocPtr xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
int recovery);
extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx); extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx); extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer, extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,

View File

@ -4,7 +4,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifndef __XML_TREE_H__ #ifndef __XML_TREE_H__
@ -15,6 +15,8 @@
extern "C" { extern "C" {
#endif #endif
#include <stdio.h>
/* /*
* The different element types carried by an XML tree * The different element types carried by an XML tree
* *
@ -61,18 +63,51 @@ typedef unsigned char CHAR;
* TODO !!!! * TODO !!!!
*/ */
#define XML_ATTRIBUTE_NONE 1
#define XML_ATTRIBUTE_REQUIRED 2
#define XML_ATTRIBUTE_IMPLIED 3
#define XML_ATTRIBUTE_FIXED 4
#define XML_ATTRIBUTE_STRING 1
#define XML_ATTRIBUTE_ID 2
#define XML_ATTRIBUTE_IDREF 3
#define XML_ATTRIBUTE_IDREFS 4
#define XML_ATTRIBUTE_ENTITY 5
#define XML_ATTRIBUTE_ENTITIES 6
#define XML_ATTRIBUTE_NMTOKEN 7
#define XML_ATTRIBUTE_NMTOKENS 8
#define XML_ATTRIBUTE_ENUMERATED 9
/* /*
* a DTD Element definition. * a DTD Element definition.
*/ */
#define XML_ELEMENT_CONTENT_PCDATA 1
#define XML_ELEMENT_CONTENT_ELEMENT 2
#define XML_ELEMENT_CONTENT_SEQ 3
#define XML_ELEMENT_CONTENT_OR 4
#define XML_ELEMENT_CONTENT_ONCE 1
#define XML_ELEMENT_CONTENT_OPT 2
#define XML_ELEMENT_CONTENT_MULT 3
#define XML_ELEMENT_CONTENT_PLUS 4
typedef struct xmlElementContent {
int type; /* PCDATA, ELEMENT, SEQ or OR */
int ocur; /* ONCE, OPT, MULT or PLUS */
const CHAR *name; /* Element name */
struct xmlElementContent *c1; /* first child */
struct xmlElementContent *c2; /* second child */
} xmlElementContent, *xmlElementContentPtr;
#define XML_ELEMENT_TYPE_EMPTY 1 #define XML_ELEMENT_TYPE_EMPTY 1
#define XML_ELEMENT_TYPE_ANY 2 #define XML_ELEMENT_TYPE_ANY 2
#define XML_ELEMENT_TYPE_MIXED 3 #define XML_ELEMENT_TYPE_MIXED 3
#define XML_ELEMENT_TYPE_ELEMENT 4 #define XML_ELEMENT_TYPE_ELEMENT 4
typedef struct xmlElement { typedef struct xmlElement {
const CHAR *name; /* Element name */ const CHAR *name; /* Element name */
int type; /* type (too simple, to extend ...) */ int type; /* The type */
/* TODO !!! more needed */ xmlElementContentPtr content; /* the allowed element content */
} xmlElement, *xmlElementPtr; } xmlElement, *xmlElementPtr;
/* /*
@ -132,6 +167,7 @@ typedef struct xmlNode {
struct xmlNode *next; /* next sibling link */ struct xmlNode *next; /* next sibling link */
struct xmlNode *prev; /* previous sibling link */ struct xmlNode *prev; /* previous sibling link */
struct xmlNode *childs; /* parent->childs link */ struct xmlNode *childs; /* parent->childs link */
struct xmlNode *last; /* last child link */
struct xmlAttr *properties; /* properties list */ struct xmlAttr *properties; /* properties list */
const CHAR *name; /* the name of the node, or the entity */ const CHAR *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */ xmlNs *ns; /* pointer to the associated namespace */
@ -153,9 +189,9 @@ typedef struct xmlDoc {
const CHAR *encoding; /* encoding, if any */ const CHAR *encoding; /* encoding, if any */
int compression;/* level of zlib compression */ int compression;/* level of zlib compression */
int standalone; /* standalone document (no external refs) */ int standalone; /* standalone document (no external refs) */
struct xmlDtd *dtd; /* the document DTD if available */ struct xmlDtd *intSubset; /* the document internal subset */
struct xmlDtd *extSubset; /* the document external subset */
struct xmlNs *oldNs; /* Global namespace, the old way */ struct xmlNs *oldNs; /* Global namespace, the old way */
void *entities; /* Hash table for general entities if any */
struct xmlNode *root; /* the document tree */ struct xmlNode *root; /* the document tree */
} xmlDoc, *xmlDocPtr; } xmlDoc, *xmlDocPtr;
@ -169,6 +205,8 @@ extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
/* /*
* Creating/freeing new structures * Creating/freeing new structures
*/ */
extern xmlDtdPtr xmlCreateIntSubset(xmlDocPtr doc, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID);
extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name, extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID); const CHAR *ExternalID, const CHAR *SystemID);
extern void xmlFreeDtd(xmlDtdPtr cur); extern void xmlFreeDtd(xmlDtdPtr cur);
@ -240,7 +278,7 @@ extern xmlNsPtr xmlCopyNamespaceList(xmlNsPtr cur);
*/ */
extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name, extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
const CHAR *value); const CHAR *value);
extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name); extern CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value); extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value);
extern xmlNodePtr xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value, extern xmlNodePtr xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value,
int len); int len);

18
include/libxml/valid.h Normal file
View File

@ -0,0 +1,18 @@
/*
* valid.h : interface to the DTD handling and the validity checking
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@w3.org
*/
#ifndef __XML_VALID_H__
#define __XML_VALID_H__
#include "tree.h"
extern xmlElementPtr xmlAddElementDecl(xmlDtdPtr dtd, char *name, int type,
xmlElementContentPtr content);
extern xmlElementContentPtr xmlNewElementContent(CHAR *name, int type);
extern void xmlFreeElementContent(xmlElementContentPtr cur);
#endif /* __XML_VALID_H__ */

964
parser.c

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifndef __XML_PARSER_H__ #ifndef __XML_PARSER_H__
@ -46,6 +46,7 @@ typedef struct xmlParserNodeInfoSeq {
typedef struct xmlParserCtxt { typedef struct xmlParserCtxt {
struct xmlSAXHandler *sax; /* The SAX handler */ struct xmlSAXHandler *sax; /* The SAX handler */
xmlDocPtr doc; /* the document being built */ xmlDocPtr doc; /* the document being built */
int wellFormed; /* is the document well formed */
/* Input stream stack */ /* Input stream stack */
xmlParserInputPtr input; /* Current input stream */ xmlParserInputPtr input; /* Current input stream */
@ -131,15 +132,8 @@ extern xmlSAXHandler xmlDefaultSAXHandler;
#include "entities.h" #include "entities.h"
/* /*
* Interfaces * CHAR handling
*/ */
extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
extern xmlDocPtr xmlParseDoc(CHAR *cur);
extern xmlDocPtr xmlParseMemory(char *buffer, int size);
extern xmlDocPtr xmlParseFile(const char *filename);
extern xmlDocPtr xmlSAXParseDoc(xmlSAXHandlerPtr sax, CHAR *cur);
extern xmlDocPtr xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer, int size);
extern xmlDocPtr xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename);
extern CHAR *xmlStrdup(const CHAR *input); extern CHAR *xmlStrdup(const CHAR *input);
extern CHAR *xmlStrndup(const CHAR *input, int n); extern CHAR *xmlStrndup(const CHAR *input, int n);
extern CHAR *xmlStrchr(const CHAR *str, CHAR val); extern CHAR *xmlStrchr(const CHAR *str, CHAR val);
@ -149,6 +143,29 @@ extern int xmlStrlen(const CHAR *str);
extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add); extern CHAR *xmlStrcat(CHAR *cur, const CHAR *add);
extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len); extern CHAR *xmlStrncat(CHAR *cur, const CHAR *add, int len);
/*
* Interfaces
*/
extern xmlDocPtr xmlParseDoc(CHAR *cur);
extern xmlDocPtr xmlParseMemory(char *buffer, int size);
extern xmlDocPtr xmlParseFile(const char *filename);
/*
* Recovery mode
*/
extern xmlDocPtr xmlRecoverDoc(CHAR *cur);
extern xmlDocPtr xmlRecoverMemory(char *buffer, int size);
extern xmlDocPtr xmlRecoverFile(const char *filename);
/*
* Internal routines
*/
extern int xmlParseDocument(xmlParserCtxtPtr ctxt);
extern xmlDocPtr xmlSAXParseDoc(xmlSAXHandlerPtr sax, CHAR *cur, int recovery);
extern xmlDocPtr xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer,
int size, int recovery);
extern xmlDocPtr xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
int recovery);
extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx); extern void xmlInitParserCtxt(xmlParserCtxtPtr ctx);
extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx); extern void xmlClearParserCtxt(xmlParserCtxtPtr ctx);
extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer, extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,

View File

@ -3,7 +3,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifdef WIN32 #ifdef WIN32
@ -32,13 +32,14 @@
static int debug = 0; static int debug = 0;
static int copy = 0; static int copy = 0;
static int recovery = 0;
/* /*
* Note: there is a couple of errors introduced on purpose. * Note: there is a couple of errors introduced on purpose.
*/ */
static CHAR buffer[] = static CHAR buffer[] =
"\n\ "\n\
<?xml version=\"1.0\">\n\ <?xml version=\"1.0\"?>\n\
<?xml:namespace ns = \"http://www.ietf.org/standards/dav/\" prefix = \"D\"?>\n\ <?xml:namespace ns = \"http://www.ietf.org/standards/dav/\" prefix = \"D\"?>\n\
<?xml:namespace ns = \"http://www.w3.com/standards/z39.50/\" prefix = \"Z\"?>\n\ <?xml:namespace ns = \"http://www.w3.com/standards/z39.50/\" prefix = \"Z\"?>\n\
<D:propertyupdate>\n\ <D:propertyupdate>\n\
@ -109,7 +110,10 @@ void parseAndPrintFile(char *filename) {
/* /*
* build an XML tree from a string; * build an XML tree from a string;
*/ */
doc = xmlParseFile(filename); if (recovery)
doc = xmlRecoverFile(filename);
else
doc = xmlParseFile(filename);
/* /*
* test intermediate copy if needed. * test intermediate copy if needed.
@ -140,7 +144,10 @@ void parseAndPrintBuffer(CHAR *buf) {
/* /*
* build an XML tree from a string; * build an XML tree from a string;
*/ */
doc = xmlParseDoc(buf); if (recovery)
doc = xmlRecoverDoc(buf);
else
doc = xmlParseDoc(buf);
/* /*
* test intermediate copy if needed. * test intermediate copy if needed.
@ -174,6 +181,9 @@ int main(int argc, char **argv) {
debug++; debug++;
else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy"))) else if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
copy++; copy++;
else if ((!strcmp(argv[i], "-recover")) ||
(!strcmp(argv[i], "--recover")))
recovery++;
} }
for (i = 1; i < argc ; i++) { for (i = 1; i < argc ; i++) {
if (argv[i][0] != '-') { if (argv[i][0] != '-') {

179
tree.c
View File

@ -3,9 +3,9 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$
*
* TODO Cleanup the Dump mechanism. * TODO Cleanup the Dump mechanism.
*
* Daniel.Veillard@w3.org
*/ */
#include "config.h" #include "config.h"
@ -27,6 +27,15 @@ int xmlIndentTreeOutput = 1;
static int xmlCompressMode = 0; static int xmlCompressMode = 0;
#define UPDATE_LAST_CHILD(n) if ((n) != NULL) { \
xmlNodePtr ulccur = (n)->childs; \
if (ulccur == NULL) { \
(n)->last = NULL; \
} else { \
while (ulccur->next != NULL) ulccur = ulccur->next; \
(n)->last = ulccur; \
} }
/************************************************************************ /************************************************************************
* * * *
* Allocation and deallocation of basic structures * * Allocation and deallocation of basic structures *
@ -234,9 +243,10 @@ xmlNewDtd(xmlDocPtr doc, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID) { const CHAR *ExternalID, const CHAR *SystemID) {
xmlDtdPtr cur; xmlDtdPtr cur;
if ((doc != NULL) && (doc->dtd != NULL)) { if ((doc != NULL) && (doc->extSubset != NULL)) {
fprintf(stderr, "xmlNewDtd(%s): document %s already have a DTD %s\n", fprintf(stderr, "xmlNewDtd(%s): document %s already have a DTD %s\n",
/* !!! */ (char *) name, doc->name, /* !!! */ (char *)doc->dtd->name); /* !!! */ (char *) name, doc->name,
/* !!! */ (char *)doc->extSubset->name);
} }
/* /*
@ -263,7 +273,58 @@ xmlNewDtd(xmlDocPtr doc, const CHAR *name,
cur->elements = NULL; cur->elements = NULL;
cur->entities = NULL; cur->entities = NULL;
if (doc != NULL) if (doc != NULL)
doc->dtd = cur; doc->extSubset = cur;
return(cur);
}
/**
* xmlCreateIntSubset:
* @doc: the document pointer
* @name: the DTD name
* @ExternalID: the external ID
* @SystemID: the system ID
*
* Creatte the internal subset of a document
* return values: a pointer to the new DTD structure
*/
xmlDtdPtr
xmlCreateIntSubset(xmlDocPtr doc, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID) {
xmlDtdPtr cur;
if ((doc != NULL) && (doc->intSubset != NULL)) {
fprintf(stderr,
"xmlCreateIntSubset(): document %s already have an internal subset\n",
doc->name);
return(NULL);
}
/*
* Allocate a new DTD and fill the fields.
*/
cur = (xmlDtdPtr) malloc(sizeof(xmlDtd));
if (cur == NULL) {
fprintf(stderr, "xmlNewDtd : malloc failed\n");
return(NULL);
}
if (name != NULL)
cur->name = xmlStrdup(name);
else
cur->name = NULL;
if (ExternalID != NULL)
cur->ExternalID = xmlStrdup(ExternalID);
else
cur->ExternalID = NULL;
if (SystemID != NULL)
cur->SystemID = xmlStrdup(SystemID);
else
cur->SystemID = NULL;
cur->elements = NULL;
cur->entities = NULL;
if (doc != NULL)
doc->intSubset = cur;
return(cur); return(cur);
} }
@ -319,10 +380,10 @@ xmlNewDoc(const CHAR *version) {
cur->version = xmlStrdup(version); cur->version = xmlStrdup(version);
cur->name = NULL; cur->name = NULL;
cur->root = NULL; cur->root = NULL;
cur->dtd = NULL; cur->intSubset = NULL;
cur->extSubset = NULL;
cur->oldNs = NULL; cur->oldNs = NULL;
cur->encoding = NULL; cur->encoding = NULL;
cur->entities = NULL;
cur->standalone = -1; cur->standalone = -1;
cur->compression = xmlCompressMode; cur->compression = xmlCompressMode;
#ifndef WITHOUT_CORBA #ifndef WITHOUT_CORBA
@ -342,17 +403,18 @@ xmlNewDoc(const CHAR *version) {
void void
xmlFreeDoc(xmlDocPtr cur) { xmlFreeDoc(xmlDocPtr cur) {
if (cur == NULL) { if (cur == NULL) {
#ifdef DEBUG_TREE
fprintf(stderr, "xmlFreeDoc : document == NULL\n"); fprintf(stderr, "xmlFreeDoc : document == NULL\n");
#endif
return; return;
} }
free((char *) cur->version); free((char *) cur->version);
if (cur->name != NULL) free((char *) cur->name); if (cur->name != NULL) free((char *) cur->name);
if (cur->encoding != NULL) free((char *) cur->encoding); if (cur->encoding != NULL) free((char *) cur->encoding);
if (cur->root != NULL) xmlFreeNode(cur->root); if (cur->root != NULL) xmlFreeNode(cur->root);
if (cur->dtd != NULL) xmlFreeDtd(cur->dtd); if (cur->intSubset != NULL) xmlFreeDtd(cur->intSubset);
if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset);
if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs); if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
if (cur->entities != NULL)
xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
memset(cur, -1, sizeof(xmlDoc)); memset(cur, -1, sizeof(xmlDoc));
free(cur); free(cur);
} }
@ -803,6 +865,7 @@ xmlNewNode(xmlNsPtr ns, const CHAR *name) {
cur->next = NULL; cur->next = NULL;
cur->prev = NULL; cur->prev = NULL;
cur->childs = NULL; cur->childs = NULL;
cur->last = NULL;
cur->properties = NULL; cur->properties = NULL;
cur->name = xmlStrdup(name); cur->name = xmlStrdup(name);
cur->ns = ns; cur->ns = ns;
@ -834,8 +897,10 @@ xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
cur = xmlNewNode(ns, name); cur = xmlNewNode(ns, name);
if (cur != NULL) { if (cur != NULL) {
cur->doc = doc; cur->doc = doc;
if (content != NULL) if (content != NULL) {
cur->childs = xmlStringGetNodeList(doc, content); cur->childs = xmlStringGetNodeList(doc, content);
UPDATE_LAST_CHILD(cur);
}
} }
return(cur); return(cur);
} }
@ -867,6 +932,7 @@ xmlNewText(const CHAR *content) {
cur->next = NULL; cur->next = NULL;
cur->prev = NULL; cur->prev = NULL;
cur->childs = NULL; cur->childs = NULL;
cur->last = NULL;
cur->properties = NULL; cur->properties = NULL;
cur->type = XML_TEXT_NODE; cur->type = XML_TEXT_NODE;
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
@ -907,6 +973,7 @@ xmlNewReference(xmlDocPtr doc, const CHAR *name) {
cur->next = NULL; cur->next = NULL;
cur->prev = NULL; cur->prev = NULL;
cur->childs = NULL; cur->childs = NULL;
cur->last = NULL;
cur->properties = NULL; cur->properties = NULL;
if (name[0] == '&') { if (name[0] == '&') {
int len; int len;
@ -973,6 +1040,7 @@ xmlNewTextLen(const CHAR *content, int len) {
cur->prev = NULL; cur->prev = NULL;
cur->next = NULL; cur->next = NULL;
cur->childs = NULL; cur->childs = NULL;
cur->last = NULL;
cur->properties = NULL; cur->properties = NULL;
cur->type = XML_TEXT_NODE; cur->type = XML_TEXT_NODE;
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
@ -1030,6 +1098,7 @@ xmlNewComment(CHAR *content) {
cur->prev = NULL; cur->prev = NULL;
cur->next = NULL; cur->next = NULL;
cur->childs = NULL; cur->childs = NULL;
cur->last = NULL;
cur->properties = NULL; cur->properties = NULL;
cur->type = XML_COMMENT_NODE; cur->type = XML_COMMENT_NODE;
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
@ -1104,11 +1173,12 @@ xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
cur->doc = parent->doc; cur->doc = parent->doc;
if (parent->childs == NULL) { if (parent->childs == NULL) {
parent->childs = cur; parent->childs = cur;
parent->last = cur;
} else { } else {
prev = parent->childs; prev = parent->last;
while (prev->next != NULL) prev = prev->next;
prev->next = cur; prev->next = cur;
cur->prev = prev; cur->prev = prev;
parent->last = cur;
} }
return(cur); return(cur);
@ -1146,6 +1216,7 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
*/ */
cur->parent = parent; cur->parent = parent;
cur->doc = parent->doc; /* the parent may not be linked to a doc ! */ cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
/* /*
* Handle the case where parent->content != NULL, in that case it will * Handle the case where parent->content != NULL, in that case it will
* create a intermediate TEXT node. * create a intermediate TEXT node.
@ -1159,17 +1230,19 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
if (text->next != NULL) if (text->next != NULL)
text->next->prev = text; text->next->prev = text;
parent->childs = text; parent->childs = text;
UPDATE_LAST_CHILD(parent);
free(parent->content); free(parent->content);
parent->content = NULL; parent->content = NULL;
} }
} }
if (parent->childs == NULL) { if (parent->childs == NULL) {
parent->childs = cur; parent->childs = cur;
parent->last = cur;
} else { } else {
prev = parent->childs; prev = parent->last;
while (prev->next != NULL) prev = prev->next;
prev->next = cur; prev->next = cur;
cur->prev = prev; cur->prev = prev;
parent->last = cur;
} }
return(cur); return(cur);
@ -1184,23 +1257,11 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
*/ */
xmlNodePtr xmlNodePtr
xmlGetLastChild(xmlNodePtr parent) { xmlGetLastChild(xmlNodePtr parent) {
xmlNodePtr last;
if (parent == NULL) { if (parent == NULL) {
fprintf(stderr, "xmlGetLastChild : parent == NULL\n"); fprintf(stderr, "xmlGetLastChild : parent == NULL\n");
return(NULL); return(NULL);
} }
return(parent->last);
/*
* add the new element at the end of the childs list.
*/
if (parent->childs == NULL) {
return(NULL);
} else {
last = parent->childs;
while (last->next != NULL) last = last->next;
}
return(last);
} }
/** /**
@ -1264,6 +1325,8 @@ xmlUnlinkNode(xmlNodePtr cur) {
} }
if ((cur->parent != NULL) && (cur->parent->childs == cur)) if ((cur->parent != NULL) && (cur->parent->childs == cur))
cur->parent->childs = cur->next; cur->parent->childs = cur->next;
if ((cur->parent != NULL) && (cur->parent->last == cur))
cur->parent->last = cur->prev;
if (cur->next != NULL) if (cur->next != NULL)
cur->next->prev = cur->prev; cur->next->prev = cur->prev;
if (cur->prev != NULL) if (cur->prev != NULL)
@ -1419,6 +1482,7 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
ret->next = NULL; ret->next = NULL;
ret->prev = NULL; ret->prev = NULL;
ret->childs = NULL; ret->childs = NULL;
ret->last = NULL;
ret->properties = NULL; ret->properties = NULL;
if (node->name != NULL) if (node->name != NULL)
ret->name = xmlStrdup(node->name); ret->name = xmlStrdup(node->name);
@ -1469,6 +1533,7 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
} }
if (node->childs != NULL) if (node->childs != NULL)
ret->childs = xmlStaticCopyNodeList(node->childs, doc, ret); ret->childs = xmlStaticCopyNodeList(node->childs, doc, ret);
UPDATE_LAST_CHILD(ret);
return(ret); return(ret);
} }
@ -1601,11 +1666,8 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
ret->standalone = doc->standalone; ret->standalone = doc->standalone;
if (!recursive) return(ret); if (!recursive) return(ret);
if (doc->dtd != NULL) if (doc->intSubset != NULL)
ret->dtd = xmlCopyDtd(doc->dtd); ret->intSubset = xmlCopyDtd(doc->intSubset);
if (doc->entities != NULL)
ret->entities = (void *) xmlCopyEntitiesTable(
(xmlEntitiesTablePtr) doc->entities);
if (doc->oldNs != NULL) if (doc->oldNs != NULL)
ret->oldNs = xmlCopyNamespaceList(doc->oldNs); ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
if (doc->root != NULL) if (doc->root != NULL)
@ -1677,6 +1739,7 @@ xmlNodeSetContent(xmlNodePtr cur, const CHAR *content) {
} }
if (cur->childs != NULL) xmlFreeNode(cur->childs); if (cur->childs != NULL) xmlFreeNode(cur->childs);
cur->childs = xmlStringGetNodeList(cur->doc, content); cur->childs = xmlStringGetNodeList(cur->doc, content);
UPDATE_LAST_CHILD(cur);
break; break;
case XML_ATTRIBUTE_NODE: case XML_ATTRIBUTE_NODE:
break; break;
@ -1688,6 +1751,7 @@ xmlNodeSetContent(xmlNodePtr cur, const CHAR *content) {
case XML_COMMENT_NODE: case XML_COMMENT_NODE:
if (cur->content != NULL) free(cur->content); if (cur->content != NULL) free(cur->content);
if (cur->childs != NULL) xmlFreeNode(cur->childs); if (cur->childs != NULL) xmlFreeNode(cur->childs);
cur->last = cur->childs = NULL;
if (content != NULL) if (content != NULL)
cur->content = xmlStrdup(content); cur->content = xmlStrdup(content);
else else
@ -1723,6 +1787,7 @@ xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) {
} }
if (cur->childs != NULL) xmlFreeNode(cur->childs); if (cur->childs != NULL) xmlFreeNode(cur->childs);
cur->childs = xmlStringLenGetNodeList(cur->doc, content, len); cur->childs = xmlStringLenGetNodeList(cur->doc, content, len);
UPDATE_LAST_CHILD(cur);
break; break;
case XML_ATTRIBUTE_NODE: case XML_ATTRIBUTE_NODE:
break; break;
@ -1734,6 +1799,7 @@ xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) {
case XML_COMMENT_NODE: case XML_COMMENT_NODE:
if (cur->content != NULL) free(cur->content); if (cur->content != NULL) free(cur->content);
if (cur->childs != NULL) xmlFreeNode(cur->childs); if (cur->childs != NULL) xmlFreeNode(cur->childs);
cur->childs = cur->last = NULL;
if (content != NULL) if (content != NULL)
cur->content = xmlStrndup(content, len); cur->content = xmlStrndup(content, len);
else else
@ -1743,6 +1809,8 @@ xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) {
break; break;
case XML_NOTATION_NODE: case XML_NOTATION_NODE:
if (cur->content != NULL) free(cur->content); if (cur->content != NULL) free(cur->content);
if (cur->childs != NULL) xmlFreeNode(cur->childs);
cur->childs = cur->last = NULL;
if (content != NULL) if (content != NULL)
cur->content = xmlStrndup(content, len); cur->content = xmlStrndup(content, len);
else else
@ -1772,24 +1840,22 @@ xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len) {
xmlNodePtr last = NULL, new; xmlNodePtr last = NULL, new;
if (cur->childs != NULL) { if (cur->childs != NULL) {
last = cur->childs; last = cur->last;
while (last->next != NULL) last = last->next;
} else { } else {
if (cur->content != NULL) { if (cur->content != NULL) {
cur->childs = xmlStringGetNodeList(cur->doc, cur->content); cur->childs = xmlStringGetNodeList(cur->doc, cur->content);
UPDATE_LAST_CHILD(cur);
free(cur->content); free(cur->content);
cur->content = NULL; cur->content = NULL;
if (cur->childs != NULL) { last = cur->last;
last = cur->childs;
while (last->next != NULL) last = last->next;
}
} }
} }
new = xmlStringLenGetNodeList(cur->doc, content, len); new = xmlNewTextLen(content, len);
if (new != NULL) { if (new != NULL) {
xmlAddChild(cur, new); xmlAddChild(cur, new);
if ((last != NULL) && (last->next == new)) if ((last != NULL) && (last->next == new)) {
xmlTextMerge(last, new); xmlTextMerge(last, new);
}
} }
break; break;
} }
@ -1936,19 +2002,14 @@ xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const CHAR *href) {
* *
* Search and get the value of an attribute associated to a node * Search and get the value of an attribute associated to a node
* This does the entity substitution. * This does the entity substitution.
*
* return values: the attribute value or NULL if not found. * return values: the attribute value or NULL if not found.
*/ */
const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) { CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
xmlAttrPtr prop = node->properties; xmlAttrPtr prop = node->properties;
while (prop != NULL) { while (prop != NULL) {
if (!xmlStrcmp(prop->name, name)) { if (!xmlStrcmp(prop->name, name))
if (prop->val != NULL) return(xmlNodeListGetString(node->doc, prop->val, 1));
return(xmlNodeListGetString(node->doc, prop->val, 1));
else
return(xmlStrndup("", 1));
}
prop = prop->next; prop = prop->next;
} }
return(NULL); return(NULL);
@ -2188,10 +2249,10 @@ xmlNsListDump(xmlNsPtr cur) {
*/ */
static void static void
xmlDtdDump(xmlDocPtr doc) { xmlDtdDump(xmlDocPtr doc) {
xmlDtdPtr cur = doc->dtd; xmlDtdPtr cur = doc->intSubset;
if (cur == NULL) { if (cur == NULL) {
fprintf(stderr, "xmlDtdDump : DTD == NULL\n"); fprintf(stderr, "xmlDtdDump : no internal subset\n");
return; return;
} }
xmlBufferWriteChar("<!DOCTYPE "); xmlBufferWriteChar("<!DOCTYPE ");
@ -2207,15 +2268,13 @@ xmlDtdDump(xmlDocPtr doc) {
xmlBufferWriteCHAR(cur->SystemID); xmlBufferWriteCHAR(cur->SystemID);
xmlBufferWriteChar("\""); xmlBufferWriteChar("\"");
} }
if ((cur->entities == NULL) && (doc->entities == NULL)) { if (cur->entities == NULL) {
xmlBufferWriteChar(">\n"); xmlBufferWriteChar(">\n");
return; return;
} }
xmlBufferWriteChar(" [\n"); xmlBufferWriteChar(" [\n");
if (cur->entities != NULL) if (cur->entities != NULL)
xmlDumpEntitiesTable((xmlEntitiesTablePtr) cur->entities); xmlDumpEntitiesTable((xmlEntitiesTablePtr) cur->entities);
if (doc->entities != NULL)
xmlDumpEntitiesTable((xmlEntitiesTablePtr) doc->entities);
xmlBufferWriteChar("]"); xmlBufferWriteChar("]");
/* TODO !!! a lot more things to dump ... */ /* TODO !!! a lot more things to dump ... */
@ -2239,13 +2298,13 @@ xmlAttrDump(xmlDocPtr doc, xmlAttrPtr cur) {
} }
xmlBufferWriteChar(" "); xmlBufferWriteChar(" ");
xmlBufferWriteCHAR(cur->name); xmlBufferWriteCHAR(cur->name);
xmlBufferWriteChar("=\"");
value = xmlNodeListGetString(doc, cur->val, 0); value = xmlNodeListGetString(doc, cur->val, 0);
if (value) { if (value) {
xmlBufferWriteChar("=\"");
xmlBufferWriteCHAR(value); xmlBufferWriteCHAR(value);
xmlBufferWriteChar("\"");
free(value); free(value);
} }
xmlBufferWriteChar("\"");
} }
/** /**
@ -2401,7 +2460,7 @@ xmlDocContentDump(xmlDocPtr cur) {
break; break;
} }
xmlBufferWriteChar("?>\n"); xmlBufferWriteChar("?>\n");
if ((cur->dtd != NULL) || (cur->entities != NULL)) if (cur->intSubset != NULL)
xmlDtdDump(cur); xmlDtdDump(cur);
if (cur->root != NULL) { if (cur->root != NULL) {
/* global namespace definitions, the old way */ /* global namespace definitions, the old way */
@ -2425,7 +2484,9 @@ xmlDocContentDump(xmlDocPtr cur) {
void void
xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) { xmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) {
if (cur == NULL) { if (cur == NULL) {
fprintf(stderr, "xmlDocDump : document == NULL\n"); #ifdef DEBUG_TREE
fprintf(stderr, "xmlDocDumpMemory : document == NULL\n");
#endif
*mem = NULL; *mem = NULL;
*size = 0; *size = 0;
return; return;
@ -2501,7 +2562,9 @@ xmlSetCompressMode(int mode) {
void void
xmlDocDump(FILE *f, xmlDocPtr cur) { xmlDocDump(FILE *f, xmlDocPtr cur) {
if (cur == NULL) { if (cur == NULL) {
#ifdef DEBUG_TREE
fprintf(stderr, "xmlDocDump : document == NULL\n"); fprintf(stderr, "xmlDocDump : document == NULL\n");
#endif
return; return;
} }
buffer_index = 0; buffer_index = 0;

52
tree.h
View File

@ -4,7 +4,7 @@
* *
* See Copyright for the status of this software. * See Copyright for the status of this software.
* *
* $Id$ * Daniel.Veillard@w3.org
*/ */
#ifndef __XML_TREE_H__ #ifndef __XML_TREE_H__
@ -15,6 +15,8 @@
extern "C" { extern "C" {
#endif #endif
#include <stdio.h>
/* /*
* The different element types carried by an XML tree * The different element types carried by an XML tree
* *
@ -61,18 +63,51 @@ typedef unsigned char CHAR;
* TODO !!!! * TODO !!!!
*/ */
#define XML_ATTRIBUTE_NONE 1
#define XML_ATTRIBUTE_REQUIRED 2
#define XML_ATTRIBUTE_IMPLIED 3
#define XML_ATTRIBUTE_FIXED 4
#define XML_ATTRIBUTE_STRING 1
#define XML_ATTRIBUTE_ID 2
#define XML_ATTRIBUTE_IDREF 3
#define XML_ATTRIBUTE_IDREFS 4
#define XML_ATTRIBUTE_ENTITY 5
#define XML_ATTRIBUTE_ENTITIES 6
#define XML_ATTRIBUTE_NMTOKEN 7
#define XML_ATTRIBUTE_NMTOKENS 8
#define XML_ATTRIBUTE_ENUMERATED 9
/* /*
* a DTD Element definition. * a DTD Element definition.
*/ */
#define XML_ELEMENT_CONTENT_PCDATA 1
#define XML_ELEMENT_CONTENT_ELEMENT 2
#define XML_ELEMENT_CONTENT_SEQ 3
#define XML_ELEMENT_CONTENT_OR 4
#define XML_ELEMENT_CONTENT_ONCE 1
#define XML_ELEMENT_CONTENT_OPT 2
#define XML_ELEMENT_CONTENT_MULT 3
#define XML_ELEMENT_CONTENT_PLUS 4
typedef struct xmlElementContent {
int type; /* PCDATA, ELEMENT, SEQ or OR */
int ocur; /* ONCE, OPT, MULT or PLUS */
const CHAR *name; /* Element name */
struct xmlElementContent *c1; /* first child */
struct xmlElementContent *c2; /* second child */
} xmlElementContent, *xmlElementContentPtr;
#define XML_ELEMENT_TYPE_EMPTY 1 #define XML_ELEMENT_TYPE_EMPTY 1
#define XML_ELEMENT_TYPE_ANY 2 #define XML_ELEMENT_TYPE_ANY 2
#define XML_ELEMENT_TYPE_MIXED 3 #define XML_ELEMENT_TYPE_MIXED 3
#define XML_ELEMENT_TYPE_ELEMENT 4 #define XML_ELEMENT_TYPE_ELEMENT 4
typedef struct xmlElement { typedef struct xmlElement {
const CHAR *name; /* Element name */ const CHAR *name; /* Element name */
int type; /* type (too simple, to extend ...) */ int type; /* The type */
/* TODO !!! more needed */ xmlElementContentPtr content; /* the allowed element content */
} xmlElement, *xmlElementPtr; } xmlElement, *xmlElementPtr;
/* /*
@ -132,6 +167,7 @@ typedef struct xmlNode {
struct xmlNode *next; /* next sibling link */ struct xmlNode *next; /* next sibling link */
struct xmlNode *prev; /* previous sibling link */ struct xmlNode *prev; /* previous sibling link */
struct xmlNode *childs; /* parent->childs link */ struct xmlNode *childs; /* parent->childs link */
struct xmlNode *last; /* last child link */
struct xmlAttr *properties; /* properties list */ struct xmlAttr *properties; /* properties list */
const CHAR *name; /* the name of the node, or the entity */ const CHAR *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */ xmlNs *ns; /* pointer to the associated namespace */
@ -153,9 +189,9 @@ typedef struct xmlDoc {
const CHAR *encoding; /* encoding, if any */ const CHAR *encoding; /* encoding, if any */
int compression;/* level of zlib compression */ int compression;/* level of zlib compression */
int standalone; /* standalone document (no external refs) */ int standalone; /* standalone document (no external refs) */
struct xmlDtd *dtd; /* the document DTD if available */ struct xmlDtd *intSubset; /* the document internal subset */
struct xmlDtd *extSubset; /* the document external subset */
struct xmlNs *oldNs; /* Global namespace, the old way */ struct xmlNs *oldNs; /* Global namespace, the old way */
void *entities; /* Hash table for general entities if any */
struct xmlNode *root; /* the document tree */ struct xmlNode *root; /* the document tree */
} xmlDoc, *xmlDocPtr; } xmlDoc, *xmlDocPtr;
@ -169,6 +205,8 @@ extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
/* /*
* Creating/freeing new structures * Creating/freeing new structures
*/ */
extern xmlDtdPtr xmlCreateIntSubset(xmlDocPtr doc, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID);
extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name, extern xmlDtdPtr xmlNewDtd(xmlDocPtr doc, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID); const CHAR *ExternalID, const CHAR *SystemID);
extern void xmlFreeDtd(xmlDtdPtr cur); extern void xmlFreeDtd(xmlDtdPtr cur);
@ -240,7 +278,7 @@ extern xmlNsPtr xmlCopyNamespaceList(xmlNsPtr cur);
*/ */
extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name, extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
const CHAR *value); const CHAR *value);
extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name); extern CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value); extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value);
extern xmlNodePtr xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value, extern xmlNodePtr xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value,
int len); int len);

162
valid.c Normal file
View File

@ -0,0 +1,162 @@
/*
* 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "valid.h"
#include "parser.h"
/****************************************************************
* *
* 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.
*
* return values: NULL if not, othervise the new element content structure
*/
xmlElementContentPtr
xmlNewElementContent(CHAR *name, int type) {
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);
}
ret = (xmlElementContentPtr) malloc(sizeof(xmlElementContent));
if (ret == NULL) {
fprintf(stderr, "xmlNewElementContent : out of memory!\n");
return(NULL);
}
ret->type = type;
ret->ocur = XML_ELEMENT_CONTENT_ONCE;
ret->name = xmlStrdup(name);
return(ret);
}
/**
* xmlNewElementContent:
* @name: the subelement name or NULL
* @type: the type of element content decl
*
* Free an element content structure. This is a recursive call !
*/
void
xmlFreeElementContent(xmlElementContentPtr cur) {
/* TODO !!! */
}
/****************************************************************
* *
* Registration of DTD declarations *
* *
****************************************************************/
/**
* xmlAddElementDecl:
* @name: the entity name
*
* Register a new element declaration
*
* return values: NULL if not, othervise the entity
*/
xmlElementPtr
xmlAddElementDecl(xmlDtdPtr dtd, char *name, int type,
xmlElementContentPtr content) {
xmlElementPtr ret;
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);
}
/*
* Validity Check:
* Search the DTD for previous declarations of the ELEMENT
*/
/* TODO */
/*
* Create and fill the structure.
*/
ret = (xmlElementPtr) malloc(sizeof(xmlElement));
if (ret == NULL) {
fprintf(stderr, "xmlAddElementDecl: out of memory\n");
return(NULL);
}
ret->type = type;
ret->name = xmlStrdup(name);
ret->content = content;
/*
* Insert the structure in the DTD Element table
*/
/* TODO */
return(ret);
}

18
valid.h Normal file
View File

@ -0,0 +1,18 @@
/*
* valid.h : interface to the DTD handling and the validity checking
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@w3.org
*/
#ifndef __XML_VALID_H__
#define __XML_VALID_H__
#include "tree.h"
extern xmlElementPtr xmlAddElementDecl(xmlDtdPtr dtd, char *name, int type,
xmlElementContentPtr content);
extern xmlElementContentPtr xmlNewElementContent(CHAR *name, int type);
extern void xmlFreeElementContent(xmlElementContentPtr cur);
#endif /* __XML_VALID_H__ */