2 * imports.c: Implementation of the XSLT imports
5 * http://www.w3.org/TR/1999/REC-xslt-19991116
7 * See Copyright for the status of this software.
17 #ifdef HAVE_SYS_TYPES_H
18 #include <sys/types.h>
36 #include <libxml/xmlmemory.h>
37 #include <libxml/tree.h>
38 #include <libxml/hash.h>
39 #include <libxml/xmlerror.h>
40 #include <libxml/uri.h>
42 #include "xsltInternals.h"
43 #include "xsltutils.h"
45 #include "documents.h"
50 /************************************************************************
54 ************************************************************************/
57 * xsltParseStylesheetImport:
58 * @style: the XSLT stylesheet
59 * @cur: the import element
61 * parse an XSLT stylesheet import element
63 * Returns 0 in case of success -1 in case of failure.
67 xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
69 xmlDocPtr import = NULL;
71 xmlChar *uriRef = NULL;
73 xsltStylesheetPtr res;
74 xsltSecurityPrefsPtr sec;
76 if ((cur == NULL) || (style == NULL))
79 uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE);
81 xsltTransformError(NULL, style, cur,
82 "xsl:import : missing href attribute\n");
86 base = xmlNodeGetBase(style->doc, cur);
87 URI = xmlBuildURI(uriRef, base);
89 xsltTransformError(NULL, style, cur,
90 "xsl:import : invalid URI reference %s\n", uriRef);
98 if (xmlStrEqual(res->doc->URL, URI)) {
99 xsltTransformError(NULL, style, cur,
100 "xsl:import : recursion detected on imported URL %s\n", URI);
107 * Security framework check
109 sec = xsltGetDefaultSecurityPrefs();
113 secres = xsltCheckRead(sec, NULL, URI);
115 xsltTransformError(NULL, NULL, NULL,
116 "xsl:import: read rights for %s denied\n",
122 #ifdef XSLT_PARSE_OPTIONS
123 import = xmlReadFile((const char *) URI, NULL, XSLT_PARSE_OPTIONS);
125 import = xmlParseFile((const char *) URI);
127 if (import == NULL) {
128 xsltTransformError(NULL, style, cur,
129 "xsl:import : unable to load %s\n", URI);
133 res = xsltParseStylesheetImportedDoc(import, style);
135 res->next = style->imports;
136 style->imports = res;
137 xmlHashScan(res->templatesHash,
138 (xmlHashScanner) xsltNormalizeCompSteps, style);
139 style->extrasNr += res->extrasNr;
157 * xsltParseStylesheetInclude:
158 * @style: the XSLT stylesheet
159 * @cur: the include node
161 * parse an XSLT stylesheet include element
163 * Returns 0 in case of success -1 in case of failure
167 xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
170 xmlChar *base = NULL;
171 xmlChar *uriRef = NULL;
173 xsltDocumentPtr include;
174 xsltDocumentPtr docptr;
176 if ((cur == NULL) || (style == NULL))
179 uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE);
180 if (uriRef == NULL) {
181 xsltTransformError(NULL, style, cur,
182 "xsl:include : missing href attribute\n");
186 base = xmlNodeGetBase(style->doc, cur);
187 URI = xmlBuildURI(uriRef, base);
189 xsltTransformError(NULL, style, cur,
190 "xsl:include : invalid URI reference %s\n", uriRef);
195 * in order to detect recursion, we check all previously included
198 docptr = style->includes;
199 while (docptr != NULL) {
200 if (xmlStrEqual(docptr->doc->URL, URI)) {
201 xsltTransformError(NULL, style, cur,
202 "xsl:include : recursion detected on included URL %s\n", URI);
205 docptr = docptr->includes;
208 include = xsltLoadStyleDocument(style, URI);
209 if (include == NULL) {
210 xsltTransformError(NULL, style, cur,
211 "xsl:include : unable to load %s\n", URI);
216 style->doc = include->doc;
217 /* chain to stylesheet for recursion checking */
218 include->includes = style->includes;
219 style->includes = include;
220 ret = (int)xsltParseStylesheetProcess(style, include->doc);
221 style->includes = include->includes;
242 * @cur: the current XSLT stylesheet
244 * Find the next stylesheet in import precedence.
246 * Returns the next stylesheet or NULL if it was the last one
250 xsltNextImport(xsltStylesheetPtr cur) {
253 if (cur->imports != NULL)
254 return(cur->imports);
255 if (cur->next != NULL)
259 if (cur == NULL) return(NULL);
260 if (cur->next != NULL) return(cur->next);
261 } while (cur != NULL);
266 * xsltNeedElemSpaceHandling:
267 * @ctxt: an XSLT transformation context
269 * Checks whether that stylesheet requires white-space stripping
271 * Returns 1 if space should be stripped, 0 if not
275 xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt) {
276 xsltStylesheetPtr style;
281 while (style != NULL) {
282 if (style->stripSpaces != NULL)
284 style = xsltNextImport(style);
290 * xsltFindElemSpaceHandling:
291 * @ctxt: an XSLT transformation context
294 * Find strip-space or preserve-space informations for an element
295 * respect the import precedence or the wildcards
297 * Returns 1 if space should be stripped, 0 if not, and 2 if everything
298 * should be CDTATA wrapped.
302 xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) {
303 xsltStylesheetPtr style;
306 if ((ctxt == NULL) || (node == NULL))
309 while (style != NULL) {
310 if (node->ns != NULL) {
311 val = (const xmlChar *)
312 xmlHashLookup2(style->stripSpaces, node->name, node->ns->href);
314 val = (const xmlChar *)
315 xmlHashLookup2(style->stripSpaces, node->name, NULL);
318 if (xmlStrEqual(val, (xmlChar *) "strip"))
320 if (xmlStrEqual(val, (xmlChar *) "preserve"))
323 if (style->stripAll == 1)
325 if (style->stripAll == -1)
328 style = xsltNextImport(style);
335 * @ctxt: an XSLT transformation context
336 * @name: the template name
337 * @nameURI: the template name URI
339 * Finds the named template, apply import precedence rule.
341 * Returns the xsltTemplatePtr or NULL if not found
344 xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
345 const xmlChar *nameURI) {
347 xsltStylesheetPtr style;
349 if ((ctxt == NULL) || (name == NULL))
352 while (style != NULL) {
353 cur = style->templates;
354 while (cur != NULL) {
355 if (xmlStrEqual(name, cur->name)) {
356 if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
357 ((nameURI != NULL) && (cur->nameURI != NULL) &&
358 (xmlStrEqual(nameURI, cur->nameURI)))) {
365 style = xsltNextImport(style);