📄 sax2.c.svn-base
字号:
ret->children = tmp; ret->last = tmp; if (tmp != NULL) { tmp->doc = ret->doc; tmp->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) { dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend); if (dup == NULL) { if (*valueend == 0) { ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, value); } else { /* * That should already be normalized. * cheaper to finally allocate here than duplicate * entry points in the full validation code */ dup = xmlStrndup(value, valueend - value); ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, dup); } } else { /* * dup now contains a string of the flattened attribute * content with entities substitued. Check if we need to * apply an extra layer of normalization. * It need to be done twice ... it's an extra burden related * to the ability to keep references in attributes */ if (ctxt->attsSpecial != NULL) { xmlChar *nvalnorm; xmlChar fn[50]; xmlChar *fullname; fullname = xmlBuildQName(localname, prefix, fn, 50); if (fullname != NULL) { ctxt->vctxt.valid = 1; nvalnorm = xmlValidCtxtNormalizeAttributeValue( &ctxt->vctxt, ctxt->myDoc, ctxt->node, fullname, dup); if (ctxt->vctxt.valid != 1) ctxt->valid = 0; if ((fullname != fn) && (fullname != localname)) xmlFree(fullname); if (nvalnorm != NULL) { xmlFree(dup); dup = nvalnorm; } } } ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, dup); } } else { /* * if entities already have been substitued, then * the attribute as passed is already normalized */ dup = xmlStrndup(value, valueend - value); ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc, ctxt->node, ret, dup); } } 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 (xmlIsID(ctxt->myDoc, ctxt->node, ret)) { /* might be worth duplicate entry points and not copy */ if (dup == NULL) dup = xmlStrndup(value, valueend - value); xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) { if (dup == NULL) dup = xmlStrndup(value, valueend - value); xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret); } else if ((prefix == ctxt->str_xml) && (localname[0] == 'i') && (localname[1] == 'd') && (localname[2] == 0)) { /* * Add the xml:id value * * Open issue: normalization of the value. */ if (dup == NULL) dup = xmlStrndup(value, valueend - value); if (xmlValidateNCName(dup, 1) != 0) { xmlErrValid(ctxt, XML_DTD_XMLID_VALUE, "xml:id : attribute value %s is not an NCName\n", (const char *) dup, NULL); } xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret); } } if (dup != NULL) xmlFree(dup);}/** * xmlSAX2StartElementNs: * @ctx: the user data (XML parser context) * @localname: the local name of the element * @prefix: the element namespace prefix if available * @URI: the element namespace name if available * @nb_namespaces: number of namespace definitions on that node * @namespaces: pointer to the array of prefix/URI pairs namespace definitions * @nb_attributes: the number of attributes on that node * @nb_defaulted: the number of defaulted attributes. * @attributes: pointer to the array of (localname/prefix/URI/value/end) * attribute values. * * SAX2 callback when an element start has been detected by the parser. * It provides the namespace informations for the element, as well as * the new namespace declarations on the element. */voidxmlSAX2StartElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNodePtr ret; xmlNodePtr parent = ctxt->node; xmlNsPtr last = NULL, ns; const xmlChar *uri, *pref; int i, j; /* * 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)))) { xmlErrValid(ctxt, XML_ERR_NO_DTD, "Validation failed: no DTD found !", NULL, NULL); ctxt->validate = 0; } /* * allocate the node */ if (ctxt->freeElems != NULL) { ret = ctxt->freeElems; ctxt->freeElems = ret->next; ctxt->freeElemsNr--; memset(ret, 0, sizeof(xmlNode)); ret->type = XML_ELEMENT_NODE; if (ctxt->dictNames) ret->name = localname; else ret->name = xmlStrdup(localname); if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) xmlRegisterNodeDefaultValue(ret); } else { if (ctxt->dictNames) ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, (xmlChar *) localname, NULL); else ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL); if (ret == NULL) { ctxt->errNo = XML_ERR_NO_MEMORY; ctxt->instate = XML_PARSER_EOF; ctxt->disableSAX = 1; return; } } if (ctxt->linenumbers) { if (ctxt->input != NULL) { if (ctxt->input->line < 65535) ret->line = (short) ctxt->input->line; else ret->line = 65535; } } if (ctxt->myDoc->children == NULL) { xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret); } else if (parent == NULL) { parent = ctxt->myDoc->children; } /* * Build the namespace list */ for (i = 0,j = 0;j < nb_namespaces;j++) { pref = namespaces[i++]; uri = namespaces[i++]; ns = xmlNewNs(NULL, uri, pref); if (ns != NULL) { if (last == NULL) { ret->nsDef = last = ns; } else { last->next = ns; last = ns; } if ((URI != NULL) && (prefix == pref)) ret->ns = ns; } else { ctxt->errNo = XML_ERR_NO_MEMORY; ctxt->instate = XML_PARSER_EOF; ctxt->disableSAX = 1; return; }#ifdef LIBXML_VALID_ENABLED if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) { ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc, ret, prefix, ns, uri); }#endif /* LIBXML_VALID_ENABLED */ } ctxt->nodemem = -1; /* * We are parsing a new node. */ nodePush(ctxt, ret); /* * Link the child element */ if (parent != NULL) { if (parent->type == XML_ELEMENT_NODE) { xmlAddChild(parent, ret); } else { xmlAddSibling(parent, ret); } } /* * Insert the defaulted attributes from the DTD only if requested: */ if ((nb_defaulted != 0) && ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0)) nb_attributes -= nb_defaulted; /* * Search the namespace if it wasn't already found */ if ((URI != NULL) && (ret->ns == NULL)) { ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix); if (ret->ns == NULL) { ns = xmlNewNs(ret, NULL, prefix); if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) ctxt->sax->warning(ctxt->userData, "Namespace prefix %s was not found\n", prefix); } } /* * process all the other attributes */ if (nb_attributes > 0) { for (j = 0,i = 0;i < nb_attributes;i++,j+=5) { xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1], attributes[j+3], attributes[j+4]); } }#ifdef LIBXML_VALID_ENABLED /* * 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)) { int chk; chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); if (chk <= 0) ctxt->valid = 0; if (chk < 0) ctxt->wellFormed = 0; ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); ctxt->vctxt.finishDtd = 1; }#endif /* LIBXML_VALID_ENABLED */}/** * xmlSAX2EndElementNs: * @ctx: the user data (XML parser context) * @localname: the local name of the element * @prefix: the element namespace prefix if available * @URI: the element namespace name if available * * SAX2 callback when an element end has been detected by the parser. * It provides the namespace informations for the element. */voidxmlSAX2EndElementNs(void *ctx, const xmlChar * localname ATTRIBUTE_UNUSED, const xmlChar * prefix ATTRIBUTE_UNUSED, const xmlChar * URI ATTRIBUTE_UNUSED){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlParserNodeInfo node_info; xmlNodePtr cur = ctxt->node; /* Capture end position and add node */ if ((ctxt->record_info) && (cur != NULL)) { 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); } ctxt->nodemem = -1;#ifdef LIBXML_VALID_ENABLED if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc && ctxt->myDoc->intSubset) ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);#endif /* LIBXML_VALID_ENABLED */ /* * end of parsing of this node. */ nodePop(ctxt);}/** * xmlSAX2Reference: * @ctx: the user data (XML parser context) * @name: The entity name * * called when an entity xmlSAX2Reference is detected. */voidxmlSAX2Reference(void *ctx, const xmlChar *name){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNodePtr ret;#ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Reference(%s)\n", name);#endif if (name[0] == '#') ret = xmlNewCharRef(ctxt->myDoc, name); else ret = xmlNewReference(ctxt->myDoc, name);#ifdef DEBUG_SAX_TREE xmlGenericError(xmlGenericErrorContext, "add xmlSAX2Reference %s to %s \n", name, ctxt->node->name);#endif xmlAddChild(ctxt->node, ret);}/** * xmlSAX2Characters: * @ctx: the user data (XML parser context) * @ch: a xmlChar string * @len: the number of xmlChar * * receiving some chars from the parser. */voidxmlSAX2Characters(void *ctx, const xmlChar *ch, int len){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNodePtr lastChild;#ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len);#endif /* * Handle the data if any. If there is no child * add it as content, otherwise if the last child is text, * concatenate it, else create a new node of type text. */ if (ctxt->node == NULL) {#ifdef DEBUG_SAX_TREE xmlGenericError(xmlGenericErrorContext, "add chars: ctxt->node == NULL !\n");#endif return; } lastChild = ctxt->node->last;#ifdef DEBUG_SAX_TREE xmlGenericError(xmlGenericErrorContext, "add chars to %s \n", ctxt->node->name);#endif /* * Here we needed an accelerator mechanism in case of very large * elements. Use an attribute in the structure !!! */ if (lastChild == NULL) { lastChild = xmlSAX2TextNode(ctxt, ch, len); if (lastChild != NULL) { ctxt->node->children = lastChild; ctxt->node->last = lastChild; lastChild->parent = ctxt->node; lastChild->doc = ctxt->node->doc; ctxt->nodelen = len; ctxt->nodemem = len + 1; } } else { int coalesceText = (lastChild != NULL) && (lastChild->type == XML_TEXT_NODE) && (lastChild->name == xmlStringText); if ((coalesceText) && (ctxt->nodemem != 0)) { /* * The whole point of maintaining nodelen and nodemem, * xmlTextConcat is too costly, i.e. compute length, * reallocate a new buffer, move data, append ch. Here * We try to minimaze realloc() uses and avoid copying * and recomputing length over and over. */ if ((ctxt->nodemem == ctxt->nodelen + 1) && (xmlDictOwns(ctxt->dict, lastChild->content))) { lastChild->content = xmlStrdup(lastChild->content); } if (ctxt->nodelen + len >= ctxt->nodemem) { xmlChar *newbuf; int size; size = ctxt->nodemem + len; size *= 2; newbuf = (xmlChar *) xmlRealloc(lastChild->content,size); if (newbuf == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, "SAX.xmlSAX2Characters(): out of memory\n"); ctxt->errNo = XML_ERR_NO_MEMORY; ctxt->instate = XML_PARSER_EOF; ctxt->disableSAX = 1; return; } ctxt->nodemem = size; lastChild->content = newbuf; } m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -