1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-02-04 01:47:02 +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>
* test/* : updated the examples, most of them were not well

View File

@ -16,7 +16,8 @@ libxml_la_SOURCES = \
error.h \
parser.c \
debugXML.c \
tree.c
tree.c \
valid.c
xmlincdir = $(includedir)/gnome-xml
xmlinc_HEADERS = \
@ -24,7 +25,8 @@ xmlinc_HEADERS = \
encoding.h \
parser.h \
debugXML.h \
tree.h
tree.h \
valid.h
DEPS = $(top_builddir)/libxml.la
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.
*
* See Copyright for the status of this software.
*
* 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
* produced by the XML parser.
*
* See Copyright for the status of this software.
*
* Daniel Veillard <Daniel.Veillard@w3.org>
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
*
* See Copyright for the status of this software.
*
* $Id$
* Daniel.Veillard@w3.org
*/
#ifndef __XML_PARSER_H__
@ -46,6 +46,7 @@ typedef struct xmlParserNodeInfoSeq {
typedef struct xmlParserCtxt {
struct xmlSAXHandler *sax; /* The SAX handler */
xmlDocPtr doc; /* the document being built */
int wellFormed; /* is the document well formed */
/* Input stream stack */
xmlParserInputPtr input; /* Current input stream */
@ -131,15 +132,8 @@ extern xmlSAXHandler xmlDefaultSAXHandler;
#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 *xmlStrndup(const CHAR *input, int n);
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 *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 xmlClearParserCtxt(xmlParserCtxtPtr ctx);
extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,

View File

@ -4,7 +4,7 @@
*
* See Copyright for the status of this software.
*
* $Id$
* Daniel.Veillard@w3.org
*/
#ifndef __XML_TREE_H__
@ -15,6 +15,8 @@
extern "C" {
#endif
#include <stdio.h>
/*
* The different element types carried by an XML tree
*
@ -61,18 +63,51 @@ typedef unsigned char CHAR;
* 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.
*/
#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_ANY 2
#define XML_ELEMENT_TYPE_MIXED 3
#define XML_ELEMENT_TYPE_ELEMENT 4
typedef struct xmlElement {
const CHAR *name; /* Element name */
int type; /* type (too simple, to extend ...) */
/* TODO !!! more needed */
const CHAR *name; /* Element name */
int type; /* The type */
xmlElementContentPtr content; /* the allowed element content */
} xmlElement, *xmlElementPtr;
/*
@ -132,6 +167,7 @@ typedef struct xmlNode {
struct xmlNode *next; /* next sibling link */
struct xmlNode *prev; /* previous sibling link */
struct xmlNode *childs; /* parent->childs link */
struct xmlNode *last; /* last child link */
struct xmlAttr *properties; /* properties list */
const CHAR *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */
@ -153,9 +189,9 @@ typedef struct xmlDoc {
const CHAR *encoding; /* encoding, if any */
int compression;/* level of zlib compression */
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 */
void *entities; /* Hash table for general entities if any */
struct xmlNode *root; /* the document tree */
} xmlDoc, *xmlDocPtr;
@ -169,6 +205,8 @@ extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
/*
* 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,
const CHAR *ExternalID, const CHAR *SystemID);
extern void xmlFreeDtd(xmlDtdPtr cur);
@ -240,7 +278,7 @@ extern xmlNsPtr xmlCopyNamespaceList(xmlNsPtr cur);
*/
extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
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 xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value,
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.
*
* $Id$
* Daniel.Veillard@w3.org
*/
#ifndef __XML_PARSER_H__
@ -46,6 +46,7 @@ typedef struct xmlParserNodeInfoSeq {
typedef struct xmlParserCtxt {
struct xmlSAXHandler *sax; /* The SAX handler */
xmlDocPtr doc; /* the document being built */
int wellFormed; /* is the document well formed */
/* Input stream stack */
xmlParserInputPtr input; /* Current input stream */
@ -131,15 +132,8 @@ extern xmlSAXHandler xmlDefaultSAXHandler;
#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 *xmlStrndup(const CHAR *input, int n);
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 *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 xmlClearParserCtxt(xmlParserCtxtPtr ctx);
extern void xmlSetupParserForBuffer(xmlParserCtxtPtr ctx, const CHAR* buffer,

View File

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

179
tree.c
View File

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

52
tree.h
View File

@ -4,7 +4,7 @@
*
* See Copyright for the status of this software.
*
* $Id$
* Daniel.Veillard@w3.org
*/
#ifndef __XML_TREE_H__
@ -15,6 +15,8 @@
extern "C" {
#endif
#include <stdio.h>
/*
* The different element types carried by an XML tree
*
@ -61,18 +63,51 @@ typedef unsigned char CHAR;
* 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.
*/
#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_ANY 2
#define XML_ELEMENT_TYPE_MIXED 3
#define XML_ELEMENT_TYPE_ELEMENT 4
typedef struct xmlElement {
const CHAR *name; /* Element name */
int type; /* type (too simple, to extend ...) */
/* TODO !!! more needed */
const CHAR *name; /* Element name */
int type; /* The type */
xmlElementContentPtr content; /* the allowed element content */
} xmlElement, *xmlElementPtr;
/*
@ -132,6 +167,7 @@ typedef struct xmlNode {
struct xmlNode *next; /* next sibling link */
struct xmlNode *prev; /* previous sibling link */
struct xmlNode *childs; /* parent->childs link */
struct xmlNode *last; /* last child link */
struct xmlAttr *properties; /* properties list */
const CHAR *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */
@ -153,9 +189,9 @@ typedef struct xmlDoc {
const CHAR *encoding; /* encoding, if any */
int compression;/* level of zlib compression */
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 */
void *entities; /* Hash table for general entities if any */
struct xmlNode *root; /* the document tree */
} xmlDoc, *xmlDocPtr;
@ -169,6 +205,8 @@ extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
/*
* 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,
const CHAR *ExternalID, const CHAR *SystemID);
extern void xmlFreeDtd(xmlDtdPtr cur);
@ -240,7 +278,7 @@ extern xmlNsPtr xmlCopyNamespaceList(xmlNsPtr cur);
*/
extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
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 xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value,
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__ */