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.
14 /************************************************************************
18 ************************************************************************/
20 * xsltFixImportedCompSteps:
21 * @master: the "master" stylesheet
22 * @style: the stylesheet being imported by the master
24 * normalize the comp steps for the stylesheet being imported
25 * by the master, together with any imports within that.
28 static void xsltFixImportedCompSteps(xsltStylesheetPtr master
,
29 xsltStylesheetPtr style
) {
30 xsltStylesheetPtr res
;
31 xmlHashScan(style
->templatesHash
, xsltNormalizeCompSteps
, master
);
32 master
->extrasNr
+= style
->extrasNr
;
33 for (res
= style
->imports
; res
!= NULL
; res
= res
->next
) {
34 xsltFixImportedCompSteps(master
, res
);
39 * xsltParseStylesheetImport:
40 * @style: the XSLT stylesheet
41 * @cur: the import element
43 * parse an XSLT stylesheet import element
45 * Returns 0 in case of success -1 in case of failure.
49 xsltParseStylesheetImport(xsltStylesheetPtr style
, xmlNodePtr cur
) {
51 xmlDocPtr import
= NULL
;
53 xmlChar
*uriRef
= NULL
;
55 xsltStylesheetPtr res
;
56 xsltSecurityPrefsPtr sec
;
58 if ((cur
== NULL
) || (style
== NULL
))
61 uriRef
= xmlGetNsProp(cur
, (const xmlChar
*)"href", NULL
);
63 xsltTransformError(NULL
, style
, cur
,
64 "xsl:import : missing href attribute\n");
68 base
= xmlNodeGetBase(style
->doc
, cur
);
69 URI
= xmlBuildURI(uriRef
, base
);
71 xsltTransformError(NULL
, style
, cur
,
72 "xsl:import : invalid URI reference %s\n", uriRef
);
80 if (xmlStrEqual(res
->doc
->URL
, URI
)) {
81 xsltTransformError(NULL
, style
, cur
,
82 "xsl:import : recursion detected on imported URL %s\n", URI
);
89 * Security framework check
91 sec
= xsltGetDefaultSecurityPrefs();
95 secres
= xsltCheckRead(sec
, NULL
, URI
);
97 xsltTransformError(NULL
, NULL
, NULL
,
98 "xsl:import: read rights for %s denied\n",
104 import
= xsltDocDefaultLoader(URI
, style
->dict
, XSLT_PARSE_OPTIONS
,
105 (void *) style
, XSLT_LOAD_STYLESHEET
);
106 if (import
== NULL
) {
107 xsltTransformError(NULL
, style
, cur
,
108 "xsl:import : unable to load %s\n", URI
);
112 res
= xsltParseStylesheetImportedDoc(import
, style
);
114 res
->next
= style
->imports
;
115 style
->imports
= res
;
116 if (style
->parent
== NULL
) {
117 xsltFixImportedCompSteps(style
, res
);
136 * xsltParseStylesheetInclude:
137 * @style: the XSLT stylesheet
138 * @cur: the include node
140 * parse an XSLT stylesheet include element
142 * Returns 0 in case of success -1 in case of failure
146 xsltParseStylesheetInclude(xsltStylesheetPtr style
, xmlNodePtr cur
) {
149 xmlChar
*base
= NULL
;
150 xmlChar
*uriRef
= NULL
;
152 xsltStylesheetPtr result
;
153 xsltDocumentPtr include
;
154 xsltDocumentPtr docptr
;
157 if ((cur
== NULL
) || (style
== NULL
))
160 uriRef
= xmlGetNsProp(cur
, (const xmlChar
*)"href", NULL
);
161 if (uriRef
== NULL
) {
162 xsltTransformError(NULL
, style
, cur
,
163 "xsl:include : missing href attribute\n");
167 base
= xmlNodeGetBase(style
->doc
, cur
);
168 URI
= xmlBuildURI(uriRef
, base
);
170 xsltTransformError(NULL
, style
, cur
,
171 "xsl:include : invalid URI reference %s\n", uriRef
);
176 * in order to detect recursion, we check all previously included
179 docptr
= style
->includes
;
180 while (docptr
!= NULL
) {
181 if (xmlStrEqual(docptr
->doc
->URL
, URI
)) {
182 xsltTransformError(NULL
, style
, cur
,
183 "xsl:include : recursion detected on included URL %s\n", URI
);
186 docptr
= docptr
->includes
;
189 include
= xsltLoadStyleDocument(style
, URI
);
190 if (include
== NULL
) {
191 xsltTransformError(NULL
, style
, cur
,
192 "xsl:include : unable to load %s\n", URI
);
195 #ifdef XSLT_REFACTORED
196 if (IS_XSLT_ELEM_FAST(cur
) && (cur
->psvi
!= NULL
)) {
197 ((xsltStyleItemIncludePtr
) cur
->psvi
)->include
= include
;
199 xsltTransformError(NULL
, style
, cur
,
200 "Internal error: (xsltParseStylesheetInclude) "
201 "The xsl:include element was not compiled.\n", URI
);
206 style
->doc
= include
->doc
;
207 /* chain to stylesheet for recursion checking */
208 include
->includes
= style
->includes
;
209 style
->includes
= include
;
210 oldNopreproc
= style
->nopreproc
;
211 style
->nopreproc
= include
->preproc
;
213 * TODO: This will change some values of the
214 * including stylesheet with every included module
215 * (e.g. excluded-result-prefixes)
216 * We need to strictly seperate such stylesheet-owned values.
218 result
= xsltParseStylesheetProcess(style
, include
->doc
);
219 style
->nopreproc
= oldNopreproc
;
220 include
->preproc
= 1;
221 style
->includes
= include
->includes
;
223 if (result
== NULL
) {
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
) break;
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 information 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
, BAD_CAST
"*",
319 val
= (const xmlChar
*)
320 xmlHashLookup2(style
->stripSpaces
, node
->name
, NULL
);
323 if (xmlStrEqual(val
, (xmlChar
*) "strip"))
325 if (xmlStrEqual(val
, (xmlChar
*) "preserve"))
328 if (style
->stripAll
== 1)
330 if (style
->stripAll
== -1)
333 style
= xsltNextImport(style
);
340 * @ctxt: an XSLT transformation context
341 * @name: the template name
342 * @nameURI: the template name URI
344 * Finds the named template, apply import precedence rule.
345 * REVISIT TODO: We'll change the nameURI fields of
346 * templates to be in the string dict, so if the
347 * specified @nameURI is in the same dict, then use pointer
348 * comparison. Check if this can be done in a sane way.
349 * Maybe this function is not needed internally at
350 * transformation-time if we hard-wire the called templates
353 * Returns the xsltTemplatePtr or NULL if not found
356 xsltFindTemplate(xsltTransformContextPtr ctxt
, const xmlChar
*name
,
357 const xmlChar
*nameURI
) {
359 xsltStylesheetPtr style
;
361 if ((ctxt
== NULL
) || (name
== NULL
))
364 while (style
!= NULL
) {
365 if (style
->namedTemplates
!= NULL
) {
366 cur
= (xsltTemplatePtr
)
367 xmlHashLookup2(style
->namedTemplates
, name
, nameURI
);
372 style
= xsltNextImport(style
);