Release 1.6, lot of fixes, more validation, code cleanup, added namespace
on attributes, Daniel.
diff --git a/SAX.c b/SAX.c
index 28bf0c2..60e6ff8 100644
--- a/SAX.c
+++ b/SAX.c
@@ -14,8 +14,10 @@
#include "valid.h"
#include "entities.h"
#include "xml-error.h"
+#include "debugXML.h"
/* #define DEBUG_SAX */
+/* #define DEBUG_SAX_TREE */
/**
* getPublicId:
@@ -45,7 +47,7 @@
getSystemId(void *ctx)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return(ctxt->input->filename);
+ return(BAD_CAST ctxt->input->filename);
}
/**
@@ -164,7 +166,7 @@
* Ask the Entity resolver to load the damn thing
*/
if ((ctxt->directory != NULL) && (dtdCtxt->directory == NULL))
- dtdCtxt->directory = xmlStrdup(ctxt->directory);
+ dtdCtxt->directory = (char *) xmlStrdup(BAD_CAST ctxt->directory);
if ((dtdCtxt->sax != NULL) && (dtdCtxt->sax->resolveEntity != NULL))
input = dtdCtxt->sax->resolveEntity(dtdCtxt->userData, ExternalID,
@@ -182,7 +184,7 @@
xmlSwitchEncoding(dtdCtxt, enc);
if (input->filename == NULL)
- input->filename = xmlStrdup(SystemID);
+ input->filename = (char *) xmlStrdup(SystemID);
input->line = 1;
input->col = 1;
input->base = dtdCtxt->input->cur;
@@ -234,15 +236,13 @@
#endif
/*
- * TODO : not 100% sure that the appropriate handling in that case.
+ * TODO : resolveEntity, handling of http://.. or ftp://..
*/
if (systemId != NULL) {
- if (!xmlStrncmp(systemId, "http://", 7)) {
- /* !!!!!!!!! TODO */
- } else if (!xmlStrncmp(systemId, "ftp://", 6)) {
- /* !!!!!!!!! TODO */
+ if (!xmlStrncmp(systemId, BAD_CAST "http://", 7)) {
+ } else if (!xmlStrncmp(systemId, BAD_CAST "ftp://", 6)) {
} else {
- return(xmlNewInputFromFile(ctxt, systemId));
+ return(xmlNewInputFromFile(ctxt, (char *) systemId));
}
}
return(NULL);
@@ -390,7 +390,6 @@
* @systemId: The system ID of the entity
*
* What to do when a notation declaration has been parsed.
- * TODO Not handled currently.
*/
void
notationDecl(void *ctx, const CHAR *name,
@@ -421,18 +420,24 @@
* @notationName: the name of the notation
*
* What to do when an unparsed entity declaration is parsed
- * TODO Create an Entity node.
*/
void
unparsedEntityDecl(void *ctx, const CHAR *name,
const CHAR *publicId, const CHAR *systemId,
const CHAR *notationName)
{
- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
name, publicId, systemId, notationName);
#endif
+ if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset)
+ ctxt->valid &= xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
+ notationName);
+ xmlAddDocEntity(ctxt->myDoc, name,
+ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
+ publicId, systemId, notationName);
}
/**
@@ -510,6 +515,7 @@
xmlAttrPtr ret;
CHAR *name;
CHAR *ns;
+ xmlNsPtr namespace;
/****************
#ifdef DEBUG_SAX
@@ -543,15 +549,29 @@
return;
}
- ret = xmlNewProp(ctxt->node, name, NULL);
+ namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
+ /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
+ ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
- if ((ret != NULL) && (ctxt->replaceEntities == 0))
- ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
+ if (ret != NULL) {
+ if (ctxt->replaceEntities == 0)
+ ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
+ else
+ ret->val = xmlNewDocText(ctxt->myDoc, value);
+ }
if (ctxt->validate && ctxt->wellFormed &&
ctxt->myDoc && ctxt->myDoc->intSubset)
ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
ctxt->node, ret, value);
+ else {
+ /*
+ * when validating, the ID registration is done at the attribute
+ * validation level. Otherwise we have to do specific handling here.
+ */
+ if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
+ }
if (name != NULL)
free(name);
@@ -566,7 +586,6 @@
* @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(void *ctx, const CHAR *fullname, const CHAR **atts)
@@ -598,32 +617,67 @@
*/
ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
if (ret == NULL) return;
- if (ctxt->myDoc->root == NULL)
+ if (ctxt->myDoc->root == NULL) {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "Setting %s as root\n", name);
+#endif
ctxt->myDoc->root = ret;
+ } else if (parent == NULL) {
+ parent = ctxt->myDoc->root;
+ }
/*
* We are parsing a new node.
*/
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "pushing(%s)\n", name);
+#endif
nodePush(ctxt, ret);
/*
* Link the child element
*/
- if (parent != NULL)
- xmlAddChild(parent, ctxt->node);
+ if (parent != NULL) {
+ if (parent->type == XML_ELEMENT_NODE) {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "adding child %s to %s\n", name, parent->name);
+#endif
+ xmlAddChild(parent, ret);
+ } else {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "adding sibling %s to ", name);
+ xmlDebugDumpOneNode(stderr, parent, 0);
+#endif
+ xmlAddSibling(parent, ret);
+ }
+ }
/*
- * process all the attributes.
+ * process all the attributes whose name start with "xml"
*/
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);
+ if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l'))
+ attribute(ctxt, att, value);
+
+ att = atts[i++];
+ value = atts[i++];
+ }
+ }
+
+ /*
+ * process all the other attributes
+ */
+ if (atts != NULL) {
+ i = 0;
+ att = atts[i++];
+ value = atts[i++];
+ while ((att != NULL) && (value != NULL)) {
+ if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l'))
+ attribute(ctxt, att, value);
/*
* Next ones
@@ -687,6 +741,9 @@
/*
* end of parsing of this node.
*/
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "popping(%s)\n", cur->name);
+#endif
nodePop(ctxt);
}
@@ -707,6 +764,9 @@
fprintf(stderr, "SAX.reference(%s)\n", name);
#endif
ret = xmlNewReference(ctxt->myDoc, name);
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "add reference %s to %s \n", name, ctxt->node->name);
+#endif
xmlAddChild(ctxt->node, ret);
}
@@ -735,6 +795,9 @@
*/
lastChild = xmlGetLastChild(ctxt->node);
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "add chars to %s \n", ctxt->node->name);
+#endif
if (lastChild == NULL)
xmlNodeAddContentLen(ctxt->node, ch, len);
else {
@@ -778,10 +841,40 @@
processingInstruction(void *ctx, const CHAR *target,
const CHAR *data)
{
- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlNodePtr ret;
+ xmlNodePtr parent = ctxt->node;
+
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
#endif
+
+ ret = xmlNewPI(target, data);
+ if (ret == NULL) return;
+ ret->doc = ctxt->myDoc;
+ if (ctxt->myDoc->root == NULL) {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "Setting PI %s as root\n", target);
+#endif
+ ctxt->myDoc->root = ret;
+ } else if (parent == NULL) {
+ parent = ctxt->myDoc->root;
+ }
+ if (parent != NULL) {
+ if (parent->type == XML_ELEMENT_NODE) {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "adding PI child %s to %s\n", target, parent->name);
+#endif
+ xmlAddChild(parent, ret);
+ } else {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "adding PI sibling %s to ", target);
+ xmlDebugDumpOneNode(stderr, parent, 0);
+#endif
+ xmlAddSibling(parent, ret);
+ }
+ }
+
}
/**
@@ -885,7 +978,7 @@
"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)) {
+ } else if (xmlStrcmp(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",
@@ -930,13 +1023,36 @@
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
xmlNodePtr ret;
+ xmlNodePtr parent = ctxt->node;
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.comment(%s)\n", value);
#endif
ret = xmlNewDocComment(ctxt->myDoc, value);
- xmlAddChild(ctxt->node, ret);
- /* !!!!! merges */
+ if (ret == NULL) return;
+
+ if (ctxt->myDoc->root == NULL) {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "Setting comment as root\n");
+#endif
+ ctxt->myDoc->root = ret;
+ } else if (parent == NULL) {
+ parent = ctxt->myDoc->root;
+ }
+ if (parent != NULL) {
+ if (parent->type == XML_ELEMENT_NODE) {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "adding comment child to %s\n", parent->name);
+#endif
+ xmlAddChild(parent, ret);
+ } else {
+#ifdef DEBUG_SAX_TREE
+ fprintf(stderr, "adding comment sibling to ");
+ xmlDebugDumpOneNode(stderr, parent, 0);
+#endif
+ xmlAddSibling(parent, ret);
+ }
+ }
}
/**
@@ -954,7 +1070,7 @@
xmlNodePtr ret;
#ifdef DEBUG_SAX
- fprintf(stderr, "SAX.pcdata(%s, %d)\n", name, len);
+ fprintf(stderr, "SAX.pcdata(%.10s, %d)\n", value, len);
#endif
ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
xmlAddChild(ctxt->node, ret);