📄 sax2.c
字号:
* xmlSAX2StartDocument: * @ctx: the user data (XML parser context) * * called when the document start being processed. */voidxmlSAX2StartDocument(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlDocPtr doc; if (ctx == NULL) return;#ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2StartDocument()\n");#endif if (ctxt->html) {#ifdef LIBXML_HTML_ENABLED if (ctxt->myDoc == NULL) ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); if (ctxt->myDoc == NULL) { xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); return; }#else xmlGenericError(xmlGenericErrorContext, "libxml2 built without HTML support\n"); ctxt->errNo = XML_ERR_INTERNAL_ERROR; ctxt->instate = XML_PARSER_EOF; ctxt->disableSAX = 1; return;#endif } else { 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; } else { xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); return; } if ((ctxt->dictNames) && (doc != NULL)) { doc->dict = ctxt->dict; xmlDictReference(doc->dict); } } if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename); if (ctxt->myDoc->URL == NULL) xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument"); }}/** * xmlSAX2EndDocument: * @ctx: the user data (XML parser context) * * called when the document end has been detected. */voidxmlSAX2EndDocument(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;#ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndDocument()\n");#endif if (ctx == NULL) return;#ifdef LIBXML_VALID_ENABLED if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);#endif /* LIBXML_VALID_ENABLED */ /* * Grab the encoding if it was added on-the-fly */ if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) && (ctxt->myDoc->encoding == NULL)) { ctxt->myDoc->encoding = ctxt->encoding; ctxt->encoding = NULL; } if ((ctxt->inputTab != NULL) && (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) && (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) && (ctxt->myDoc->encoding == NULL)) { ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding); } if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) && (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) { ctxt->myDoc->charset = ctxt->charset; }}#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)/** * xmlSAX2AttributeInternal: * @ctx: the user data (XML parser context) * @fullname: The attribute name, including namespace prefix * @value: The attribute value * @prefix: the prefix on the element node * * 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. */static voidxmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, const xmlChar *value, const xmlChar *prefix ATTRIBUTE_UNUSED){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlAttrPtr ret; xmlChar *name; xmlChar *ns; xmlChar *nval; xmlNsPtr namespace; if (ctxt->html) { name = xmlStrdup(fullname); ns = NULL; namespace = NULL; } else { /* * Split the full name into a namespace prefix and the tag name */ name = xmlSplitQName(ctxt, fullname, &ns); if ((name != NULL) && (name[0] == 0)) { if (xmlStrEqual(ns, BAD_CAST "xmlns")) { xmlNsErrMsg(ctxt, XML_ERR_NS_DECL_ERROR, "invalid namespace declaration '%s'\n", fullname, NULL); } else { xmlNsWarnMsg(ctxt, XML_WAR_NS_COLUMN, "Avoid attribute ending with ':' like '%s'\n", fullname, NULL); } if (ns != NULL) xmlFree(ns); ns = NULL; xmlFree(name); name = xmlStrdup(fullname); } } if (name == NULL) { xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); if (ns != NULL) xmlFree(ns); return; }#ifdef LIBXML_VALID_ENABLED /* * Do the last stage of the attribute normalization * Needed for HTML too: * http://www.w3.org/TR/html4/types.html#h-6.2 */ ctxt->vctxt.valid = 1; nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt, ctxt->myDoc, ctxt->node, fullname, value); if (ctxt->vctxt.valid != 1) { ctxt->valid = 0; } if (nval != NULL) value = nval;#else nval = NULL;#endif /* LIBXML_VALID_ENABLED */ /* * Check whether it's a namespace definition */ if ((!ctxt->html) && (ns == NULL) && (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') && (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) { xmlNsPtr nsret; xmlChar *val; if (!ctxt->replaceEntities) { ctxt->depth++; val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 0,0,0); ctxt->depth--; } else { val = (xmlChar *) value; } if (val[0] != 0) { xmlURIPtr uri; uri = xmlParseURI((const char *)val); if (uri == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) ctxt->sax->warning(ctxt->userData, "xmlns: %s not a valid URI\n", val); } else { if (uri->scheme == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) ctxt->sax->warning(ctxt->userData, "xmlns: URI %s is not absolute\n", val); } xmlFreeURI(uri); } } /* a default namespace definition */ nsret = xmlNewNs(ctxt->node, val, NULL);#ifdef LIBXML_VALID_ENABLED /* * Validate also for namespace decls, they are attributes from * an XML-1.0 perspective */ if (nsret != NULL && ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, ctxt->node, prefix, nsret, val);#endif /* LIBXML_VALID_ENABLED */ if (name != NULL) xmlFree(name); if (nval != NULL) xmlFree(nval); if (val != value) xmlFree(val); return; } if ((!ctxt->html) && (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { xmlNsPtr nsret; xmlChar *val; if (!ctxt->replaceEntities) { ctxt->depth++; val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 0,0,0); ctxt->depth--; if (val == NULL) { xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); xmlFree(ns); if (name != NULL) xmlFree(name); return; } } else { val = (xmlChar *) value; } if (val[0] == 0) { xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY, "Empty namespace name for prefix %s\n", name, NULL); } if ((ctxt->pedantic != 0) && (val[0] != 0)) { xmlURIPtr uri; uri = xmlParseURI((const char *)val); if (uri == NULL) { xmlNsWarnMsg(ctxt, XML_WAR_NS_URI, "xmlns:%s: %s not a valid URI\n", name, value); } else { if (uri->scheme == NULL) { xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE, "xmlns:%s: URI %s is not absolute\n", name, value); } xmlFreeURI(uri); } } /* a standard namespace definition */ nsret = xmlNewNs(ctxt->node, val, name); xmlFree(ns);#ifdef LIBXML_VALID_ENABLED /* * Validate also for namespace decls, they are attributes from * an XML-1.0 perspective */ if (nsret != NULL && ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, ctxt->node, prefix, nsret, value);#endif /* LIBXML_VALID_ENABLED */ if (name != NULL) xmlFree(name); if (nval != NULL) xmlFree(nval); if (val != value) xmlFree(val); return; } if (ns != NULL) { xmlAttrPtr prop; namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns); if (namespace == NULL) { xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, "Namespace prefix %s of attribute %s is not defined\n", ns, name); } prop = ctxt->node->properties; while (prop != NULL) { if (prop->ns != NULL) { if ((xmlStrEqual(name, prop->name)) && ((namespace == prop->ns) || (xmlStrEqual(namespace->href, prop->ns->href)))) { xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED, "Attribute %s in %s redefined\n", name, namespace->href); ctxt->wellFormed = 0; if (ctxt->recovery == 0) ctxt->disableSAX = 1; goto error; } } prop = prop->next; } } else { namespace = NULL; } /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */ ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL); if (ret != NULL) { if ((ctxt->replaceEntities == 0) && (!ctxt->html)) { xmlNodePtr tmp; ret->children = xmlStringGetNodeList(ctxt->myDoc, value); tmp = ret->children; while (tmp != NULL) { tmp->parent = (xmlNodePtr) ret; if (tmp->next == NULL) ret->last = tmp; tmp = tmp->next; } } else if (value != NULL) { ret->children = xmlNewDocText(ctxt->myDoc, value); ret->last = ret->children; if (ret->children != NULL) ret->children->parent = (xmlNodePtr) ret; } }#ifdef LIBXML_VALID_ENABLED if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) { /* * If we don't substitute entities, the validation should be * done on a value with replaced entities anyway. */ if (!ctxt->replaceEntities) { xmlChar *val; ctxt->depth++; val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF, 0,0,0); ctxt->depth--; if (val == NULL) ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value); else { xmlChar *nvalnorm; /* * Do the last stage of the attribute normalization * It need to be done twice ... it's an extra burden related * to the ability to keep xmlSAX2References in attributes */ nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node, fullname, val); if (nvalnorm != NULL) { xmlFree(val); val = nvalnorm; } ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, val); xmlFree(val); } } else { ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value); } } else#endif /* LIBXML_VALID_ENABLED */ if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) && (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) || ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) { /* * when validating, the ID registration is done at the attribute * validation level. Otherwise we have to do specific handling here. */ if (xmlStrEqual(fullname, BAD_CAST "xml:id")) { /* * Add the xml:id value * * Open issue: normalization of the value. */ if (xmlValidateNCName(value, 1) != 0) { xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, "xml:id : attribute value %s is not an NCName\n", (const char *) value, NULL); } xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret); else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret); }error: if (nval != NULL) xmlFree(nval); if (ns != NULL) xmlFree(ns);}/* * xmlCheckDefaultedAttributes: * * Check defaulted attributes from the DTD */static voidxmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name, const xmlChar *prefix, const xmlChar **atts) { xmlElementPtr elemDecl; const xmlChar *att; int internal = 1; int i; elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix); if (elemDecl == NULL) { elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix); internal = 0; }process_external_subset: if (elemDecl != NULL) { xmlAttributePtr attr = elemDecl->attributes; /* * Check against defaulted attributes from the external subset * if the document is stamped as standalone */ if ((ctxt->myDoc->standalone == 1) && (ctxt->myDoc->extSubset != NULL) && (ctxt->validate)) { while (attr != NULL) { if ((attr->defaultValue != NULL) && (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset, attr->elem, attr->name, attr->prefix) == attr) && (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset, attr->elem, attr->name, attr->prefix) == NULL)) { xmlChar *fulln; if (attr->prefix != NULL) { fulln = xmlStrdup(attr->prefix); fulln = xmlStrcat(fulln, BAD_CAST ":"); fulln = xmlStrcat(fulln, attr->name); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -