📄 xinclude.c
字号:
/* * Now gather the remaining nodes from cur to end */ continue; /* while */ } } else if (cur == start) { /* Not at the end, are we at start? */ if ((cur->type == XML_TEXT_NODE) || (cur->type == XML_CDATA_SECTION_NODE)) { const xmlChar *content = cur->content; if (content == NULL) { tmp = xmlNewTextLen(NULL, 0); } else { if (index1 > 1) { content += (index1 - 1); index1 = 0; } tmp = xmlNewText(content); } last = list = tmp; listParent = cur->parent; } else { /* Not text node */ /* * start of the range - need to take care of * properties and namespaces */ tmp = xmlDocCopyNode(cur, target, 2); list = last = tmp; listParent = cur->parent; if (index1 > 1) { /* Do we need to position? */ cur = xmlXIncludeGetNthChild(cur, index1 - 1); level = lastLevel = 1; index1 = 0; /* * Now gather the remaining nodes from cur to end */ continue; /* while */ } } } else { tmp = NULL; switch (cur->type) { case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_NODE: /* Do not copy DTD informations */ break; case XML_ENTITY_DECL: /* handle crossing entities -> stack needed */ break; case XML_XINCLUDE_START: case XML_XINCLUDE_END: /* don't consider it part of the tree content */ break; case XML_ATTRIBUTE_NODE: /* Humm, should not happen ! */ break; default: /* * Middle of the range - need to take care of * properties and namespaces */ tmp = xmlDocCopyNode(cur, target, 2); break; } if (tmp != NULL) { if (level == lastLevel) xmlAddNextSibling(last, tmp); else { xmlAddChild(last, tmp); lastLevel = level; } last = tmp; } } /* * Skip to next node in document order */ cur = xmlXPtrAdvanceNode(cur, &level); if (endFlag && (level >= endLevel)) break; } return(list);}/** * xmlXIncludeBuildNodeList: * @ctxt: the XInclude context * @target: the document target * @source: the document source * @obj: the XPointer result from the evaluation. * * Build a node list tree copy of the XPointer result. * This will drop Attributes and Namespace declarations. * * Returns an xmlNodePtr list or NULL. * the caller has to free the node tree. */static xmlNodePtrxmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, xmlDocPtr source, xmlXPathObjectPtr obj) { xmlNodePtr list = NULL, last = NULL; int i; if (source == NULL) source = ctxt->doc; if ((ctxt == NULL) || (target == NULL) || (source == NULL) || (obj == NULL)) return(NULL); switch (obj->type) { case XPATH_NODESET: { xmlNodeSetPtr set = obj->nodesetval; if (set == NULL) return(NULL); for (i = 0;i < set->nodeNr;i++) { if (set->nodeTab[i] == NULL) continue; switch (set->nodeTab[i]->type) { case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ELEMENT_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE:#ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE:#endif case XML_XINCLUDE_END: break; case XML_XINCLUDE_START: { xmlNodePtr tmp, cur = set->nodeTab[i]; cur = cur->next; while (cur != NULL) { switch(cur->type) { case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ELEMENT_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: tmp = xmlXIncludeCopyNode(ctxt, target, source, cur); if (last == NULL) { list = last = tmp; } else { xmlAddNextSibling(last, tmp); last = tmp; } cur = cur->next; continue; default: break; } break; } continue; } case XML_ATTRIBUTE_NODE: case XML_NAMESPACE_DECL: case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_FRAG_NODE: case XML_NOTATION_NODE: case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: continue; /* for */ } if (last == NULL) list = last = xmlXIncludeCopyNode(ctxt, target, source, set->nodeTab[i]); else { xmlAddNextSibling(last, xmlXIncludeCopyNode(ctxt, target, source, set->nodeTab[i])); if (last->next != NULL) last = last->next; } } break; } case XPATH_LOCATIONSET: { xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user; if (set == NULL) return(NULL); for (i = 0;i < set->locNr;i++) { if (last == NULL) list = last = xmlXIncludeCopyXPointer(ctxt, target, source, set->locTab[i]); else xmlAddNextSibling(last, xmlXIncludeCopyXPointer(ctxt, target, source, set->locTab[i])); if (last != NULL) { while (last->next != NULL) last = last->next; } } break; }#ifdef LIBXML_XPTR_ENABLED case XPATH_RANGE: return(xmlXIncludeCopyRange(ctxt, target, source, obj));#endif case XPATH_POINT: /* points are ignored in XInclude */ break; default: break; } return(list);}/************************************************************************ * * * XInclude I/O handling * * * ************************************************************************/typedef struct _xmlXIncludeMergeData xmlXIncludeMergeData;typedef xmlXIncludeMergeData *xmlXIncludeMergeDataPtr;struct _xmlXIncludeMergeData { xmlDocPtr doc; xmlXIncludeCtxtPtr ctxt;};/** * xmlXIncludeMergeOneEntity: * @ent: the entity * @doc: the including doc * @nr: the entity name * * Inplements the merge of one entity */static voidxmlXIncludeMergeEntity(xmlEntityPtr ent, xmlXIncludeMergeDataPtr data, xmlChar *name ATTRIBUTE_UNUSED) { xmlEntityPtr ret, prev; xmlDocPtr doc; xmlXIncludeCtxtPtr ctxt; if ((ent == NULL) || (data == NULL)) return; ctxt = data->ctxt; doc = data->doc; if ((ctxt == NULL) || (doc == NULL)) return; switch (ent->etype) { case XML_INTERNAL_PARAMETER_ENTITY: case XML_EXTERNAL_PARAMETER_ENTITY: case XML_INTERNAL_PREDEFINED_ENTITY: return; case XML_INTERNAL_GENERAL_ENTITY: case XML_EXTERNAL_GENERAL_PARSED_ENTITY: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: break; } ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID, ent->SystemID, ent->content); if (ret != NULL) { if (ent->URI != NULL) ret->URI = xmlStrdup(ent->URI); } else { prev = xmlGetDocEntity(doc, ent->name); if (prev != NULL) { if (ent->etype != prev->etype) goto error; if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) { if (!xmlStrEqual(ent->SystemID, prev->SystemID)) goto error; } else if ((ent->ExternalID != NULL) && (prev->ExternalID != NULL)) { if (!xmlStrEqual(ent->ExternalID, prev->ExternalID)) goto error; } else if ((ent->content != NULL) && (prev->content != NULL)) { if (!xmlStrEqual(ent->content, prev->content)) goto error; } else { goto error; } } } return;error: switch (ent->etype) { case XML_INTERNAL_PARAMETER_ENTITY: case XML_EXTERNAL_PARAMETER_ENTITY: case XML_INTERNAL_PREDEFINED_ENTITY: case XML_INTERNAL_GENERAL_ENTITY: case XML_EXTERNAL_GENERAL_PARSED_ENTITY: return; case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: break; } xmlXIncludeErr(ctxt, (xmlNodePtr) ent, XML_XINCLUDE_ENTITY_DEF_MISMATCH, "mismatch in redefinition of entity %s\n", ent->name);}/** * xmlXIncludeMergeEntities: * @ctxt: an XInclude context * @doc: the including doc * @from: the included doc * * Inplements the entity merge * * Returns 0 if merge succeeded, -1 if some processing failed */static intxmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlDocPtr from) { xmlNodePtr cur; xmlDtdPtr target, source; if (ctxt == NULL) return(-1); if ((from == NULL) || (from->intSubset == NULL)) return(0); target = doc->intSubset; if (target == NULL) { cur = xmlDocGetRootElement(doc); if (cur == NULL) return(-1); target = xmlCreateIntSubset(doc, cur->name, NULL, NULL); if (target == NULL) return(-1); } source = from->intSubset; if ((source != NULL) && (source->entities != NULL)) { xmlXIncludeMergeData data; data.ctxt = ctxt; data.doc = doc; xmlHashScan((xmlHashTablePtr) source->entities, (xmlHashScanner) xmlXIncludeMergeEntity, &data); } source = from->extSubset; if ((source != NULL) && (source->entities != NULL)) { xmlXIncludeMergeData data; data.ctxt = ctxt; data.doc = doc; /* * don't duplicate existing stuff when external subsets are the same */ if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) && (!xmlStrEqual(target->SystemID, source->SystemID))) { xmlHashScan((xmlHashTablePtr) source->entities, (xmlHashScanner) xmlXIncludeMergeEntity, &data); } } return(0);}/** * xmlXIncludeLoadDoc: * @ctxt: the XInclude context * @url: the associated URL * @nr: the xinclude node number * * Load the document, and store the result in the XInclude context * * Returns 0 in case of success, -1 in case of failure */static intxmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { xmlDocPtr doc; xmlURIPtr uri; xmlChar *URL; xmlChar *fragment = NULL; int i = 0;#ifdef LIBXML_XPTR_ENABLED int saveFlags;#endif#ifdef DEBUG_XINCLUDE xmlGenericError(xmlGenericErrorContext, "Loading doc %s:%d\n", url, nr);#endif /* * Check the URL and remove any fragment identifier */ uri = xmlParseURI((const char *)url); if (uri == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", url); return(-1); } if (uri->fragment != NULL) { fragment = (xmlChar *) uri->fragment; uri->fragment = NULL; } if ((ctxt->incTab != NULL) && (ctxt->incTab[nr] != NULL) && (ctxt->incTab[nr]->fragment != NULL)) { if (fragment != NULL) xmlFree(fragment); fragment = xmlStrdup(ctxt->incTab[nr]->fragment); } URL = xmlSaveUri(uri); xmlFreeURI(uri); if (URL == NULL) { if (ctxt->incTab != NULL) xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", url); else xmlXIncludeErr(ctxt, NULL, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", url); if (fragment != NULL) xmlFree(fragment); return(-1); } /* * Handling of references to the local document are done * directly through ctxt->doc. */ if ((URL[0] == 0) || (URL[0] == '#') || ((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) { doc = NULL; goto loaded; } /* * Prevent reloading twice the document. */ for (i = 0; i < ctxt->incNr; i++) { if ((xmlStrEqual(URL, ctxt->incTab[i]->URI)) && (ctxt->incTab[i]->doc != NULL)) { doc = ctxt->incTab[i]->doc;#ifdef DEBUG_XINCLUDE printf("Already loaded %s\n", URL);#endif goto loaded; } } /* * Load it. */#ifdef DEBUG_XINCLUDE printf("loading %s\n", URL);#endif#ifdef LIBXML_XPTR_ENABLED /* * If this is an XPointer evaluation, we want to assure that * all entities have been resolved prior to processing the * referenced document */ saveFlags = ctxt->parseFlags; if (fragment != NULL) { /* if this is an XPointer eval */ ctxt->parseFlags |= XML_PARSE_NOENT; }#endif doc = xmlXIncludeParseFile(ctxt, (const char *)URL);#ifdef LIBXML_XPTR_ENABLED ctxt->parseFlags = saveFlags;#endif if (doc == NULL) { xmlFree(URL); if (fragment != NULL) xmlFree(fragment); return(-1); } ctxt->incTab[nr]->doc = doc; /* * It's possible that the requested URL has been mapped to a * completely different location (e.g. through a catalog entry). * To check for this, we compare the URL with that of the doc * and change it if they disagree (bug 146988). */ if (!xmlStrEqual(URL, doc->URL)) { xmlFree(URL); URL = xmlStrdup(doc->URL); } for (i = nr + 1; i < ctxt->incNr; i++) { if (xmlStrEqual(URL, ctxt->incTab[i]->URI)) { ctxt->incTab[nr]->count++;#ifdef DEBUG_XINCLUDE printf("Increasing %s count since reused\n", URL);#endif break; } } /* * Make sure we have all entities fixed up */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -