📄 sax.c
字号:
{ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNotationPtr nota = NULL;#ifdef DEBUG_SAX fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);#endif if (ctxt->inSubset == 1) nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name, publicId, systemId); else if (ctxt->inSubset == 2) nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name, publicId, systemId); else { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt, "SAX.notationDecl(%s) called while not in subset\n", name); return; } if (nota == NULL) ctxt->valid = 0; if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc, nota);}/** * unparsedEntityDecl: * @ctx: the user data (XML parser context) * @name: The name of the entity * @publicId: The public ID of the entity * @systemId: The system ID of the entity * @notationName: the name of the notation * * What to do when an unparsed entity declaration is parsed */voidunparsedEntityDecl(void *ctx, const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId, const xmlChar *notationName){ 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);}/** * setDocumentLocator: * @ctx: the user data (XML parser context) * @loc: A SAX Locator * * Receive the document locator at startup, actually xmlDefaultSAXLocator * Everything is available on the context, so this is useless in our case. */voidsetDocumentLocator(void *ctx, xmlSAXLocatorPtr loc){ /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */#ifdef DEBUG_SAX fprintf(stderr, "SAX.setDocumentLocator()\n");#endif}/** * startDocument: * @ctx: the user data (XML parser context) * * called when the document start being processed. */voidstartDocument(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; 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; }}/** * endDocument: * @ctx: the user data (XML parser context) * * called when the document end has been detected. */voidendDocument(void *ctx){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;#ifdef DEBUG_SAX fprintf(stderr, "SAX.endDocument()\n");#endif if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);}/** * attribute: * @ctx: the user data (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. */voidattribute(void *ctx, const xmlChar *fullname, const xmlChar *value){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlAttrPtr ret; xmlChar *name; xmlChar *ns; xmlChar *nval; xmlNsPtr namespace;/****************#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(ctxt, fullname, &ns); /* * Do the last stave of the attribute normalization */ nval = xmlValidNormalizeAttributeValue(ctxt->myDoc, ctxt->node, fullname, value); if (nval != NULL) value = nval; /* * 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) xmlFree(name); if (nval != NULL) xmlFree(nval); return; } if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { /* * Validate also for namespace decls, they are attributes from * an XML-1.0 perspective TODO ... doesn't map well with current API if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value); */ /* a standard namespace definition */ xmlNewNs(ctxt->node, value, name); xmlFree(ns); if (name != NULL) xmlFree(name); if (nval != NULL) xmlFree(nval); return; } if (ns != NULL) namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns); else { namespace = NULL; } /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */ ret = xmlNewNsProp(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 { ret->children = xmlNewDocText(ctxt->myDoc, value); ret->last = ret->children; if (ret->children != NULL) ret->children->parent = (xmlNodePtr) ret; } } if (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 { 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 { /* * 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); else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret); } if (nval != NULL) xmlFree(nval); if (name != NULL) xmlFree(name); if (ns != NULL) xmlFree(ns);}/** * startElement: * @ctx: the user data (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. */voidstartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNodePtr ret; xmlNodePtr parent = ctxt->node; xmlNsPtr ns; xmlChar *name; xmlChar *prefix; const xmlChar *att; const xmlChar *value; int i;#ifdef DEBUG_SAX fprintf(stderr, "SAX.startElement(%s)\n", fullname);#endif /* * First check on validity: */ if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) && ((ctxt->myDoc->intSubset == NULL) || ((ctxt->myDoc->intSubset->notations == NULL) && (ctxt->myDoc->intSubset->elements == NULL) && (ctxt->myDoc->intSubset->attributes == NULL) && (ctxt->myDoc->intSubset->entities == NULL)))) { if (ctxt->vctxt.error != NULL) { ctxt->vctxt.error(ctxt->vctxt.userData, "Validation failed: no DTD found !\n"); } ctxt->validate = 0; } /* * Split the full name into a namespace prefix and the tag name */ name = xmlSplitQName(ctxt, 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->children == NULL) {#ifdef DEBUG_SAX_TREE fprintf(stderr, "Setting %s as root\n", name);#endif xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); } else if (parent == NULL) { parent = ctxt->myDoc->children; } /* * 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) { 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); } } /* * If it's the Document root, finish the Dtd validation and * check the document root element for validity */ if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) { ctxt->valid &= xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); ctxt->vctxt.finishDtd = 1; } /* * 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)) { 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 */ 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) xmlFree(prefix); if (name != NULL) xmlFree(name);}/** * endElement: * @ctx: the user data (XML parser context) * @name: The element name * * called when the end of an element has been detected. */voidendElement(void *ctx, const xmlChar *name){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlParserNodeInfo node_info; xmlNodePtr cur = ctxt->node;#ifdef DEBUG_SAX 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); } if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur); /* * end of parsing of this node. */#ifdef DEBUG_SAX_TREE fprintf(stderr, "popping(%s)\n", cur->name);#endif nodePop(ctxt);}/** * reference: * @ctx: the user data (XML parser context) * @name: The entity name * * called when an entity reference is detected. */voidreference(void *ctx, const xmlChar *name){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNodePtr ret;#ifdef DEBUG_SAX fprintf(stderr, "SAX.reference(%s)\n", name);#endif if (name[0] == '#') ret = xmlNewCharRef(ctxt->myDoc, name); else ret = xmlNewReference(ctxt->myDoc, name);#ifdef DEBUG_SAX_TREE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -