/* * imports.c: Implementation of the XSLT imports * * Reference: * http://www.w3.org/TR/1999/REC-xslt-19991116 * * See Copyright for the status of this software. * * daniel@veillard.com */ #define IN_LIBXSLT #include "libxslt.h" #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_MATH_H #include #endif #ifdef HAVE_FLOAT_H #include #endif #ifdef HAVE_IEEEFP_H #include #endif #ifdef HAVE_NAN_H #include #endif #ifdef HAVE_CTYPE_H #include #endif #include #include #include #include #include #include "xslt.h" #include "xsltInternals.h" #include "xsltutils.h" #include "imports.h" #include "documents.h" #include "security.h" /************************************************************************ * * * Module interfaces * * * ************************************************************************/ /** * xsltParseStylesheetImport: * @style: the XSLT stylesheet * @cur: the import element * * parse an XSLT stylesheet import element * * Returns 0 in case of success -1 in case of failure. */ int xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) { int ret = -1; xmlDocPtr import = NULL; xmlChar *base = NULL; xmlChar *uriRef = NULL; xmlChar *URI = NULL; xsltStylesheetPtr res; xsltSecurityPrefsPtr sec; if ((cur == NULL) || (style == NULL)) return (ret); uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE); if (uriRef == NULL) { xsltTransformError(NULL, style, cur, "xsl:import : missing href attribute\n"); goto error; } base = xmlNodeGetBase(style->doc, cur); URI = xmlBuildURI(uriRef, base); if (URI == NULL) { xsltTransformError(NULL, style, cur, "xsl:import : invalid URI reference %s\n", uriRef); goto error; } /* * Security framework check */ sec = xsltGetDefaultSecurityPrefs(); if (sec != NULL) { int secres; secres = xsltCheckRead(sec, NULL, URI); if (secres == 0) { xsltTransformError(NULL, NULL, NULL, "xsl:import: read rights for %s denied\n", URI); goto error; } } import = xmlParseFile((const char *)URI); if (import == NULL) { xsltTransformError(NULL, style, cur, "xsl:import : unable to load %s\n", URI); goto error; } res = xsltParseStylesheetImportedDoc(import); if (res != NULL) { res->parent = style; res->next = style->imports; style->imports = res; style->extrasNr += res->extrasNr; ret = 0; } else { xmlFreeDoc(import); } error: if (uriRef != NULL) xmlFree(uriRef); if (base != NULL) xmlFree(base); if (URI != NULL) xmlFree(URI); return (ret); } /** * xsltParseStylesheetInclude: * @style: the XSLT stylesheet * @cur: the include node * * parse an XSLT stylesheet include element * * Returns 0 in case of success -1 in case of failure */ int xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) { int ret = -1; xmlDocPtr oldDoc; xmlChar *base = NULL; xmlChar *uriRef = NULL; xmlChar *URI = NULL; xsltDocumentPtr include; if ((cur == NULL) || (style == NULL)) return (ret); uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE); if (uriRef == NULL) { xsltTransformError(NULL, style, cur, "xsl:include : missing href attribute\n"); goto error; } base = xmlNodeGetBase(style->doc, cur); URI = xmlBuildURI(uriRef, base); if (URI == NULL) { xsltTransformError(NULL, style, cur, "xsl:include : invalid URI reference %s\n", uriRef); goto error; } include = xsltLoadStyleDocument(style, URI); if (include == NULL) { xsltTransformError(NULL, style, cur, "xsl:include : unable to load %s\n", URI); goto error; } oldDoc = style->doc; style->doc = include->doc; ret = (int)xsltParseStylesheetProcess(style, include->doc); style->doc = oldDoc; if (ret == 0) { ret = -1; goto error; } ret = 0; error: if (uriRef != NULL) xmlFree(uriRef); if (base != NULL) xmlFree(base); if (URI != NULL) xmlFree(URI); return (ret); } /** * xsltNextImport: * @cur: the current XSLT stylesheet * * Find the next stylesheet in import precedence. * * Returns the next stylesheet or NULL if it was the last one */ xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur) { if (cur == NULL) return(NULL); if (cur->imports != NULL) return(cur->imports); if (cur->next != NULL) return(cur->next) ; do { cur = cur->parent; if (cur == NULL) return(NULL); if (cur->next != NULL) return(cur->next); } while (cur != NULL); return(cur); } /** * xsltNeedElemSpaceHandling: * @ctxt: an XSLT transformation context * * Checks whether that stylesheet requires white-space stripping * * Returns 1 if space should be stripped, 0 if not */ int xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt) { xsltStylesheetPtr style; if (ctxt == NULL) return(0); style = ctxt->style; while (style != NULL) { if (style->stripSpaces != NULL) return(1); style = xsltNextImport(style); } return(0); } /** * xsltFindElemSpaceHandling: * @ctxt: an XSLT transformation context * @node: an XML node * * Find strip-space or preserve-space informations for an element * respect the import precedence or the wildcards * * Returns 1 if space should be stripped, 0 if not, and 2 if everything * should be CDTATA wrapped. */ int xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) { xsltStylesheetPtr style; const xmlChar *val; if ((ctxt == NULL) || (node == NULL)) return(0); style = ctxt->style; while (style != NULL) { if (node->ns != NULL) { val = (const xmlChar *) xmlHashLookup2(style->stripSpaces, node->name, node->ns->href); } else { val = (const xmlChar *) xmlHashLookup2(style->stripSpaces, node->name, NULL); } if (val != NULL) { if (xmlStrEqual(val, (xmlChar *) "strip")) return(1); if (xmlStrEqual(val, (xmlChar *) "preserve")) return(0); } if (style->stripAll == 1) return(1); if (style->stripAll == -1) return(0); style = xsltNextImport(style); } return(0); } /** * xsltFindTemplate: * @ctxt: an XSLT transformation context * @name: the template name * @nameURI: the template name URI * * Finds the named template, apply import precedence rule. * * Returns the xsltTemplatePtr or NULL if not found */ xsltTemplatePtr xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI) { xsltTemplatePtr cur; xsltStylesheetPtr style; if ((ctxt == NULL) || (name == NULL)) return(NULL); style = ctxt->style; while (style != NULL) { cur = style->templates; while (cur != NULL) { if (xmlStrEqual(name, cur->name)) { if (((nameURI == NULL) && (cur->nameURI == NULL)) || ((nameURI != NULL) && (cur->nameURI != NULL) && (xmlStrEqual(nameURI, cur->nameURI)))) { return(cur); } } cur = cur->next; } style = xsltNextImport(style); } return(NULL); }