📄 xinclude.c.svn-base
字号:
xmlChar *URL; xmlChar *fragment = NULL; xmlChar *href; xmlChar *parse; xmlChar *base; xmlChar *URI; int xml = 1, i; /* default Issue 64 */ int local = 0; if (ctxt == NULL) return(-1); if (cur == NULL) return(-1);#ifdef DEBUG_XINCLUDE xmlGenericError(xmlGenericErrorContext, "Add node\n");#endif /* * read the attributes */ href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF); if (href == NULL) { href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */ if (href == NULL) return(-1); local = 1; } if (href[0] == '#') local = 1; parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE); if (parse != NULL) { if (xmlStrEqual(parse, XINCLUDE_PARSE_XML)) xml = 1; else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT)) xml = 0; else { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE, "invalid value %s for 'parse'\n", parse); if (href != NULL) xmlFree(href); if (parse != NULL) xmlFree(parse); return(-1); } } /* * compute the URI */ base = xmlNodeGetBase(ctxt->doc, cur); if (base == NULL) { URI = xmlBuildURI(href, ctxt->doc->URL); } else { URI = xmlBuildURI(href, base); } if (URI == NULL) { xmlChar *escbase; xmlChar *eschref; /* * Some escaping may be needed */ escbase = xmlURIEscape(base); eschref = xmlURIEscape(href); URI = xmlBuildURI(eschref, escbase); if (escbase != NULL) xmlFree(escbase); if (eschref != NULL) xmlFree(eschref); } if (parse != NULL) xmlFree(parse); if (href != NULL) xmlFree(href); if (base != NULL) xmlFree(base); if (URI == NULL) { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI, "failed build URL\n", NULL); return(-1); } fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER); /* * Check the URL and remove any fragment identifier */ uri = xmlParseURI((const char *)URI); if (uri == NULL) { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", URI); if (fragment != NULL) xmlFree(fragment); xmlFree(URI); return(-1); } if (uri->fragment != NULL) { if (ctxt->legacy != 0) { if (fragment == NULL) { fragment = (xmlChar *) uri->fragment; } else { xmlFree(uri->fragment); } } else { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_FRAGMENT_ID, "Invalid fragment identifier in URI %s use the xpointer attribute\n", URI); if (fragment != NULL) xmlFree(fragment); xmlFreeURI(uri); xmlFree(URI); return(-1); } uri->fragment = NULL; } URL = xmlSaveUri(uri); xmlFreeURI(uri); xmlFree(URI); if (URL == NULL) { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", URI); if (fragment != NULL) xmlFree(fragment); return(-1); } /* * Check the URL against the stack for recursions */ if (!local) { for (i = 0;i < ctxt->urlNr;i++) { if (xmlStrEqual(URL, ctxt->urlTab[i])) { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION, "detected a recursion in %s\n", URL); return(-1); } } } ref = xmlXIncludeNewRef(ctxt, URL, cur); if (ref == NULL) { return(-1); } ref->fragment = fragment; ref->doc = NULL; ref->xml = xml; ref->count = 1; xmlFree(URL); return(0);}/** * xmlXIncludeRecurseDoc: * @ctxt: the XInclude context * @doc: the new document * @url: the associated URL * * The XInclude recursive nature is handled at this point. */static voidxmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, const xmlURL url ATTRIBUTE_UNUSED) { xmlXIncludeCtxtPtr newctxt; int i; /* * Avoid recursion in already substitued resources for (i = 0;i < ctxt->urlNr;i++) { if (xmlStrEqual(doc->URL, ctxt->urlTab[i])) return; } */#ifdef DEBUG_XINCLUDE xmlGenericError(xmlGenericErrorContext, "Recursing in doc %s\n", doc->URL);#endif /* * Handle recursion here. */ newctxt = xmlXIncludeNewContext(doc); if (newctxt != NULL) { /* * Copy the existing document set */ newctxt->incMax = ctxt->incMax; newctxt->incNr = ctxt->incNr; newctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(newctxt->incMax * sizeof(newctxt->incTab[0])); if (newctxt->incTab == NULL) { xmlXIncludeErrMemory(ctxt, (xmlNodePtr) doc, "processing doc"); xmlFree(newctxt); return; } /* * copy the urlTab */ newctxt->urlMax = ctxt->urlMax; newctxt->urlNr = ctxt->urlNr; newctxt->urlTab = ctxt->urlTab; /* * Inherit the documents already in use by other includes */ newctxt->incBase = ctxt->incNr; for (i = 0;i < ctxt->incNr;i++) { newctxt->incTab[i] = ctxt->incTab[i]; newctxt->incTab[i]->count++; /* prevent the recursion from freeing it */ } /* * The new context should also inherit the Parse Flags * (bug 132597) */ newctxt->parseFlags = ctxt->parseFlags; xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc)); for (i = 0;i < ctxt->incNr;i++) { newctxt->incTab[i]->count--; newctxt->incTab[i] = NULL; } /* urlTab may have been reallocated */ ctxt->urlTab = newctxt->urlTab; ctxt->urlMax = newctxt->urlMax; newctxt->urlMax = 0; newctxt->urlNr = 0; newctxt->urlTab = NULL; xmlXIncludeFreeContext(newctxt); }#ifdef DEBUG_XINCLUDE xmlGenericError(xmlGenericErrorContext, "Done recursing in doc %s\n", url);#endif}/** * xmlXIncludeAddTxt: * @ctxt: the XInclude context * @txt: the new text node * @url: the associated URL * * Add a new txtument to the list */static voidxmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) {#ifdef DEBUG_XINCLUDE xmlGenericError(xmlGenericErrorContext, "Adding text %s\n", url);#endif if (ctxt->txtMax == 0) { ctxt->txtMax = 4; ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax * sizeof(ctxt->txtTab[0])); if (ctxt->txtTab == NULL) { xmlXIncludeErrMemory(ctxt, NULL, "processing text"); return; } ctxt->txturlTab = (xmlURL *) xmlMalloc(ctxt->txtMax * sizeof(ctxt->txturlTab[0])); if (ctxt->txturlTab == NULL) { xmlXIncludeErrMemory(ctxt, NULL, "processing text"); return; } } if (ctxt->txtNr >= ctxt->txtMax) { ctxt->txtMax *= 2; ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab, ctxt->txtMax * sizeof(ctxt->txtTab[0])); if (ctxt->txtTab == NULL) { xmlXIncludeErrMemory(ctxt, NULL, "processing text"); return; } ctxt->txturlTab = (xmlURL *) xmlRealloc(ctxt->txturlTab, ctxt->txtMax * sizeof(ctxt->txturlTab[0])); if (ctxt->txturlTab == NULL) { xmlXIncludeErrMemory(ctxt, NULL, "processing text"); return; } } ctxt->txtTab[ctxt->txtNr] = txt; ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url); ctxt->txtNr++;}/************************************************************************ * * * Node copy with specific semantic * * * ************************************************************************//** * xmlXIncludeCopyNode: * @ctxt: the XInclude context * @target: the document target * @source: the document source * @elem: the element * * Make a copy of the node while preserving the XInclude semantic * of the Infoset copy */static xmlNodePtrxmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, xmlDocPtr source, xmlNodePtr elem) { xmlNodePtr result = NULL; if ((ctxt == NULL) || (target == NULL) || (source == NULL) || (elem == NULL)) return(NULL); if (elem->type == XML_DTD_NODE) return(NULL); result = xmlDocCopyNode(elem, target, 1); return(result);}/** * xmlXIncludeCopyNodeList: * @ctxt: the XInclude context * @target: the document target * @source: the document source * @elem: the element list * * Make a copy of the node list while preserving the XInclude semantic * of the Infoset copy */static xmlNodePtrxmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, xmlDocPtr source, xmlNodePtr elem) { xmlNodePtr cur, res, result = NULL, last = NULL; if ((ctxt == NULL) || (target == NULL) || (source == NULL) || (elem == NULL)) return(NULL); cur = elem; while (cur != NULL) { res = xmlXIncludeCopyNode(ctxt, target, source, cur); if (res != NULL) { if (result == NULL) { result = last = res; } else { last->next = res; res->prev = last; last = res; } } cur = cur->next; } return(result);}/** * xmlXIncludeGetNthChild: * @cur: the node * @no: the child number * * Returns the @n'th element child of @cur or NULL */static xmlNodePtrxmlXIncludeGetNthChild(xmlNodePtr cur, int no) { int i; if (cur == NULL) return(cur); cur = cur->children; for (i = 0;i <= no;cur = cur->next) { if (cur == NULL) return(cur); if ((cur->type == XML_ELEMENT_NODE) || (cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_HTML_DOCUMENT_NODE)) { i++; if (i == no) break; } } return(cur);}xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); /* in xpointer.c *//** * xmlXIncludeCopyRange: * @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. * * Returns an xmlNodePtr list or NULL. * The caller has to free the node tree. */static xmlNodePtrxmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, xmlDocPtr source, xmlXPathObjectPtr range) { /* pointers to generated nodes */ xmlNodePtr list = NULL, last = NULL, listParent = NULL; xmlNodePtr tmp, tmp2; /* pointers to traversal nodes */ xmlNodePtr start, cur, end; int index1, index2; int level = 0, lastLevel = 0, endLevel = 0, endFlag = 0; if ((ctxt == NULL) || (target == NULL) || (source == NULL) || (range == NULL)) return(NULL); if (range->type != XPATH_RANGE) return(NULL); start = (xmlNodePtr) range->user; if (start == NULL) return(NULL); end = range->user2; if (end == NULL) return(xmlDocCopyNode(start, target, 1)); cur = start; index1 = range->index; index2 = range->index2; /* * level is depth of the current node under consideration * list is the pointer to the root of the output tree * listParent is a pointer to the parent of output tree (within the included file) in case we need to add another level * last is a pointer to the last node added to the output tree * lastLevel is the depth of last (relative to the root) */ while (cur != NULL) { /* * Check if our output tree needs a parent */ if (level < 0) { while (level < 0) { /* copy must include namespaces and properties */ tmp2 = xmlDocCopyNode(listParent, target, 2); xmlAddChild(tmp2, list); list = tmp2; listParent = listParent->parent; level++; } last = list; lastLevel = 0; } /* * Check whether we need to change our insertion point */ while (level < lastLevel) { last = last->parent; lastLevel --; } if (cur == end) { /* Are we at the end of the range? */ if (cur->type == XML_TEXT_NODE) { const xmlChar *content = cur->content; int len; if (content == NULL) { tmp = xmlNewTextLen(NULL, 0); } else { len = index2; if ((cur == start) && (index1 > 1)) { content += (index1 - 1); len -= (index1 - 1); index1 = 0; } else { len = index2; } tmp = xmlNewTextLen(content, len); } /* single sub text node selection */ if (list == NULL) return(tmp); /* prune and return full set */ if (level == lastLevel) xmlAddNextSibling(last, tmp); else xmlAddChild(last, tmp); return(list); } else { /* ending node not a text node */ endLevel = level; /* remember the level of the end node */ endFlag = 1; /* last node - need to take care of properties + namespaces */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -