📄 xinclude.c.svn-base
字号:
* 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; 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 */ xmlXIncludeMergeEntities(ctxt, ctxt->doc, doc); /* * We don't need the DTD anymore, free up space if (doc->intSubset != NULL) { xmlUnlinkNode((xmlNodePtr) doc->intSubset); xmlFreeNode((xmlNodePtr) doc->intSubset); doc->intSubset = NULL; } if (doc->extSubset != NULL) { xmlUnlinkNode((xmlNodePtr) doc->extSubset); xmlFreeNode((xmlNodePtr) doc->extSubset); doc->extSubset = NULL; } */ xmlXIncludeRecurseDoc(ctxt, doc, URL);loaded: if (fragment == NULL) { /* * Add the top children list as the replacement copy. */ if (doc == NULL) { /* Hopefully a DTD declaration won't be copied from * the same document */ ctxt->incTab[nr]->inc = xmlCopyNodeList(ctxt->doc->children); } else { ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc, doc, doc->children); } } #ifdef LIBXML_XPTR_ENABLED else { /* * Computes the XPointer expression and make a copy used * as the replacement copy. */ xmlXPathObjectPtr xptr; xmlXPathContextPtr xptrctxt; xmlNodeSetPtr set; if (doc == NULL) { xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr]->ref, NULL); } else { xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); } if (xptrctxt == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_FAILED, "could not create XPointer context\n", NULL); xmlFree(URL); xmlFree(fragment); return(-1); } xptr = xmlXPtrEval(fragment, xptrctxt); if (xptr == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_FAILED, "XPointer evaluation failed: #%s\n", fragment); xmlXPathFreeContext(xptrctxt); xmlFree(URL); xmlFree(fragment); return(-1); } switch (xptr->type) { case XPATH_UNDEFINED: case XPATH_BOOLEAN: case XPATH_NUMBER: case XPATH_STRING: case XPATH_POINT: case XPATH_USERS: case XPATH_XSLT_TREE: xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer is not a range: #%s\n", fragment); xmlXPathFreeContext(xptrctxt); xmlFree(URL); xmlFree(fragment); return(-1); case XPATH_NODESET: if ((xptr->nodesetval == NULL) || (xptr->nodesetval->nodeNr <= 0)) { xmlXPathFreeContext(xptrctxt); xmlFree(URL); xmlFree(fragment); return(-1); } case XPATH_RANGE: case XPATH_LOCATIONSET: break; } set = xptr->nodesetval; if (set != 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 continue; case XML_ATTRIBUTE_NODE: xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer selects an attribute: #%s\n", fragment); set->nodeTab[i] = NULL; continue; case XML_NAMESPACE_DECL: xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer selects a namespace: #%s\n", fragment); set->nodeTab[i] = NULL; continue; 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: case XML_XINCLUDE_START: case XML_XINCLUDE_END: xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_RESULT, "XPointer selects unexpected nodes: #%s\n", fragment); set->nodeTab[i] = NULL; set->nodeTab[i] = NULL; continue; /* for */ } } } if (doc == NULL) { ctxt->incTab[nr]->xptr = xptr; ctxt->incTab[nr]->inc = NULL; } else { ctxt->incTab[nr]->inc = xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr); xmlXPathFreeObject(xptr); } xmlXPathFreeContext(xptrctxt); xmlFree(fragment); }#endif /* * Do the xml:base fixup if needed */ if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/'))) { xmlNodePtr node; node = ctxt->incTab[nr]->inc; while (node != NULL) { if (node->type == XML_ELEMENT_NODE) xmlNodeSetBase(node, URL); node = node->next; } } if ((nr < ctxt->incNr) && (ctxt->incTab[nr]->doc != NULL) && (ctxt->incTab[nr]->count <= 1)) {#ifdef DEBUG_XINCLUDE printf("freeing %s\n", ctxt->incTab[nr]->doc->URL);#endif xmlFreeDoc(ctxt->incTab[nr]->doc); ctxt->incTab[nr]->doc = NULL; } xmlFree(URL); return(0);}/** * xmlXIncludeLoadTxt: * @ctxt: the XInclude context * @url: the associated URL * @nr: the xinclude node number * * Load the content, and store the result in the XInclude context * * Returns 0 in case of success, -1 in case of failure */static intxmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { xmlParserInputBufferPtr buf; xmlNodePtr node; xmlURIPtr uri; xmlChar *URL; int i; xmlChar *encoding = NULL; xmlCharEncoding enc = (xmlCharEncoding) 0; /* * 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) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT, "fragment identifier forbidden for text: %s\n", (const xmlChar *) uri->fragment); xmlFreeURI(uri); return(-1); } URL = xmlSaveUri(uri); xmlFreeURI(uri); if (URL == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI, "invalid value URI %s\n", url); return(-1); } /* * Handling of references to the local document are done * directly through ctxt->doc. */ if (URL[0] == 0) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_DOCUMENT, "text serialization of document not available\n", NULL); xmlFree(URL); return(-1); } /* * Prevent reloading twice the document. */ for (i = 0; i < ctxt->txtNr; i++) { if (xmlStrEqual(URL, ctxt->txturlTab[i])) { node = xmlCopyNode(ctxt->txtTab[i], 1); goto loaded; } } /* * Try to get the encoding if available */ if ((ctxt->incTab[nr] != NULL) && (ctxt->incTab[nr]->ref != NULL)) { encoding = xmlGetProp(ctxt->incTab[nr]->ref, XINCLUDE_PARSE_ENCODING); } if (encoding != NULL) { /* * TODO: we should not have to remap to the xmlCharEncoding * predefined set, a better interface than * xmlParserInputBufferCreateFilename should allow any * encoding supported by iconv */ enc = xmlParseCharEncoding((const char *) encoding); if (enc == XML_CHAR_ENCODING_ERROR) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_UNKNOWN_ENCODING, "encoding %s not supported\n", encoding); xmlFree(encoding); xmlFree(URL); return(-1); } xmlFree(encoding); } /* * Load it. */ buf = xmlParserInputBufferCreateFilename((const char *)URL, enc); if (buf == NULL) { xmlFree(URL); return(-1); } node = xmlNewText(NULL); /* * Scan all chars from the resource and add the to the node */ while (xmlParserInputBufferRead(buf, 128) > 0) { int len; const xmlChar *content; content = xmlBufferContent(buf->buffer); len = xmlBufferLength(buf->buffer); for (i = 0;i < len;) { int cur; int l; cur = xmlStringCurrentChar(NULL, &content[i], &l); if (!IS_CHAR(cur)) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_INVALID_CHAR, "%s contains invalid char\n", URL); } else { xmlNodeAddContentLen(node, &content[i], l); } i += l; } xmlBufferShrink(buf->buffer, len); } xmlFreeParserInputBuffer(buf); xmlXIncludeAddTxt(ctxt, node, URL);loaded: /* * Add the element as the replacement copy. */ ctxt->incTab[nr]->inc = node; xmlFree(URL); return(0);}/** * xmlXIncludeLoadFallback: * @ctxt: the XInclude context * @fallback: the fallback node * @nr: the xinclude node number * * Load the content of the fallback node, and store the result * in the XInclude context * * Returns 0 in case of success, -1 in case of failure */static intxmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) { xmlXIncludeCtxtPtr newctxt; int ret = 0; if ((fallback == NULL) || (ctxt == NULL)) return(-1); if (fallback->children != NULL) { /* * It's possible that the fallback also has 'includes' * (Bug 129969), so we re-process the fallback just in case */ newctxt = xmlXIncludeNewContext(ctxt->doc); if (newctxt == NULL) return (-1); xmlXIncludeSetFlags(newctxt, ctxt->parseFlags); ret = xmlXIncludeDoProcess(newctxt, ctxt->doc, fallback->children); if (ctxt->nbErrors > 0) ret = -1; else if (ret > 0) ret = 0; /* xmlXIncludeDoProcess can return +ve number */ xmlXIncludeFreeContext(newctxt); ctxt->incTab[nr]->inc = xmlCopyNodeList(fallback->children); } else { ctxt->incTab[nr]->inc = NULL; ctxt->incTab[nr]->emptyFb = 1; /* flag empty callback */ } return(ret);}/************************************************************************ * * * XInclude Processing * * * ************************************************************************//** * xmlXIncludePreProcessNode: * @ctxt: an XInclude context * @node: an XInclude node * * Implement the XInclude preprocessing, currently just adding the element * for further processing. * * Returns the result list or NULL in case of error */static xmlNodePtrxmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) { xmlXIncludeAddNode(ctxt, node); return(0);}/** * xmlXIncludeLoadNode: * @ctxt: an XInclude context * @nr: the node number * * Find and load the infoset replacement for the given node. * * Returns 0 if substitution succeeded, -1 if some processing failed */static intxmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { xmlNodePtr cur; xmlChar *href; xmlChar *parse; xmlChar *base; xmlChar *URI; int xml = 1; /* default Issue 64 */ int ret; if (ctxt == NULL) return(-1); if ((nr < 0) || (nr >= ctxt->incNr)) return(-1); cur = ctxt->incTab[nr]->ref; if (cur == NULL) return(-1); /* * 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); } 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, ctxt->incTab[nr]->ref, 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -