summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>1999-04-05 12:20:10 +0000
committerDaniel Veillard <veillard@src.gnome.org>1999-04-05 12:20:10 +0000
commit517752b9859719c25e3eff6f5397de9dcd3bfd69 (patch)
tree8f4e26c579dbeb45705ec8c738786cc7f413092d
parent87c83bd3346b5ee5a740072c4c201faf2ade2472 (diff)
downloadlibxml2-517752b9859719c25e3eff6f5397de9dcd3bfd69.tar.gz
Completed/revamped the SAX support, removed old namespace suppport, Daniel
-rw-r--r--ChangeLog10
-rw-r--r--SAX.c527
-rw-r--r--entities.h4
-rw-r--r--include/libxml/entities.h4
-rw-r--r--include/libxml/parser.h43
-rw-r--r--include/libxml/parserInternals.h21
-rw-r--r--include/libxml/tree.h4
-rw-r--r--include/libxml/valid.h12
-rw-r--r--parser.c602
-rw-r--r--parser.h43
-rw-r--r--parserInternals.h21
-rw-r--r--tree.c4
-rw-r--r--tree.h4
-rw-r--r--valid.c10
-rw-r--r--valid.h12
15 files changed, 925 insertions, 396 deletions
diff --git a/ChangeLog b/ChangeLog
index 19b8c692..de4e14b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Mon Apr 5 14:14:40 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
+
+ * parser.[ch] tree.[ch] SAX.c, parserInternals.h valid.[ch]:
+ large revamping of the parser to use SAX callbacks
+ http://www.megginson.com/SAX/ (or at least a C like interface
+ a la Expat). It's now possible to set up your own callbacks
+ and the parser will not build a DOM tree.
+ * test/* result/*: updated the test suite, I finally removed
+ the old Namespace draft support (PI based).
+
Fri Apr 2 17:57:32 CEST 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* Makefile.am: added test result to EXTRA_DIST for make tests
diff --git a/SAX.c b/SAX.c
index b4a6cb16..7f9ea18a 100644
--- a/SAX.c
+++ b/SAX.c
@@ -10,6 +10,8 @@
#include <stdlib.h>
#include "tree.h"
#include "parser.h"
+#include "parserInternals.h"
+#include "valid.h"
#include "entities.h"
#include "xml-error.h"
@@ -81,6 +83,65 @@ xmlSAXLocator xmlDefaultSAXLocator = {
};
/**
+ * isStandalone:
+ * @ctxt: An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+int
+isStandalone(xmlParserCtxtPtr ctxt)
+{
+ return(ctxt->myDoc->standalone == 1);
+}
+
+/**
+ * hasInternalSubset:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+int
+hasInternalSubset(xmlParserCtxtPtr ctxt)
+{
+ return(ctxt->myDoc->intSubset != NULL);
+}
+
+/**
+ * hasExternalSubset:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+int
+hasExternalSubset(xmlParserCtxtPtr ctxt)
+{
+ return(ctxt->myDoc->extSubset != NULL);
+}
+
+/**
+ * hasInternalSubset:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+void
+internalSubset(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *ExternalID, const CHAR *SystemID)
+{
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
+ name, ExternalID, SystemID);
+#endif
+ xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
+}
+
+/**
* resolveEntity:
* @ctxt: An XML parser context
* @publicId: The public ID of the entity
@@ -102,10 +163,107 @@ resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId)
fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
#endif
+ /*
+ * TODO : not 100% sure that the appropriate handling in that case.
+ */
return(NULL);
}
/**
+ * getEntity:
+ * @ctxt: An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+xmlEntityPtr
+getEntity(xmlParserCtxtPtr ctxt, const CHAR *name)
+{
+ xmlEntityPtr ret;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.getEntity(%s)\n", name);
+#endif
+
+ ret = xmlGetDocEntity(ctxt->myDoc, name);
+ return(ret);
+}
+
+
+/**
+ * entityDecl:
+ * @ctxt: An XML parser context
+ * @name: the entity name
+ * @type: the entity type
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @content: the entity value (without processing).
+ *
+ * An entity definition has been parsed
+ */
+void
+entityDecl(xmlParserCtxtPtr ctxt, const CHAR *name, int type,
+ const CHAR *publicId, const CHAR *systemId, CHAR *content)
+{
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
+ name, type, publicId, systemId, content);
+#endif
+ xmlAddDocEntity(ctxt->myDoc, name, type, publicId, systemId, content);
+}
+
+/**
+ * attributeDecl:
+ * @ctxt: An XML parser context
+ * @name: the attribute name
+ * @type: the attribute type
+ * @publicId: The public ID of the attribute
+ * @systemId: The system ID of the attribute
+ * @content: the attribute value (without processing).
+ *
+ * An attribute definition has been parsed
+ */
+void
+attributeDecl(xmlParserCtxtPtr ctxt, const CHAR *elem, const CHAR *name,
+ int type, int def, const CHAR *defaultValue,
+ xmlEnumerationPtr tree)
+{
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
+ elem, name, type, def, defaultValue);
+#endif
+ xmlAddAttributeDecl(ctxt->myDoc->intSubset, elem, name, type, def,
+ defaultValue, tree);
+}
+
+/**
+ * elementDecl:
+ * @ctxt: An XML parser context
+ * @name: the element name
+ * @type: the element type
+ * @publicId: The public ID of the element
+ * @systemId: The system ID of the element
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+void
+elementDecl(xmlParserCtxtPtr ctxt, const CHAR *name, int type,
+ xmlElementContentPtr content)
+{
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
+ name, type);
+#endif
+ xmlAddElementDecl(ctxt->myDoc->intSubset, name, type, content);
+}
+
+/**
* notationDecl:
* @ctxt: An XML parser context
* @name: The name of the notation
@@ -122,6 +280,7 @@ notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
#endif
+ xmlAddNotationDecl(ctxt->myDoc->intSubset, name, publicId, systemId);
}
/**
@@ -171,9 +330,19 @@ setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc)
void
startDocument(xmlParserCtxtPtr ctxt)
{
+ xmlDocPtr doc;
+
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.startDocument()\n");
#endif
+ doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
+ if (doc != NULL) {
+ if (ctxt->encoding != NULL)
+ doc->encoding = xmlStrdup(ctxt->encoding);
+ else
+ doc->encoding = NULL;
+ doc->standalone = ctxt->standalone;
+ }
}
/**
@@ -191,19 +360,151 @@ endDocument(xmlParserCtxtPtr ctxt)
}
/**
+ * attribute:
+ * @ctxt: An XML parser context
+ * @name: The attribute name
+ * @value: The attribute value
+ *
+ * Handle an attribute that has been read by the parser.
+ * The default handling is to convert the attribute into an
+ * DOM subtree and past it in a new xmlAttr element added to
+ * the element.
+ */
+void
+attribute(xmlParserCtxtPtr ctxt, const CHAR *fullname, const CHAR *value)
+{
+ xmlAttrPtr ret;
+ CHAR *name;
+ CHAR *ns;
+
+/****************
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.attribute(%s, %s)\n", fullname, value);
+#endif
+ ****************/
+ /*
+ * Split the full name into a namespace prefix and the tag name
+ */
+ name = xmlSplitQName(fullname, &ns);
+
+ /*
+ * Check whether it's a namespace definition
+ */
+ if ((ns == NULL) &&
+ (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
+ (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
+ /* a default namespace definition */
+ xmlNewNs(ctxt->node, value, NULL);
+ if (name != NULL)
+ free(name);
+ return;
+ }
+ if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
+ (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
+ /* a standard namespace definition */
+ xmlNewNs(ctxt->node, value, name);
+ free(ns);
+ if (name != NULL)
+ free(name);
+ return;
+ }
+
+ ret = xmlNewProp(ctxt->node, name, NULL);
+ if (ret != NULL)
+ ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
+ if (name != NULL)
+ free(name);
+ if (ns != NULL)
+ free(ns);
+}
+
+/**
* startElement:
* @ctxt: An XML parser context
* @name: The element name
+ * @atts: An array of name/value attributes pairs, NULL terminated
*
* called when an opening tag has been processed.
* TODO We currently have a small pblm with the arguments ...
*/
void
-startElement(xmlParserCtxtPtr ctxt, const CHAR *name)
+startElement(xmlParserCtxtPtr ctxt, const CHAR *fullname, const CHAR **atts)
{
+ xmlNodePtr ret;
+ xmlNodePtr parent = ctxt->node;
+ xmlNsPtr ns;
+ CHAR *name;
+ CHAR *prefix;
+ const CHAR *att;
+ const CHAR *value;
+
+ int i;
+
#ifdef DEBUG_SAX
- fprintf(stderr, "SAX.startElement(%s)\n", name);
+ fprintf(stderr, "SAX.startElement(%s)\n", fullname);
#endif
+ /*
+ * Split the full name into a namespace prefix and the tag name
+ */
+ name = xmlSplitQName(fullname, &prefix);
+
+
+ /*
+ * Note : the namespace resolution is deferred until the end of the
+ * attributes parsing, since local namespace can be defined as
+ * an attribute at this level.
+ */
+ ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
+ if (ret == NULL) return;
+ if (ctxt->myDoc->root == NULL)
+ ctxt->myDoc->root = ret;
+
+ /*
+ * We are parsing a new node.
+ */
+ nodePush(ctxt, ret);
+
+ /*
+ * Link the child element
+ */
+ if (parent != NULL)
+ xmlAddChild(parent, ctxt->node);
+
+ /*
+ * process all the attributes.
+ */
+ if (atts != NULL) {
+ i = 0;
+ att = atts[i++];
+ value = atts[i++];
+ while ((att != NULL) && (value != NULL)) {
+ /*
+ * Handle one pair of attribute/value
+ */
+ attribute(ctxt, att, value);
+
+ /*
+ * Next ones
+ */
+ att = atts[i++];
+ value = atts[i++];
+ }
+ }
+
+ /*
+ * Search the namespace, note that since the attributes have been
+ * processed, the local namespaces are available.
+ */
+ ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
+ if ((ns == NULL) && (parent != NULL))
+ ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
+ xmlSetNs(ret, ns);
+
+ if (prefix != NULL)
+ free(prefix);
+ if (name != NULL)
+ free(name);
+
}
/**
@@ -216,47 +517,65 @@ startElement(xmlParserCtxtPtr ctxt, const CHAR *name)
void
endElement(xmlParserCtxtPtr ctxt, const CHAR *name)
{
+ xmlParserNodeInfo node_info;
+ xmlNodePtr cur = ctxt->node;
+
#ifdef DEBUG_SAX
- fprintf(stderr, "SAX.endElement(%s)\n", name);
+ if (name == NULL)
+ fprintf(stderr, "SAX.endElement(NULL)\n");
+ else
+ fprintf(stderr, "SAX.endElement(%s)\n", name);
#endif
+
+ /* Capture end position and add node */
+ if (cur != NULL && ctxt->record_info) {
+ node_info.end_pos = ctxt->input->cur - ctxt->input->base;
+ node_info.end_line = ctxt->input->line;
+ node_info.node = cur;
+ xmlParserAddNodeInfo(ctxt, &node_info);
+ }
+
+ /*
+ * end of parsing of this node.
+ */
+ nodePop(ctxt);
}
/**
- * attribute:
+ * reference:
* @ctxt: An XML parser context
- * @name: The attribute name
- * @value: The attribute value
+ * @name: The entity name
*
- * called when an attribute has been read by the parser.
- * The default handling is to convert the attribute into an
- * DOM subtree and past it in a new xmlAttr element added to
- * the element.
+ * called when an entity reference is detected.
*/
void
-attribute(xmlParserCtxtPtr ctxt, const CHAR *name, const CHAR *value)
+reference(xmlParserCtxtPtr ctxt, const CHAR *name)
{
+ xmlNodePtr ret;
+
#ifdef DEBUG_SAX
- fprintf(stderr, "SAX.attribute(%s, %s)\n", name, value);
+ fprintf(stderr, "SAX.reference(%s)\n", name);
#endif
+ ret = xmlNewReference(ctxt->myDoc, name);
+ xmlAddChild(ctxt->node, ret);
}
/**
* characters:
* @ctxt: An XML parser context
* @ch: a CHAR string
- * @start: the first char in the string
* @len: the number of CHAR
*
* receiving some chars from the parser.
* Question: how much at a time ???
*/
void
-characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
+characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int len)
{
xmlNodePtr lastChild;
#ifdef DEBUG_SAX
- fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
+ fprintf(stderr, "SAX.characters(%.30s, %d)\n", ch, len);
#endif
/*
* Handle the data if any. If there is no child
@@ -266,12 +585,12 @@ characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
lastChild = xmlGetLastChild(ctxt->node);
if (lastChild == NULL)
- xmlNodeAddContentLen(ctxt->node, &ch[start], len);
+ xmlNodeAddContentLen(ctxt->node, ch, len);
else {
if (xmlNodeIsText(lastChild))
- xmlTextConcat(lastChild, &ch[start], len);
+ xmlTextConcat(lastChild, ch, len);
else {
- lastChild = xmlNewTextLen(&ch[start], len);
+ lastChild = xmlNewTextLen(ch, len);
xmlAddChild(ctxt->node, lastChild);
}
}
@@ -281,17 +600,16 @@ characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
* ignorableWhitespace:
* @ctxt: An XML parser context
* @ch: a CHAR string
- * @start: the first char in the string
* @len: the number of CHAR
*
* receiving some ignorable whitespaces from the parser.
* Question: how much at a time ???
*/
void
-ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len)
+ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, int len)
{
#ifdef DEBUG_SAX
- fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
+ fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
#endif
}
@@ -313,19 +631,173 @@ processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
#endif
}
+/**
+ * globalNamespace:
+ * @ctxt: An XML parser context
+ * @href: the namespace associated URN
+ * @prefix: the namespace prefix
+ *
+ * An old global namespace has been parsed.
+ */
+void
+globalNamespace(xmlParserCtxtPtr ctxt, const CHAR *href, const CHAR *prefix)
+{
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.globalNamespace(%s, %s)\n", href, prefix);
+#endif
+ xmlNewGlobalNs(ctxt->myDoc, href, prefix);
+}
+
+/**
+ * setNamespace:
+ * @ctxt: An XML parser context
+ * @name: the namespace prefix
+ *
+ * Set the current element namespace.
+ */
+void
+setNamespace(xmlParserCtxtPtr ctxt, const CHAR *name)
+{
+ xmlNsPtr ns;
+ xmlNodePtr parent;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.setNamespace(%s)\n", name);
+#endif
+ ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
+ if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
+ if (ctxt->nodeNr >= 2) {
+ parent = ctxt->nodeTab[ctxt->nodeNr - 2];
+ if (parent != NULL)
+ ns = xmlSearchNs(ctxt->myDoc, parent, name);
+ }
+ }
+ xmlSetNs(ctxt->node, ns);
+}
+
+/**
+ * getNamespace:
+ * @ctxt: An XML parser context
+ *
+ * Get the current element namespace.
+ */
+xmlNsPtr
+getNamespace(xmlParserCtxtPtr ctxt)
+{
+ xmlNsPtr ret;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.getNamespace()\n");
+#endif
+ ret = ctxt->node->ns;
+ return(ret);
+}
+
+/**
+ * checkNamespace:
+ * @ctxt: An XML parser context
+ * @namespace: the namespace to check against
+ *
+ * Check that the current element namespace is the same as the
+ * one read upon parsing.
+ */
+int
+checkNamespace(xmlParserCtxtPtr ctxt, CHAR *namespace)
+{
+ xmlNodePtr cur = ctxt->node;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.checkNamespace(%s)\n", namespace);
+#endif
+
+ /*
+ * Check that the Name in the ETag is the same as in the STag.
+ */
+ if (namespace == NULL) {
+ if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt,
+ "End tags for %s don't hold the namespace %s\n",
+ cur->name, cur->ns->prefix);
+ ctxt->wellFormed = 0;
+ }
+ } else {
+ if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt,
+ "End tags %s holds a prefix %s not used by the open tag\n",
+ cur->name, namespace);
+ ctxt->wellFormed = 0;
+ } else if (strcmp(namespace, cur->ns->prefix)) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt,
+ "Start and End tags for %s don't use the same namespaces: %s and %s\n",
+ cur->name, cur->ns->prefix, namespace);
+ ctxt->wellFormed = 0;
+ } else
+ return(1);
+ }
+ return(0);
+}
+
+/**
+ * namespaceDecl:
+ * @ctxt: An XML parser context
+ * @href: the namespace associated URN
+ * @prefix: the namespace prefix
+ *
+ * A namespace has been parsed.
+ */
+void
+namespaceDecl(xmlParserCtxtPtr ctxt, const CHAR *href, const CHAR *prefix)
+{
+#ifdef DEBUG_SAX
+ if (prefix == NULL)
+ fprintf(stderr, "SAX.namespaceDecl(%s, NULL)\n", href);
+ else
+ fprintf(stderr, "SAX.namespaceDecl(%s, %s)\n", href, prefix);
+#endif
+ xmlNewNs(ctxt->node, href, prefix);
+}
+
+/**
+ * comment:
+ * @ctxt: An XML parser context
+ * @value: the comment content
+ *
+ * A comment has been parsed.
+ */
+void
+comment(xmlParserCtxtPtr ctxt, const CHAR *value)
+{
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.comment(%s)\n", value);
+#endif
+ xmlNewDocComment(ctxt->myDoc, value);
+}
+
xmlSAXHandler xmlDefaultSAXHandler = {
+ internalSubset,
+ isStandalone,
+ hasInternalSubset,
+ hasExternalSubset,
resolveEntity,
+ getEntity,
+ entityDecl,
notationDecl,
+ attributeDecl,
+ elementDecl,
unparsedEntityDecl,
setDocumentLocator,
startDocument,
endDocument,
startElement,
endElement,
- attribute,
+ reference,
characters,
ignorableWhitespace,
processingInstruction,
+ comment,
xmlParserWarning,
xmlParserError,
xmlParserError,
@@ -339,7 +811,15 @@ xmlSAXHandler xmlDefaultSAXHandler = {
void
xmlDefaultSAXHandlerInit(void)
{
+ xmlDefaultSAXHandler.internalSubset = internalSubset;
+ xmlDefaultSAXHandler.isStandalone = isStandalone;
+ xmlDefaultSAXHandler.hasInternalSubset = hasInternalSubset;
+ xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
xmlDefaultSAXHandler.resolveEntity = resolveEntity;
+ xmlDefaultSAXHandler.getEntity = getEntity;
+ xmlDefaultSAXHandler.entityDecl = entityDecl;
+ xmlDefaultSAXHandler.attributeDecl = attributeDecl;
+ xmlDefaultSAXHandler.elementDecl = elementDecl;
xmlDefaultSAXHandler.notationDecl = notationDecl;
xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
@@ -347,10 +827,11 @@ xmlDefaultSAXHandlerInit(void)
xmlDefaultSAXHandler.endDocument = endDocument;
xmlDefaultSAXHandler.startElement = startElement;
xmlDefaultSAXHandler.endElement = endElement;
- xmlDefaultSAXHandler.attribute = attribute;
+ xmlDefaultSAXHandler.reference = reference;
xmlDefaultSAXHandler.characters = characters;
xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
xmlDefaultSAXHandler.processingInstruction = processingInstruction;
+ xmlDefaultSAXHandler.comment = comment;
xmlDefaultSAXHandler.warning = xmlParserWarning;
xmlDefaultSAXHandler.error = xmlParserError;
xmlDefaultSAXHandler.fatalError = xmlParserError;
diff --git a/entities.h b/entities.h
index 99ce163c..89770547 100644
--- a/entities.h
+++ b/entities.h
@@ -9,7 +9,7 @@
#ifndef __XML_ENTITIES_H__
#define __XML_ENTITIES_H__
-#include "parser.h"
+#include "tree.h"
#ifdef __cplusplus
extern "C" {
@@ -56,6 +56,8 @@ typedef xmlEntitiesTable *xmlEntitiesTablePtr;
* External functions :
*/
+#include "parser.h"
+
void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index 99ce163c..89770547 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -9,7 +9,7 @@
#ifndef __XML_ENTITIES_H__
#define __XML_ENTITIES_H__
-#include "parser.h"
+#include "tree.h"
#ifdef __cplusplus
extern "C" {
@@ -56,6 +56,8 @@ typedef xmlEntitiesTable *xmlEntitiesTablePtr;
* External functions :
*/
+#include "parser.h"
+
void xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 3dc84453..3e433a26 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -51,8 +51,12 @@ typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
typedef struct _xmlParserCtxt {
struct xmlSAXHandler *sax; /* The SAX handler */
- xmlDocPtr doc; /* the document being built */
+ void *userData; /* the document being built */
+ xmlDocPtr myDoc; /* the document being built */
int wellFormed; /* is the document well formed */
+ const CHAR *version; /* the XML version string */
+ const CHAR *encoding; /* encoding, if any */
+ int standalone; /* standalone document */
/* Input stream stack */
xmlParserInputPtr input; /* Current input stream */
@@ -89,10 +93,24 @@ typedef xmlSAXLocator *xmlSAXLocatorPtr;
* a SAX Exception.
*/
+#include "entities.h"
+
typedef xmlParserInputPtr (*resolveEntitySAXFunc) (xmlParserCtxtPtr ctxt,
const CHAR *publicId, const CHAR *systemId);
+typedef void (*internalSubsetSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *ExternalID, const CHAR *SystemID);
+typedef xmlEntityPtr (*getEntitySAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *name);
+typedef void (*entityDeclSAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *name, int type, const CHAR *publicId,
+ const CHAR *systemId, CHAR *content);
typedef void (*notationDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
const CHAR *publicId, const CHAR *systemId);
+typedef void (*attributeDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *elem,
+ const CHAR *name, int type, int def,
+ const CHAR *defaultValue, xmlEnumerationPtr tree);
+typedef void (*elementDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
+ int type, xmlElementContentPtr content);
typedef void (*unparsedEntityDeclSAXFunc)(xmlParserCtxtPtr ctxt,
const CHAR *name, const CHAR *publicId,
const CHAR *systemId, const CHAR *notationName);
@@ -100,33 +118,48 @@ typedef void (*setDocumentLocatorSAXFunc) (xmlParserCtxtPtr ctxt,
xmlSAXLocatorPtr loc);
typedef void (*startDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
typedef void (*endDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
-typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR **atts);
typedef void (*endElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
typedef void (*attributeSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name,
const CHAR *value);
+typedef void (*referenceSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
typedef void (*charactersSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *ch,
- int start, int len);
+ int len);
typedef void (*ignorableWhitespaceSAXFunc) (xmlParserCtxtPtr ctxt,
- const CHAR *ch, int start, int len);
+ const CHAR *ch, int len);
typedef void (*processingInstructionSAXFunc) (xmlParserCtxtPtr ctxt,
const CHAR *target, const CHAR *data);
+typedef void (*commentSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *value);
typedef void (*warningSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
typedef void (*errorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
typedef void (*fatalErrorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef int (*isStandaloneSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef int (*hasInternalSubsetSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef int (*hasExternalSubsetSAXFunc) (xmlParserCtxtPtr ctxt);
typedef struct xmlSAXHandler {
+ internalSubsetSAXFunc internalSubset;
+ isStandaloneSAXFunc isStandalone;
+ hasInternalSubsetSAXFunc hasInternalSubset;
+ hasExternalSubsetSAXFunc hasExternalSubset;
resolveEntitySAXFunc resolveEntity;
+ getEntitySAXFunc getEntity;
+ entityDeclSAXFunc entityDecl;
notationDeclSAXFunc notationDecl;
+ attributeDeclSAXFunc attributeDecl;
+ elementDeclSAXFunc elementDecl;
unparsedEntityDeclSAXFunc unparsedEntityDecl;
setDocumentLocatorSAXFunc setDocumentLocator;
startDocumentSAXFunc startDocument;
endDocumentSAXFunc endDocument;
startElementSAXFunc startElement;
endElementSAXFunc endElement;
- attributeSAXFunc attribute;
+ referenceSAXFunc reference;
charactersSAXFunc characters;
ignorableWhitespaceSAXFunc ignorableWhitespace;
processingInstructionSAXFunc processingInstruction;
+ commentSAXFunc comment;
warningSAXFunc warning;
errorSAXFunc error;
fatalErrorSAXFunc fatalError;
diff --git a/include/libxml/parserInternals.h b/include/libxml/parserInternals.h
index 28ef54d1..75e9e130 100644
--- a/include/libxml/parserInternals.h
+++ b/include/libxml/parserInternals.h
@@ -529,6 +529,8 @@ xmlFreeInputStream(xmlParserInputPtr input);
* Namespaces.
*/
CHAR *
+xmlSplitQName(const CHAR *name, CHAR **prefix);
+CHAR *
xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt);
CHAR *
xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, CHAR **prefix);
@@ -558,7 +560,7 @@ void
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata);
CHAR *
xmlParseExternalID(xmlParserCtxtPtr ctxt, CHAR **publicID, int strict);
-xmlNodePtr
+void
xmlParseComment(xmlParserCtxtPtr ctxt, int create);
CHAR *
xmlParsePITarget(xmlParserCtxtPtr ctxt);
@@ -601,17 +603,17 @@ CHAR *
xmlParsePEReference(xmlParserCtxtPtr ctxt);
void
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt);
-xmlAttrPtr
-xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node);
-xmlNodePtr
+CHAR *
+xmlParseAttribute(xmlParserCtxtPtr ctxt, CHAR **value);
+void
xmlParseStartTag(xmlParserCtxtPtr ctxt);
void
-xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr);
+xmlParseEndTag(xmlParserCtxtPtr ctxt);
void
xmlParseCDSect(xmlParserCtxtPtr ctxt);
void
xmlParseContent(xmlParserCtxtPtr ctxt);
-xmlNodePtr
+void
xmlParseElement(xmlParserCtxtPtr ctxt);
CHAR *
xmlParseVersionNum(xmlParserCtxtPtr ctxt);
@@ -628,5 +630,12 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt);
void
xmlParseMisc(xmlParserCtxtPtr ctxt);
+/*
+ * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP
+ */
+extern int nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value);
+extern xmlNodePtr nodePop(xmlParserCtxtPtr ctxt);
+extern int inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value);
+extern xmlParserInputPtr inputPop(xmlParserCtxtPtr ctxt);
#endif /* __XML_PARSER_INTERNALS_H__ */
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 4443836b..3f00aa09 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -283,8 +283,8 @@ xmlNodePtr xmlNewDocText(xmlDocPtr doc, const CHAR *content);
xmlNodePtr xmlNewText(const CHAR *content);
xmlNodePtr xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len);
xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
-xmlNodePtr xmlNewDocComment(xmlDocPtr doc, CHAR *content);
-xmlNodePtr xmlNewComment(CHAR *content);
+xmlNodePtr xmlNewDocComment(xmlDocPtr doc, const CHAR *content);
+xmlNodePtr xmlNewComment(const CHAR *content);
xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name);
xmlNodePtr xmlCopyNode(xmlNodePtr node, int recursive);
xmlNodePtr xmlCopyNodeList(xmlNodePtr node);
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
index 14a72285..22c824ab 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -54,8 +54,8 @@ typedef struct xmlAttributeTable {
typedef xmlAttributeTable *xmlAttributeTablePtr;
/* Notation */
-xmlNotationPtr xmlAddNotationDecl(xmlDtdPtr dtd, CHAR *name,
- CHAR *PublicID, CHAR *SystemID);
+xmlNotationPtr xmlAddNotationDecl(xmlDtdPtr dtd, const CHAR *name,
+ const CHAR *PublicID, const CHAR *SystemID);
xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table);
void xmlFreeNotationTable(xmlNotationTablePtr table);
void xmlDumpNotationTable(xmlNotationTablePtr table);
@@ -66,7 +66,7 @@ xmlElementContentPtr xmlCopyElementContent(xmlElementContentPtr content);
void xmlFreeElementContent(xmlElementContentPtr cur);
/* Element */
-xmlElementPtr xmlAddElementDecl(xmlDtdPtr dtd, CHAR *name, int type,
+xmlElementPtr xmlAddElementDecl(xmlDtdPtr dtd, const CHAR *name, int type,
xmlElementContentPtr content);
xmlElementTablePtr xmlCopyElementTable(xmlElementTablePtr table);
void xmlFreeElementTable(xmlElementTablePtr table);
@@ -78,9 +78,9 @@ void xmlFreeEnumeration(xmlEnumerationPtr cur);
xmlEnumerationPtr xmlCopyEnumeration(xmlEnumerationPtr cur);
/* Attribute */
-xmlAttributePtr xmlAddAttributeDecl(xmlDtdPtr dtd, CHAR *elem,
- CHAR *name, int type, int def,
- CHAR *defaultValue, xmlEnumerationPtr tree);
+xmlAttributePtr xmlAddAttributeDecl(xmlDtdPtr dtd, const CHAR *elem,
+ const CHAR *name, int type, int def,
+ const CHAR *defaultValue, xmlEnumerationPtr tree);
xmlAttributeTablePtr xmlCopyAttributeTable(xmlAttributeTablePtr table);
void xmlFreeAttributeTable(xmlAttributeTablePtr table);
void xmlDumpAttributeTable(xmlAttributeTablePtr table);
diff --git a/parser.c b/parser.c
index 512611e0..f1ea2fb9 100644
--- a/parser.c
+++ b/parser.c
@@ -43,7 +43,7 @@
*/
#define PUSH_AND_POP(type, name) \
-int name##Push(xmlParserCtxtPtr ctxt, type value) { \
+extern int name##Push(xmlParserCtxtPtr ctxt, type value) { \
if (ctxt->name##Nr >= ctxt->name##Max) { \
ctxt->name##Max *= 2; \
ctxt->name##Tab = (void *) realloc(ctxt->name##Tab, \
@@ -57,7 +57,7 @@ int name##Push(xmlParserCtxtPtr ctxt, type value) { \
ctxt->name = value; \
return(ctxt->name##Nr++); \
} \
-type name##Pop(xmlParserCtxtPtr ctxt) { \
+extern type name##Pop(xmlParserCtxtPtr ctxt) { \
type ret; \
if (ctxt->name##Nr <= 0) return(0); \
ctxt->name##Nr--; \
@@ -496,6 +496,7 @@ static int areBlanks(xmlParserCtxtPtr ctxt, const CHAR *str, int len) {
if (!(IS_BLANK(str[i]))) return(0);
if (CUR != '<') return(0);
+ if (ctxt->node == NULL) return(0);
lastChild = xmlGetLastChild(ctxt->node);
if (lastChild == NULL) {
if (ctxt->node->content != NULL) return(0);
@@ -540,15 +541,14 @@ handle_as_char:
/*
* Just handle the content as a set of chars.
*/
- if (ctxt->sax != NULL)
- ctxt->sax->characters(ctxt, entity->content, 0, len);
+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
+ ctxt->sax->characters(ctxt, entity->content, len);
}
/*
* Forward definition for recusive behaviour.
*/
-xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt);
CHAR *xmlParseReference(xmlParserCtxtPtr ctxt);
@@ -626,6 +626,61 @@ xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, CHAR **prefix) {
}
/**
+ * xmlSplitQName:
+ * @name: an XML parser context
+ * @prefix: a CHAR **
+ *
+ * parse an XML qualified name string
+ *
+ * [NS 5] QName ::= (Prefix ':')? LocalPart
+ *
+ * [NS 6] Prefix ::= NCName
+ *
+ * [NS 7] LocalPart ::= NCName
+ *
+ * Returns the function returns the local part, and prefix is updated
+ * to get the Prefix if any.
+ */
+
+CHAR *
+xmlSplitQName(const CHAR *name, CHAR **prefix) {
+ CHAR *ret = NULL;
+ const CHAR *q;
+ const CHAR *cur = name;
+
+ *prefix = NULL;
+ if (!IS_LETTER(*cur) && (*cur != '_')) return(NULL);
+ q = cur++;
+
+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
+ (*cur == '.') || (*cur == '-') ||
+ (*cur == '_') ||
+ (IS_COMBINING(*cur)) ||
+ (IS_EXTENDER(*cur)))
+ cur++;
+
+ ret = xmlStrndup(q, cur - q);
+
+ if (*cur == ':') {
+ cur++;
+ if (!IS_LETTER(*cur) && (*cur != '_')) return(ret);
+ *prefix = ret;
+
+ q = cur++;
+
+ while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
+ (*cur == '.') || (*cur == '-') ||
+ (*cur == '_') ||
+ (IS_COMBINING(*cur)) ||
+ (IS_EXTENDER(*cur)))
+ cur++;
+
+ ret = xmlStrndup(q, cur - q);
+ }
+
+ return(ret);
+}
+/**
* xmlNamespaceParseNSDef:
* @ctxt: an XML parser context
*
@@ -789,9 +844,10 @@ xmlParseNamespace(xmlParserCtxtPtr ctxt) {
/*
* Register the DTD.
- */
if (href != NULL)
- xmlNewGlobalNs(ctxt->doc, href, prefix);
+ if ((ctxt->sax != NULL) && (ctxt->sax->globalNamespace != NULL))
+ ctxt->sax->globalNamespace(ctxt, href, prefix);
+ */
if (prefix != NULL) free(prefix);
if (href != NULL) free(href);
@@ -1228,10 +1284,13 @@ xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
* Ok the segment [q CUR_PTR] is to be consumed as chars.
*/
if (ctxt->sax != NULL) {
- if (areBlanks(ctxt, q, CUR_PTR - q))
- ctxt->sax->ignorableWhitespace(ctxt, q, 0, CUR_PTR - q);
- else
- ctxt->sax->characters(ctxt, q, 0, CUR_PTR - q);
+ if (areBlanks(ctxt, q, CUR_PTR - q)) {
+ if (ctxt->sax->ignorableWhitespace != NULL)
+ ctxt->sax->ignorableWhitespace(ctxt, q, CUR_PTR - q);
+ } else {
+ if (ctxt->sax->characters != NULL)
+ ctxt->sax->characters(ctxt, q, CUR_PTR - q);
+ }
}
}
@@ -1342,15 +1401,9 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, CHAR **publicID, int strict) {
* must not occur within comments. "
*
* [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
- *
- * TODO: this should call a SAX function which will handle (or not) the
- * creation of the comment !
- *
- * Returns the comment node, or NULL
*/
-xmlNodePtr
+void
xmlParseComment(xmlParserCtxtPtr ctxt, int create) {
- xmlNodePtr ret = NULL;
const CHAR *q, *start;
const CHAR *r;
CHAR *val;
@@ -1359,7 +1412,7 @@ xmlParseComment(xmlParserCtxtPtr ctxt, int create) {
* Check that there is a comment right here.
*/
if ((CUR != '<') || (NXT(1) != '!') ||
- (NXT(2) != '-') || (NXT(3) != '-')) return(NULL);
+ (NXT(2) != '-') || (NXT(3) != '-')) return;
SKIP(4);
start = q = CUR_PTR;
@@ -1385,11 +1438,11 @@ xmlParseComment(xmlParserCtxtPtr ctxt, int create) {
NEXT;
if (create) {
val = xmlStrndup(start, q - start);
- ret = xmlNewDocComment(ctxt->doc, val);
+ if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL))
+ ctxt->sax->comment(ctxt, val);
free(val);
}
}
- return(ret);
}
/**
@@ -1449,54 +1502,29 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
*/
target = xmlParsePITarget(ctxt);
if (target != NULL) {
- /*
- * Support for the old Processing Instruction related to namespace.
- */
- if ((target[0] == 'n') && (target[1] == 'a') &&
- (target[2] == 'm') && (target[3] == 'e') &&
- (target[4] == 's') && (target[5] == 'p') &&
- (target[6] == 'a') && (target[7] == 'c') &&
- (target[8] == 'e')) {
- xmlParseNamespace(ctxt);
- } else if ((target[0] == 'x') && (target[1] == 'm') &&
- (target[2] == 'l') && (target[3] == ':') &&
- (target[4] == 'n') && (target[5] == 'a') &&
- (target[6] == 'm') && (target[7] == 'e') &&
- (target[8] == 's') && (target[9] == 'p') &&
- (target[10] == 'a') && (target[11] == 'c') &&
- (target[12] == 'e')) {
- xmlParseNamespace(ctxt);
- } else {
- const CHAR *q = CUR_PTR;
+ const CHAR *q = CUR_PTR;
- while (IS_CHAR(CUR) &&
- ((CUR != '?') || (NXT(1) != '>')))
- NEXT;
- if (!IS_CHAR(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "xmlParsePI: PI %s never end ...\n", target);
- ctxt->wellFormed = 0;
- } else {
- CHAR *data;
+ while (IS_CHAR(CUR) &&
+ ((CUR != '?') || (NXT(1) != '>')))
+ NEXT;
+ if (!IS_CHAR(CUR)) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt,
+ "xmlParsePI: PI %s never end ...\n", target);
+ ctxt->wellFormed = 0;
+ } else {
+ CHAR *data;
- data = xmlStrndup(CUR_PTR, CUR_PTR - q);
- SKIP(2);
+ data = xmlStrndup(q, CUR_PTR - q);
+ SKIP(2);
- /*
- * SAX: PI detected.
- */
- if (ctxt->sax)
- ctxt->sax->processingInstruction(ctxt, target, data);
- /*
- * Unknown PI, ignore it !
- */
- else
- xmlParserWarning(ctxt,
- "xmlParsePI : skipping unknown PI %s\n",
- target);
- free(data);
- }
+ /*
+ * SAX: PI detected.
+ */
+ if ((ctxt->sax) &&
+ (ctxt->sax->processingInstruction != NULL))
+ ctxt->sax->processingInstruction(ctxt, target, data);
+ free(data);
}
free(target);
} else {
@@ -1577,7 +1605,8 @@ xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
if (CUR == '>') {
NEXT;
- xmlAddNotationDecl(ctxt->doc->intSubset, name, Pubid, Systemid);
+ if ((ctxt->sax != NULL) && (ctxt->sax->notationDecl != NULL))
+ ctxt->sax->notationDecl(ctxt, name, Pubid, Systemid);
} else {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt,
@@ -1662,14 +1691,16 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
if ((CUR == '"') || (CUR == '\''))
value = xmlParseEntityValue(ctxt);
if (value) {
- xmlAddDocEntity(ctxt->doc, name,
+ if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
+ ctxt->sax->entityDecl(ctxt, name,
XML_INTERNAL_PARAMETER_ENTITY,
NULL, NULL, value);
}
else {
URI = xmlParseExternalID(ctxt, &literal, 1);
if (URI) {
- xmlAddDocEntity(ctxt->doc, name,
+ if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
+ ctxt->sax->entityDecl(ctxt, name,
XML_EXTERNAL_PARAMETER_ENTITY,
literal, URI, NULL);
}
@@ -1677,7 +1708,8 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
} else {
if ((CUR == '"') || (CUR == '\'')) {
value = xmlParseEntityValue(ctxt);
- xmlAddDocEntity(ctxt->doc, name,
+ if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
+ ctxt->sax->entityDecl(ctxt, name,
XML_INTERNAL_GENERAL_ENTITY,
NULL, NULL, value);
} else {
@@ -1701,11 +1733,13 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
}
SKIP_BLANKS;
ndata = xmlParseName(ctxt);
- xmlAddDocEntity(ctxt->doc, name,
+ if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
+ ctxt->sax->entityDecl(ctxt, name,
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
literal, URI, ndata);
} else {
- xmlAddDocEntity(ctxt->doc, name,
+ if ((ctxt->sax != NULL) && (ctxt->sax->entityDecl != NULL))
+ ctxt->sax->entityDecl(ctxt, name,
XML_EXTERNAL_GENERAL_PARSED_ENTITY,
literal, URI, NULL);
}
@@ -2087,7 +2121,8 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
"xmlParseAttributeListDecl: detected internal error\n");
break;
}
- xmlAddAttributeDecl(ctxt->doc->intSubset, elemName, attrName,
+ if ((ctxt->sax != NULL) && (ctxt->sax->attributeDecl != NULL))
+ ctxt->sax->attributeDecl(ctxt, elemName, attrName,
type, def, defaultValue, tree);
if (attrName != NULL)
free(attrName);
@@ -2511,7 +2546,8 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
ctxt->wellFormed = 0;
} else {
NEXT;
- xmlAddElementDecl(ctxt->doc->intSubset, name, ret, content);
+ if ((ctxt->sax != NULL) && (ctxt->sax->elementDecl != NULL))
+ ctxt->sax->elementDecl(ctxt, name, ret, content);
}
if (name != NULL) {
free(name);
@@ -2632,7 +2668,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
CHAR *ret = NULL;
const CHAR *q;
CHAR *name;
- xmlEntityPtr ent;
+ xmlEntityPtr ent = NULL;
xmlParserInputPtr input = NULL;
q = CUR_PTR;
@@ -2655,19 +2691,28 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
* then
* the entity referenced must have been declared
*
- * TODO: to be double checked !!!
+ * TODO: to be double checked !!! This is wrong !
*/
- ent = xmlGetDocEntity(ctxt->doc, name);
- if ((ctxt->doc->standalone == 1) ||
- ((ctxt->doc->intSubset == NULL) &&
- (ctxt->doc->extSubset == NULL))) {
- if (ent == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "Entity '%s' not defined\n", name);
- ctxt->wellFormed = 0;
+ if (ctxt->sax != NULL) {
+ if (ctxt->sax->getEntity != NULL)
+ ent = ctxt->sax->getEntity(ctxt, name);
+
+ if (((ctxt->sax->isStandalone != NULL) &&
+ ctxt->sax->isStandalone(ctxt) == 1) ||
+ (((ctxt->sax->hasInternalSubset == NULL) ||
+ ctxt->sax->hasInternalSubset(ctxt) == 0) &&
+ ((ctxt->sax->hasExternalSubset == NULL) ||
+ ctxt->sax->hasExternalSubset(ctxt) == 0))) {
+ if (ent == NULL) {
+ if ((ctxt->sax != NULL) &&
+ (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt,
+ "Entity '%s' not defined\n", name);
+ ctxt->wellFormed = 0;
+ }
}
- }
+ } else
+ ctxt->wellFormed = 0;
/*
* Well Formedness Constraint :
@@ -2703,7 +2748,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
* - get a new input stream
* - or keep the reference inline
*/
- if (ctxt->sax)
+ if ((ctxt->sax) && (ctxt->sax->resolveEntity != NULL))
input = ctxt->sax->resolveEntity(ctxt, NULL, name);
if (input != NULL)
xmlPushInput(ctxt, input);
@@ -2768,7 +2813,7 @@ CHAR *
xmlParsePEReference(xmlParserCtxtPtr ctxt) {
CHAR *ret = NULL;
CHAR *name;
- xmlEntityPtr entity;
+ xmlEntityPtr entity = NULL;
xmlParserInputPtr input;
if (CUR == '%') {
@@ -2781,7 +2826,9 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) {
} else {
if (CUR == ';') {
NEXT;
- entity = xmlGetDtdEntity(ctxt->doc, name);
+ if ((ctxt->sax != NULL) && (ctxt->sax->getEntity != NULL))
+ entity = ctxt->sax->getEntity(ctxt, name);
+ /* TODO !!!! Must check that it's of the proper type !!! */
if (entity == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
ctxt->sax->warning(ctxt,
@@ -2818,7 +2865,6 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) {
void
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
- xmlDtdPtr dtd;
CHAR *name;
CHAR *ExternalID = NULL;
CHAR *URI = NULL;
@@ -2848,7 +2894,8 @@ xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
URI = xmlParseExternalID(ctxt, &ExternalID, 1);
SKIP_BLANKS;
- dtd = xmlCreateIntSubset(ctxt->doc, name, ExternalID, URI);
+ if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL))
+ ctxt->sax->internalSubset(ctxt, name, ExternalID, URI);
/*
* Is there any DTD definition ?
@@ -2901,7 +2948,7 @@ xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
/**
* xmlParseAttribute:
* @ctxt: an XML parser context
- * @node: the node carrying the attribute
+ * @value: a CHAR ** used to store the value of the attribute
*
* parse an attribute
*
@@ -2916,17 +2963,15 @@ xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
* Also the case QName == xmlns:??? is handled independently as a namespace
* definition.
*
- * Returns the attribute just parsed of NULL in case of error.
+ * Returns the attribute name, and the value in *value.
*/
-xmlAttrPtr
-xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
+CHAR *
+xmlParseAttribute(xmlParserCtxtPtr ctxt, CHAR **value) {
CHAR *name, *val;
- CHAR *ns;
- CHAR *value = NULL;
- xmlAttrPtr ret;
- name = xmlNamespaceParseQName(ctxt, &ns);
+ *value = NULL;
+ name = xmlParseName(ctxt);
if (name == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt, "error parsing attribute name\n");
@@ -2941,61 +2986,17 @@ xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
if (CUR == '=') {
NEXT;
SKIP_BLANKS;
- value = xmlParseAttValue(ctxt);
+ val = xmlParseAttValue(ctxt);
} else {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt,
"Specification mandate value for attribute %s\n", name);
ctxt->wellFormed = 0;
- }
-
- /*
- * Check whether it's a namespace definition
- */
- if ((ns == NULL) &&
- (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
- (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
- /* a default namespace definition */
- xmlNewNs(node, value, NULL);
- if (name != NULL)
- free(name);
- if (value != NULL)
- free(value);
return(NULL);
}
- if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
- (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
- /* a standard namespace definition */
- xmlNewNs(node, value, name);
- free(ns);
- if (name != NULL)
- free(name);
- if (value != NULL)
- free(value);
- return(NULL);
- }
-
- /*
- * Well formedness requires at most one declaration of an attribute
- */
- if ((val = xmlGetProp(ctxt->node, name)) != NULL) {
- free(val);
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt, "Attribute %s redefined\n", name);
- ctxt->wellFormed = 0;
- ret = NULL;
- } else {
- ret = xmlNewProp(ctxt->node, name, NULL);
- if (ret != NULL)
- ret->val = xmlStringGetNodeList(ctxt->doc, value);
- }
- if (ns != NULL)
- free(ns);
- if (value != NULL)
- free(value);
- free(name);
- return(ret);
+ *value = val;
+ return(name);
}
/**
@@ -3014,48 +3015,31 @@ xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
* [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
*
* [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
- *
- * Returns the XML new node or NULL.
*/
-xmlNodePtr
+void
xmlParseStartTag(xmlParserCtxtPtr ctxt) {
- CHAR *namespace, *name;
- xmlNsPtr ns = NULL;
- xmlNodePtr ret = NULL;
- xmlNodePtr parent = ctxt->node;
+ CHAR *name;
+ CHAR *attname;
+ CHAR *attvalue;
+ const CHAR **atts = NULL;
+ int nbatts = 0;
+ int maxatts = 0;
+ int i;
- if (CUR != '<') return(NULL);
+ if (CUR != '<') return;
NEXT;
- name = xmlNamespaceParseQName(ctxt, &namespace);
+ name = xmlParseName(ctxt);
if (name == NULL) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt,
"xmlParseStartTag: invalid element name\n");
ctxt->wellFormed = 0;
- return(NULL);
- }
-
- /*
- * Note : the namespace resolution is deferred until the end of the
- * attributes parsing, since local namespace can be defined as
- * an attribute at this level.
- */
- ret = xmlNewDocNode(ctxt->doc, ns, name, NULL);
- if (ret == NULL) {
- if (namespace != NULL)
- free(namespace);
- free(name);
- return(NULL);
+ return;
}
/*
- * We are parsing a new node.
- */
- nodePush(ctxt, ret);
-
- /*
* Now parse the attributes, it ends up with the ending
*
* (S Attribute)* S?
@@ -3066,9 +3050,50 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
((CUR != '/') || (NXT(1) != '>'))) {
const CHAR *q = CUR_PTR;
- xmlParseAttribute(ctxt, ret);
- SKIP_BLANKS;
+ attname = xmlParseAttribute(ctxt, &attvalue);
+ if ((attname != NULL) && (attvalue != NULL)) {
+ /*
+ * Well formedness requires at most one declaration of an attribute
+ */
+ for (i = 0; i < nbatts;i += 2) {
+ if (!xmlStrcmp(atts[i], attname)) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt, "Attribute %s redefined\n",
+ name);
+ ctxt->wellFormed = 0;
+ free(attname);
+ free(attvalue);
+ break;
+ }
+ }
+
+ /*
+ * Add the pair to atts
+ */
+ if (atts == NULL) {
+ maxatts = 10;
+ atts = (const CHAR **) malloc(maxatts * sizeof(CHAR *));
+ if (atts == NULL) {
+ fprintf(stderr, "malloc of %d byte failed\n",
+ maxatts * sizeof(CHAR *));
+ return;
+ }
+ } else if (nbatts + 2 < maxatts) {
+ maxatts *= 2;
+ atts = (const CHAR **) realloc(atts, maxatts * sizeof(CHAR *));
+ if (atts == NULL) {
+ fprintf(stderr, "realloc of %d byte failed\n",
+ maxatts * sizeof(CHAR *));
+ return;
+ }
+ }
+ atts[nbatts++] = attname;
+ atts[nbatts++] = attvalue;
+ atts[nbatts] = NULL;
+ atts[nbatts + 1] = NULL;
+ }
+ SKIP_BLANKS;
if (q == CUR_PTR) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt,
@@ -3079,38 +3104,21 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
}
/*
- * Search the namespace
- */
- ns = xmlSearchNs(ctxt->doc, ret, namespace);
- if (ns == NULL) /* ret still doesn't have a parent yet ! */
- ns = xmlSearchNs(ctxt->doc, parent, namespace);
- xmlSetNs(ret, ns);
- if (namespace != NULL)
- free(namespace);
-
- /*
* SAX: Start of Element !
*/
- if (ctxt->sax != NULL)
- ctxt->sax->startElement(ctxt, name);
- free(name);
-
- /*
- * Link the child element
- */
- if (ctxt->nodeNr < 2) return(ret);
- parent = ctxt->nodeTab[ctxt->nodeNr - 2];
- if (parent != NULL)
- xmlAddChild(parent, ctxt->node);
+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+ ctxt->sax->startElement(ctxt, name, atts);
- return(ret);
+ free(name);
+ if (atts != NULL) {
+ for (i = 0;i < nbatts;i++) free((CHAR *) atts[i]);
+ free(atts);
+ }
}
/**
* xmlParseEndTag:
* @ctxt: an XML parser context
- * @nsPtr: the current node namespace definition
- * @tagPtr: CHAR** receive the tag value
*
* parse an end of tag
*
@@ -3118,18 +3126,12 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
*
* With namespace
*
- * [9] ETag ::= '</' QName S? '>'
- *
- * tagPtr receive the tag name just read
+ * [NS 9] ETag ::= '</' QName S? '>'
*/
void
-xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr) {
- CHAR *namespace, *name;
- xmlNsPtr ns = NULL;
-
- *nsPtr = NULL;
- *tagPtr = NULL;
+xmlParseEndTag(xmlParserCtxtPtr ctxt) {
+ CHAR *name;
if ((CUR != '<') || (NXT(1) != '/')) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
@@ -3139,17 +3141,7 @@ xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr) {
}
SKIP(2);
- name = xmlNamespaceParseQName(ctxt, &namespace);
-
- /*
- * Search the namespace
- */
- ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
- if (namespace != NULL)
- free(namespace);
-
- *nsPtr = ns;
- *tagPtr = name;
+ name = xmlParseName(ctxt);
/*
* We should definitely be at the ending "S? '>'" part
@@ -3162,6 +3154,15 @@ xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr) {
} else
NEXT;
+ /*
+ * SAX: End of Tag
+ */
+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+ ctxt->sax->endElement(ctxt, name);
+
+ if (name != NULL)
+ free(name);
+
return;
}
@@ -3221,10 +3222,14 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
* Ok the segment [base CUR_PTR] is to be consumed as chars.
*/
if (ctxt->sax != NULL) {
- if (areBlanks(ctxt, base, CUR_PTR - base))
- ctxt->sax->ignorableWhitespace(ctxt, base, 0, (CUR_PTR - base) - 2);
- else
- ctxt->sax->characters(ctxt, base, 0, (CUR_PTR - base) - 2);
+ if (areBlanks(ctxt, base, CUR_PTR - base)) {
+ if (ctxt->sax->ignorableWhitespace != NULL)
+ ctxt->sax->ignorableWhitespace(ctxt, base,
+ (CUR_PTR - base) - 2);
+ } else {
+ if (ctxt->sax->characters != NULL)
+ ctxt->sax->characters(ctxt, base, (CUR_PTR - base) - 2);
+ }
}
}
@@ -3239,11 +3244,8 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
void
xmlParseContent(xmlParserCtxtPtr ctxt) {
- xmlNodePtr ret = NULL;
-
while ((CUR != '<') || (NXT(1) != '/')) {
const CHAR *test = CUR_PTR;
- ret = NULL;
/*
* First case : a Processing Instruction.
@@ -3251,6 +3253,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
if ((CUR == '<') && (NXT(1) == '?')) {
xmlParsePI(ctxt);
}
+
/*
* Second case : a CDSection
*/
@@ -3261,19 +3264,22 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
(NXT(8) == '[')) {
xmlParseCDSect(ctxt);
}
+
/*
* Third case : a comment
*/
else if ((CUR == '<') && (NXT(1) == '!') &&
(NXT(2) == '-') && (NXT(3) == '-')) {
- ret = xmlParseComment(ctxt, 1);
+ xmlParseComment(ctxt, 1);
}
+
/*
* Fourth case : a sub-element.
*/
else if (CUR == '<') {
- ret = xmlParseElement(ctxt);
+ xmlParseElement(ctxt);
}
+
/*
* Fifth case : a reference. If if has not been resolved,
* parsing returns it's Name, create the node
@@ -3285,19 +3291,19 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
/*
* inline predefined entity.
*/
- if (ctxt->sax != NULL)
- ctxt->sax->characters(ctxt, val, 0, xmlStrlen(val));
+ if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
+ ctxt->sax->characters(ctxt, val, xmlStrlen(val));
} else {
/*
* user defined entity, create a node.
*/
- ret = xmlNewReference(ctxt->doc, val);
- xmlAddChild(ctxt->node, ret);
- ret = NULL;
+ if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL))
+ ctxt->sax->reference(ctxt, val);
}
free(val);
}
}
+
/*
* Last case, text. Note that References are handled directly.
*/
@@ -3330,42 +3336,27 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
* [39] element ::= EmptyElemTag | STag content ETag
*
* [41] Attribute ::= Name Eq AttValue
- *
- * Returns the XML new node or NULL
*/
-
-xmlNodePtr
+void
xmlParseElement(xmlParserCtxtPtr ctxt) {
- xmlNodePtr ret;
const CHAR *openTag = CUR_PTR;
xmlParserNodeInfo node_info;
- CHAR *endTag;
- xmlNsPtr endNs;
/* Capture start position */
node_info.begin_pos = CUR_PTR - ctxt->input->base;
node_info.begin_line = ctxt->input->line;
- ret = xmlParseStartTag(ctxt);
- if (ret == NULL) {
- return(NULL);
- }
+ xmlParseStartTag(ctxt);
/*
* Check for an Empty Element.
*/
if ((CUR == '/') && (NXT(1) == '>')) {
SKIP(2);
- if (ctxt->sax != NULL)
- ctxt->sax->endElement(ctxt, ret->name);
-
- /*
- * end of parsing of this node.
- */
- nodePop(ctxt);
-
- return(ret);
+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+ ctxt->sax->endElement(ctxt, NULL);
+ return;
}
if (CUR == '>') NEXT;
else {
@@ -3376,10 +3367,11 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
/*
* end of parsing of this node.
+ * TODO !!!!!!!! check the macro in case of non DOM parsing
*/
nodePop(ctxt);
- return(NULL);
+ return;
}
/*
@@ -3394,61 +3386,17 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
/*
* end of parsing of this node.
+ * TODO !!!!!!!! check the macro in case of non DOM parsing
*/
nodePop(ctxt);
- return(NULL);
+ return;
}
/*
* parse the end of tag: '</' should be here.
*/
- xmlParseEndTag(ctxt, &endNs, &endTag);
-
- /*
- * Check that the Name in the ETag is the same as in the STag.
- */
- if (endNs != ret->ns) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "Start and End tags don't use the same namespace\n%.30s\n%.30s\n",
- openTag, endTag);
- ctxt->wellFormed = 0;
- }
- if (endTag == NULL ) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt, "The End tag has no name\n%.30s\n", openTag);
- ctxt->wellFormed = 0;
- } else if (xmlStrcmp(ret->name, endTag)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "Start and End tags don't use the same name\n%.30s\n%.30s\n",
- openTag, endTag);
- ctxt->wellFormed = 0;
- }
- /*
- * SAX: End of Tag
- */
- else if (ctxt->sax != NULL)
- ctxt->sax->endElement(ctxt, endTag);
-
- if (endTag != NULL)
- free(endTag);
-
- /* Capture end position and add node */
- if ( ret != NULL && ctxt->record_info ) {
- node_info.end_pos = CUR_PTR - ctxt->input->base;
- node_info.end_line = ctxt->input->line;
- node_info.node = ret;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
-
- /*
- * end of parsing of this node.
- */
- nodePop(ctxt);
-
- return(ret);
+ xmlParseEndTag(ctxt);
}
/**
@@ -3746,7 +3694,7 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
version = xmlParseVersionInfo(ctxt);
if (version == NULL)
version = xmlCharStrdup(XML_DEFAULT_VERSION);
- ctxt->doc = xmlNewDoc(version);
+ ctxt->version = xmlStrdup(version);
free(version);
/*
@@ -3761,12 +3709,12 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
ctxt->sax->error(ctxt, "Blank needed here\n");
ctxt->wellFormed = 0;
}
- ctxt->doc->encoding = xmlParseEncodingDecl(ctxt);
+ ctxt->encoding = xmlParseEncodingDecl(ctxt);
/*
* We may have the standalone status.
*/
- if ((ctxt->doc->encoding != NULL) && (!IS_BLANK(CUR))) {
+ if ((ctxt->encoding != NULL) && (!IS_BLANK(CUR))) {
if ((CUR == '?') && (NXT(1) == '>')) {
SKIP(2);
return;
@@ -3776,7 +3724,7 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
ctxt->wellFormed = 0;
}
SKIP_BLANKS;
- ctxt->doc->standalone = xmlParseSDDecl(ctxt);
+ ctxt->standalone = xmlParseSDDecl(ctxt);
SKIP_BLANKS;
if ((CUR == '?') && (NXT(1) == '>')) {
@@ -3842,10 +3790,8 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
/*
* SAX: beginning of the document processing.
*/
- if (ctxt->sax)
+ if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
ctxt->sax->setDocumentLocator(ctxt, &xmlDefaultSAXLocator);
- if (ctxt->sax)
- ctxt->sax->startDocument(ctxt);
/*
* We should check for encoding here and plug-in some
@@ -3889,12 +3835,10 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
/* SKIP_EOL(cur); */
SKIP_BLANKS;
} else {
- CHAR *version;
-
- version = xmlCharStrdup(XML_DEFAULT_VERSION);
- ctxt->doc = xmlNewDoc(version);
- free(version);
+ ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
}
+ if ((ctxt->sax) && (ctxt->sax->startDocument))
+ ctxt->sax->startDocument(ctxt);
/*
* The Misc part of the Prolog
@@ -3917,7 +3861,7 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
/*
* Time to start parsing the tree itself
*/
- ctxt->doc->root = xmlParseElement(ctxt);
+ xmlParseElement(ctxt);
/*
* The Misc part at the end
@@ -3934,7 +3878,7 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
/*
* SAX: end of the document processing.
*/
- if (ctxt->sax)
+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
ctxt->sax->endDocument(ctxt);
if (! ctxt->wellFormed) return(-1);
return(0);
@@ -4004,11 +3948,11 @@ xmlSAXParseDoc(xmlSAXHandlerPtr sax, CHAR *cur, int recovery) {
if (sax != NULL) ctxt->sax = sax;
xmlParseDocument(ctxt);
- if ((ctxt->wellFormed) || recovery) ret = ctxt->doc;
+ if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
else {
ret = NULL;
- xmlFreeDoc(ctxt->doc);
- ctxt->doc = NULL;
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
@@ -4187,11 +4131,11 @@ xmlDocPtr xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
xmlParseDocument(ctxt);
- if ((ctxt->wellFormed) || recovery) ret = ctxt->doc;
+ if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
else {
ret = NULL;
- xmlFreeDoc(ctxt->doc);
- ctxt->doc = NULL;
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
@@ -4300,11 +4244,11 @@ xmlSAXParseMemory(xmlSAXHandlerPtr sax, char *buffer, int size, int recovery) {
xmlParseDocument(ctxt);
- if ((ctxt->wellFormed) || recovery) ret = ctxt->doc;
+ if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
else {
ret = NULL;
- xmlFreeDoc(ctxt->doc);
- ctxt->doc = NULL;
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
@@ -4355,6 +4299,9 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
ctxt->inputNr = 0;
ctxt->inputMax = 5;
ctxt->input = NULL;
+ ctxt->version = NULL;
+ ctxt->encoding = NULL;
+ ctxt->standalone = -1;
/* Allocate the Node stack */
ctxt->nodeTab = (xmlNodePtr *) malloc(10 * sizeof(xmlNodePtr));
@@ -4363,7 +4310,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
ctxt->node = NULL;
ctxt->sax = &xmlDefaultSAXHandler;
- ctxt->doc = NULL;
+ ctxt->myDoc = NULL;
ctxt->wellFormed = 1;
ctxt->record_info = 0;
xmlInitNodeInfoSeq(&ctxt->node_seq);
@@ -4374,7 +4321,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
* @ctxt: an XML parser context
*
* Free all the memory used by a parser context. However the parsed
- * document in ctxt->doc is not freed.
+ * document in ctxt->myDoc is not freed.
*/
void
@@ -4390,6 +4337,7 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
if (ctxt->nodeTab != NULL) free(ctxt->nodeTab);
if (ctxt->inputTab != NULL) free(ctxt->inputTab);
+ if (ctxt->version != NULL) free(ctxt->version);
free(ctxt);
}
diff --git a/parser.h b/parser.h
index 3dc84453..3e433a26 100644
--- a/parser.h
+++ b/parser.h
@@ -51,8 +51,12 @@ typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
typedef struct _xmlParserCtxt {
struct xmlSAXHandler *sax; /* The SAX handler */
- xmlDocPtr doc; /* the document being built */
+ void *userData; /* the document being built */
+ xmlDocPtr myDoc; /* the document being built */
int wellFormed; /* is the document well formed */
+ const CHAR *version; /* the XML version string */
+ const CHAR *encoding; /* encoding, if any */
+ int standalone; /* standalone document */
/* Input stream stack */
xmlParserInputPtr input; /* Current input stream */
@@ -89,10 +93,24 @@ typedef xmlSAXLocator *xmlSAXLocatorPtr;
* a SAX Exception.
*/
+#include "entities.h"
+
typedef xmlParserInputPtr (*resolveEntitySAXFunc) (xmlParserCtxtPtr ctxt,
const CHAR *publicId, const CHAR *systemId);
+typedef void (*internalSubsetSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *ExternalID, const CHAR *SystemID);
+typedef xmlEntityPtr (*getEntitySAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *name);
+typedef void (*entityDeclSAXFunc) (xmlParserCtxtPtr ctxt,
+ const CHAR *name, int type, const CHAR *publicId,
+ const CHAR *systemId, CHAR *content);
typedef void (*notationDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
const CHAR *publicId, const CHAR *systemId);
+typedef void (*attributeDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *elem,
+ const CHAR *name, int type, int def,
+ const CHAR *defaultValue, xmlEnumerationPtr tree);
+typedef void (*elementDeclSAXFunc)(xmlParserCtxtPtr ctxt, const CHAR *name,
+ int type, xmlElementContentPtr content);
typedef void (*unparsedEntityDeclSAXFunc)(xmlParserCtxtPtr ctxt,
const CHAR *name, const CHAR *publicId,
const CHAR *systemId, const CHAR *notationName);
@@ -100,33 +118,48 @@ typedef void (*setDocumentLocatorSAXFunc) (xmlParserCtxtPtr ctxt,
xmlSAXLocatorPtr loc);
typedef void (*startDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
typedef void (*endDocumentSAXFunc) (xmlParserCtxtPtr ctxt);
-typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
+typedef void (*startElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR **atts);
typedef void (*endElementSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
typedef void (*attributeSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name,
const CHAR *value);
+typedef void (*referenceSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *name);
typedef void (*charactersSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *ch,
- int start, int len);
+ int len);
typedef void (*ignorableWhitespaceSAXFunc) (xmlParserCtxtPtr ctxt,
- const CHAR *ch, int start, int len);
+ const CHAR *ch, int len);
typedef void (*processingInstructionSAXFunc) (xmlParserCtxtPtr ctxt,
const CHAR *target, const CHAR *data);
+typedef void (*commentSAXFunc) (xmlParserCtxtPtr ctxt, const CHAR *value);
typedef void (*warningSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
typedef void (*errorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
typedef void (*fatalErrorSAXFunc) (xmlParserCtxtPtr ctxt, const char *msg, ...);
+typedef int (*isStandaloneSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef int (*hasInternalSubsetSAXFunc) (xmlParserCtxtPtr ctxt);
+typedef int (*hasExternalSubsetSAXFunc) (xmlParserCtxtPtr ctxt);
typedef struct xmlSAXHandler {
+ internalSubsetSAXFunc internalSubset;
+ isStandaloneSAXFunc isStandalone;
+ hasInternalSubsetSAXFunc hasInternalSubset;
+ hasExternalSubsetSAXFunc hasExternalSubset;
resolveEntitySAXFunc resolveEntity;
+ getEntitySAXFunc getEntity;
+ entityDeclSAXFunc entityDecl;
notationDeclSAXFunc notationDecl;
+ attributeDeclSAXFunc attributeDecl;
+ elementDeclSAXFunc elementDecl;
unparsedEntityDeclSAXFunc unparsedEntityDecl;
setDocumentLocatorSAXFunc setDocumentLocator;
startDocumentSAXFunc startDocument;
endDocumentSAXFunc endDocument;
startElementSAXFunc startElement;
endElementSAXFunc endElement;
- attributeSAXFunc attribute;
+ referenceSAXFunc reference;
charactersSAXFunc characters;
ignorableWhitespaceSAXFunc ignorableWhitespace;
processingInstructionSAXFunc processingInstruction;
+ commentSAXFunc comment;
warningSAXFunc warning;
errorSAXFunc error;
fatalErrorSAXFunc fatalError;
diff --git a/parserInternals.h b/parserInternals.h
index 28ef54d1..75e9e130 100644
--- a/parserInternals.h
+++ b/parserInternals.h
@@ -529,6 +529,8 @@ xmlFreeInputStream(xmlParserInputPtr input);
* Namespaces.
*/
CHAR *
+xmlSplitQName(const CHAR *name, CHAR **prefix);
+CHAR *
xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt);
CHAR *
xmlNamespaceParseQName(xmlParserCtxtPtr ctxt, CHAR **prefix);
@@ -558,7 +560,7 @@ void
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata);
CHAR *
xmlParseExternalID(xmlParserCtxtPtr ctxt, CHAR **publicID, int strict);
-xmlNodePtr
+void
xmlParseComment(xmlParserCtxtPtr ctxt, int create);
CHAR *
xmlParsePITarget(xmlParserCtxtPtr ctxt);
@@ -601,17 +603,17 @@ CHAR *
xmlParsePEReference(xmlParserCtxtPtr ctxt);
void
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt);
-xmlAttrPtr
-xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node);
-xmlNodePtr
+CHAR *
+xmlParseAttribute(xmlParserCtxtPtr ctxt, CHAR **value);
+void
xmlParseStartTag(xmlParserCtxtPtr ctxt);
void
-xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlNsPtr *nsPtr, CHAR **tagPtr);
+xmlParseEndTag(xmlParserCtxtPtr ctxt);
void
xmlParseCDSect(xmlParserCtxtPtr ctxt);
void
xmlParseContent(xmlParserCtxtPtr ctxt);
-xmlNodePtr
+void
xmlParseElement(xmlParserCtxtPtr ctxt);
CHAR *
xmlParseVersionNum(xmlParserCtxtPtr ctxt);
@@ -628,5 +630,12 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt);
void
xmlParseMisc(xmlParserCtxtPtr ctxt);
+/*
+ * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP
+ */
+extern int nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value);
+extern xmlNodePtr nodePop(xmlParserCtxtPtr ctxt);
+extern int inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value);
+extern xmlParserInputPtr inputPop(xmlParserCtxtPtr ctxt);
#endif /* __XML_PARSER_INTERNALS_H__ */
diff --git a/tree.c b/tree.c
index a331fe1d..13c30875 100644
--- a/tree.c
+++ b/tree.c
@@ -1088,7 +1088,7 @@ xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len) {
* Returns a pointer to the new node object.
*/
xmlNodePtr
-xmlNewComment(CHAR *content) {
+xmlNewComment(const CHAR *content) {
xmlNodePtr cur;
/*
@@ -1128,7 +1128,7 @@ xmlNewComment(CHAR *content) {
* Returns a pointer to the new node object.
*/
xmlNodePtr
-xmlNewDocComment(xmlDocPtr doc, CHAR *content) {
+xmlNewDocComment(xmlDocPtr doc, const CHAR *content) {
xmlNodePtr cur;
cur = xmlNewComment(content);
diff --git a/tree.h b/tree.h
index 4443836b..3f00aa09 100644
--- a/tree.h
+++ b/tree.h
@@ -283,8 +283,8 @@ xmlNodePtr xmlNewDocText(xmlDocPtr doc, const CHAR *content);
xmlNodePtr xmlNewText(const CHAR *content);
xmlNodePtr xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len);
xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
-xmlNodePtr xmlNewDocComment(xmlDocPtr doc, CHAR *content);
-xmlNodePtr xmlNewComment(CHAR *content);
+xmlNodePtr xmlNewDocComment(xmlDocPtr doc, const CHAR *content);
+xmlNodePtr xmlNewComment(const CHAR *content);
xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name);
xmlNodePtr xmlCopyNode(xmlNodePtr node, int recursive);
xmlNodePtr xmlCopyNodeList(xmlNodePtr node);
diff --git a/valid.c b/valid.c
index 3cb6276c..2c1be9f2 100644
--- a/valid.c
+++ b/valid.c
@@ -216,7 +216,7 @@ xmlCreateElementTable(void) {
* Returns NULL if not, othervise the entity
*/
xmlElementPtr
-xmlAddElementDecl(xmlDtdPtr dtd, CHAR *name, int type,
+xmlAddElementDecl(xmlDtdPtr dtd, const CHAR *name, int type,
xmlElementContentPtr content) {
xmlElementPtr ret, cur;
xmlElementTablePtr table;
@@ -560,8 +560,9 @@ xmlCreateAttributeTable(void) {
* Returns NULL if not, othervise the entity
*/
xmlAttributePtr
-xmlAddAttributeDecl(xmlDtdPtr dtd, CHAR *elem, CHAR *name, int type, int def,
- CHAR *defaultValue, xmlEnumerationPtr tree) {
+xmlAddAttributeDecl(xmlDtdPtr dtd, const CHAR *elem, const CHAR *name,
+ int type, int def, const CHAR *defaultValue,
+ xmlEnumerationPtr tree) {
xmlAttributePtr ret, cur;
xmlAttributeTablePtr table;
int i;
@@ -890,7 +891,8 @@ xmlCreateNotationTable(void) {
* Returns NULL if not, othervise the entity
*/
xmlNotationPtr
-xmlAddNotationDecl(xmlDtdPtr dtd, CHAR *name, CHAR *PublicID, CHAR *SystemID) {
+xmlAddNotationDecl(xmlDtdPtr dtd, const CHAR *name, const CHAR *PublicID,
+ const CHAR *SystemID) {
xmlNotationPtr ret, cur;
xmlNotationTablePtr table;
int i;
diff --git a/valid.h b/valid.h
index 14a72285..22c824ab 100644
--- a/valid.h
+++ b/valid.h
@@ -54,8 +54,8 @@ typedef struct xmlAttributeTable {
typedef xmlAttributeTable *xmlAttributeTablePtr;
/* Notation */
-xmlNotationPtr xmlAddNotationDecl(xmlDtdPtr dtd, CHAR *name,
- CHAR *PublicID, CHAR *SystemID);
+xmlNotationPtr xmlAddNotationDecl(xmlDtdPtr dtd, const CHAR *name,
+ const CHAR *PublicID, const CHAR *SystemID);
xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table);
void xmlFreeNotationTable(xmlNotationTablePtr table);
void xmlDumpNotationTable(xmlNotationTablePtr table);
@@ -66,7 +66,7 @@ xmlElementContentPtr xmlCopyElementContent(xmlElementContentPtr content);
void xmlFreeElementContent(xmlElementContentPtr cur);
/* Element */
-xmlElementPtr xmlAddElementDecl(xmlDtdPtr dtd, CHAR *name, int type,
+xmlElementPtr xmlAddElementDecl(xmlDtdPtr dtd, const CHAR *name, int type,
xmlElementContentPtr content);
xmlElementTablePtr xmlCopyElementTable(xmlElementTablePtr table);
void xmlFreeElementTable(xmlElementTablePtr table);
@@ -78,9 +78,9 @@ void xmlFreeEnumeration(xmlEnumerationPtr cur);
xmlEnumerationPtr xmlCopyEnumeration(xmlEnumerationPtr cur);
/* Attribute */
-xmlAttributePtr xmlAddAttributeDecl(xmlDtdPtr dtd, CHAR *elem,
- CHAR *name, int type, int def,
- CHAR *defaultValue, xmlEnumerationPtr tree);
+xmlAttributePtr xmlAddAttributeDecl(xmlDtdPtr dtd, const CHAR *elem,
+ const CHAR *name, int type, int def,
+ const CHAR *defaultValue, xmlEnumerationPtr tree);
xmlAttributeTablePtr xmlCopyAttributeTable(xmlAttributeTablePtr table);
void xmlFreeAttributeTable(xmlAttributeTablePtr table);
void xmlDumpAttributeTable(xmlAttributeTablePtr table);