aboutsummaryrefslogtreecommitdiffstats
path: root/SAX.c
diff options
context:
space:
mode:
Diffstat (limited to 'SAX.c')
-rw-r--r--SAX.c162
1 files changed, 154 insertions, 8 deletions
diff --git a/SAX.c b/SAX.c
index 968021ad..28bf0c2f 100644
--- a/SAX.c
+++ b/SAX.c
@@ -132,7 +132,7 @@ hasExternalSubset(void *ctx)
}
/**
- * hasInternalSubset:
+ * internalSubset:
* @ctx: the user data (XML parser context)
*
* Does this document has an internal subset
@@ -141,15 +141,72 @@ void
internalSubset(void *ctx, const CHAR *name,
const CHAR *ExternalID, const CHAR *SystemID)
{
- xmlDtdPtr externalSubset;
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.internalSubset(%s, %s, %s)\n",
name, ExternalID, SystemID);
#endif
xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
- if ((ExternalID != NULL) || (SystemID != NULL)) {
- externalSubset = xmlParseDTD(ExternalID, SystemID);
+ if (((ExternalID != NULL) || (SystemID != NULL)) &&
+ (ctxt->validate && ctxt->wellFormed && ctxt->myDoc)) {
+ /*
+ * Try to fetch and parse the external subset.
+ */
+ xmlDtdPtr ret = NULL;
+ xmlParserCtxtPtr dtdCtxt;
+ xmlParserInputPtr input = NULL;
+ xmlCharEncoding enc;
+
+ dtdCtxt = xmlNewParserCtxt();
+ if (dtdCtxt == NULL) return;
+
+ /*
+ * Ask the Entity resolver to load the damn thing
+ */
+ if ((ctxt->directory != NULL) && (dtdCtxt->directory == NULL))
+ dtdCtxt->directory = xmlStrdup(ctxt->directory);
+
+ if ((dtdCtxt->sax != NULL) && (dtdCtxt->sax->resolveEntity != NULL))
+ input = dtdCtxt->sax->resolveEntity(dtdCtxt->userData, ExternalID,
+ SystemID);
+ if (input == NULL) {
+ xmlFreeParserCtxt(dtdCtxt);
+ return;
+ }
+
+ /*
+ * plug some encoding conversion routines here. !!!
+ */
+ xmlPushInput(dtdCtxt, input);
+ enc = xmlDetectCharEncoding(dtdCtxt->input->cur);
+ xmlSwitchEncoding(dtdCtxt, enc);
+
+ if (input->filename == NULL)
+ input->filename = xmlStrdup(SystemID);
+ input->line = 1;
+ input->col = 1;
+ input->base = dtdCtxt->input->cur;
+ input->cur = dtdCtxt->input->cur;
+ input->free = NULL;
+
+ /*
+ * let's parse that entity knowing it's an external subset.
+ */
+ xmlParseExternalSubset(dtdCtxt, ExternalID, SystemID);
+
+ if (dtdCtxt->myDoc != NULL) {
+ if (dtdCtxt->wellFormed) {
+ ret = dtdCtxt->myDoc->intSubset;
+ dtdCtxt->myDoc->intSubset = NULL;
+ } else {
+ ret = NULL;
+ }
+ xmlFreeDoc(dtdCtxt->myDoc);
+ dtdCtxt->myDoc = NULL;
+ }
+ xmlFreeParserCtxt(dtdCtxt);
+
+ ctxt->myDoc->extSubset = ret;
}
}
@@ -214,6 +271,29 @@ getEntity(void *ctx, const CHAR *name)
return(ret);
}
+/**
+ * getParameterEntity:
+ * @ctx: the user data (XML parser context)
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlEntityPtr if found.
+ */
+xmlEntityPtr
+getParameterEntity(void *ctx, const CHAR *name)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlEntityPtr ret;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.getParameterEntity(%s)\n", name);
+#endif
+
+ ret = xmlGetParameterEntity(ctxt->myDoc, name);
+ return(ret);
+}
+
/**
* entityDecl:
@@ -256,13 +336,19 @@ attributeDecl(void *ctx, const CHAR *elem, const CHAR *name,
xmlEnumerationPtr tree)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlAttributePtr attr;
#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);
+ attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
+ name, type, def, defaultValue, tree);
+ if (attr == 0) ctxt->valid = 0;
+ if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset)
+ ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
+ attr);
}
/**
@@ -281,12 +367,19 @@ elementDecl(void *ctx, const CHAR *name, int type,
xmlElementContentPtr content)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlElementPtr elem;
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.elementDecl(%s, %d, ...)\n",
name, type);
#endif
- xmlAddElementDecl(ctxt->myDoc->intSubset, name, type, content);
+
+ elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
+ name, type, content);
+ if (elem == 0) ctxt->valid = 0;
+ if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset)
+ ctxt->valid &= xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
}
/**
@@ -304,10 +397,19 @@ notationDecl(void *ctx, const CHAR *name,
const CHAR *publicId, const CHAR *systemId)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlNotationPtr nota;
+
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
#endif
- xmlAddNotationDecl(ctxt->myDoc->intSubset, name, publicId, systemId);
+
+ nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
+ publicId, systemId);
+ if (nota == 0) ctxt->valid = 0;
+ if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset)
+ ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
+ nota);
}
/**
@@ -442,8 +544,15 @@ attribute(void *ctx, const CHAR *fullname, const CHAR *value)
}
ret = xmlNewProp(ctxt->node, name, NULL);
+
if ((ret != NULL) && (ctxt->replaceEntities == 0))
ret->val = xmlStringGetNodeList(ctxt->myDoc, value);
+
+ if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset)
+ ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
+ ctxt->node, ret, value);
+
if (name != NULL)
free(name);
if (ns != NULL)
@@ -569,6 +678,12 @@ endElement(void *ctx, const CHAR *name)
xmlParserAddNodeInfo(ctxt, &node_info);
}
+ if (ctxt->validate && ctxt->wellFormed &&
+ ctxt->myDoc && ctxt->myDoc->intSubset)
+ ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
+ cur);
+
+
/*
* end of parsing of this node.
*/
@@ -821,6 +936,29 @@ comment(void *ctx, const CHAR *value)
#endif
ret = xmlNewDocComment(ctxt->myDoc, value);
xmlAddChild(ctxt->node, ret);
+ /* !!!!! merges */
+}
+
+/**
+ * cdataBlock:
+ * @ctx: the user data (XML parser context)
+ * @value: The pcdata content
+ * @len: the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+void
+cdataBlock(void *ctx, const CHAR *value, int len)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlNodePtr ret;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.pcdata(%s, %d)\n", name, len);
+#endif
+ ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
+ xmlAddChild(ctxt->node, ret);
+ /* !!!!! merges */
}
/*
@@ -851,6 +989,8 @@ xmlSAXHandler xmlDefaultSAXHandler = {
xmlParserWarning,
xmlParserError,
xmlParserError,
+ getParameterEntity,
+ cdataBlock,
};
/**
@@ -867,6 +1007,7 @@ xmlDefaultSAXHandlerInit(void)
xmlDefaultSAXHandler.hasExternalSubset = hasExternalSubset;
xmlDefaultSAXHandler.resolveEntity = resolveEntity;
xmlDefaultSAXHandler.getEntity = getEntity;
+ xmlDefaultSAXHandler.getParameterEntity = getParameterEntity;
xmlDefaultSAXHandler.entityDecl = entityDecl;
xmlDefaultSAXHandler.attributeDecl = attributeDecl;
xmlDefaultSAXHandler.elementDecl = elementDecl;
@@ -879,6 +1020,7 @@ xmlDefaultSAXHandlerInit(void)
xmlDefaultSAXHandler.endElement = endElement;
xmlDefaultSAXHandler.reference = reference;
xmlDefaultSAXHandler.characters = characters;
+ xmlDefaultSAXHandler.cdataBlock = cdataBlock;
xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
xmlDefaultSAXHandler.processingInstruction = processingInstruction;
xmlDefaultSAXHandler.comment = comment;
@@ -915,6 +1057,8 @@ xmlSAXHandler htmlDefaultSAXHandler = {
xmlParserWarning,
xmlParserError,
xmlParserError,
+ getParameterEntity,
+ NULL,
};
/**
@@ -931,6 +1075,7 @@ htmlDefaultSAXHandlerInit(void)
htmlDefaultSAXHandler.hasExternalSubset = NULL;
htmlDefaultSAXHandler.resolveEntity = NULL;
htmlDefaultSAXHandler.getEntity = getEntity;
+ htmlDefaultSAXHandler.getParameterEntity = NULL;
htmlDefaultSAXHandler.entityDecl = NULL;
htmlDefaultSAXHandler.attributeDecl = NULL;
htmlDefaultSAXHandler.elementDecl = NULL;
@@ -943,6 +1088,7 @@ htmlDefaultSAXHandlerInit(void)
htmlDefaultSAXHandler.endElement = endElement;
htmlDefaultSAXHandler.reference = NULL;
htmlDefaultSAXHandler.characters = characters;
+ htmlDefaultSAXHandler.cdataBlock = NULL;
htmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
htmlDefaultSAXHandler.processingInstruction = NULL;
htmlDefaultSAXHandler.comment = comment;