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
,
32 (xmlHashScanner
) xsltNormalizeCompSteps
, master
);
33 master
->extrasNr
+= style
->extrasNr
;
34 for (res
= style
->imports
; res
!= NULL
; res
= res
->next
) {
35 xsltFixImportedCompSteps(master
, res
);
40 * xsltParseStylesheetImport:
41 * @style: the XSLT stylesheet
42 * @cur: the import element
44 * parse an XSLT stylesheet import element
46 * Returns 0 in case of success -1 in case of failure.
50 xsltParseStylesheetImport(xsltStylesheetPtr style
, xmlNodePtr cur
) {
52 xmlDocPtr import
= NULL
;
54 xmlChar
*uriRef
= NULL
;
56 xsltStylesheetPtr res
;
57 xsltSecurityPrefsPtr sec
;
59 if ((cur
== NULL
) || (style
== NULL
))
62 uriRef
= xmlGetNsProp(cur
, (const xmlChar
*)"href", NULL
);
64 xsltTransformError(NULL
, style
, cur
,
65 "xsl:import : missing href attribute\n");
69 base
= xmlNodeGetBase(style
->doc
, cur
);
70 URI
= xmlBuildURI(uriRef
, base
);
72 xsltTransformError(NULL
, style
, cur
,
73 "xsl:import : invalid URI reference %s\n", uriRef
);
81 if (xmlStrEqual(res
->doc
->URL
, URI
)) {
82 xsltTransformError(NULL
, style
, cur
,
83 "xsl:import : recursion detected on imported URL %s\n", URI
);
90 * Security framework check
92 sec
= xsltGetDefaultSecurityPrefs();
96 secres
= xsltCheckRead(sec
, NULL
, URI
);
98 xsltTransformError(NULL
, NULL
, NULL
,
99 "xsl:import: read rights for %s denied\n",
105 import
= xsltDocDefaultLoader(URI
, style
->dict
, XSLT_PARSE_OPTIONS
,
106 (void *) style
, XSLT_LOAD_STYLESHEET
);
107 if (import
== NULL
) {
108 xsltTransformError(NULL
, style
, cur
,
109 "xsl:import : unable to load %s\n", URI
);
113 res
= xsltParseStylesheetImportedDoc(import
, style
);
115 res
->next
= style
->imports
;
116 style
->imports
= res
;
117 if (style
->parent
== NULL
) {
118 xsltFixImportedCompSteps(style
, res
);
137 * xsltParseStylesheetInclude:
138 * @style: the XSLT stylesheet
139 * @cur: the include node
141 * parse an XSLT stylesheet include element
143 * Returns 0 in case of success -1 in case of failure
147 xsltParseStylesheetInclude(xsltStylesheetPtr style
, xmlNodePtr cur
) {
150 xmlChar
*base
= NULL
;
151 xmlChar
*uriRef
= NULL
;
153 xsltStylesheetPtr result
;
154 xsltDocumentPtr include
;
155 xsltDocumentPtr docptr
;
158 if ((cur
== NULL
) || (style
== NULL
))
161 uriRef
= xmlGetNsProp(cur
, (const xmlChar
*)"href", NULL
);
162 if (uriRef
== NULL
) {
163 xsltTransformError(NULL
, style
, cur
,
164 "xsl:include : missing href attribute\n");
168 base
= xmlNodeGetBase(style
->doc
, cur
);
169 URI
= xmlBuildURI(uriRef
, base
);
171 xsltTransformError(NULL
, style
, cur
,
172 "xsl:include : invalid URI reference %s\n", uriRef
);
177 * in order to detect recursion, we check all previously included
180 docptr
= style
->includes
;
181 while (docptr
!= NULL
) {
182 if (xmlStrEqual(docptr
->doc
->URL
, URI
)) {
183 xsltTransformError(NULL
, style
, cur
,
184 "xsl:include : recursion detected on included URL %s\n", URI
);
187 docptr
= docptr
->includes
;
190 include
= xsltLoadStyleDocument(style
, URI
);
191 if (include
== NULL
) {
192 xsltTransformError(NULL
, style
, cur
,
193 "xsl:include : unable to load %s\n", URI
);
196 #ifdef XSLT_REFACTORED
197 if (IS_XSLT_ELEM_FAST(cur
) && (cur
->psvi
!= NULL
)) {
198 ((xsltStyleItemIncludePtr
) cur
->psvi
)->include
= include
;
200 xsltTransformError(NULL
, style
, cur
,
201 "Internal error: (xsltParseStylesheetInclude) "
202 "The xsl:include element was not compiled.\n", URI
);
207 style
->doc
= include
->doc
;
208 /* chain to stylesheet for recursion checking */
209 include
->includes
= style
->includes
;
210 style
->includes
= include
;
211 oldNopreproc
= style
->nopreproc
;
212 style
->nopreproc
= include
->preproc
;
214 * TODO: This will change some values of the
215 * including stylesheet with every included module
216 * (e.g. excluded-result-prefixes)
217 * We need to strictly seperate such stylesheet-owned values.
219 result
= xsltParseStylesheetProcess(style
, include
->doc
);
220 style
->nopreproc
= oldNopreproc
;
221 include
->preproc
= 1;
222 style
->includes
= include
->includes
;
224 if (result
== NULL
) {
243 * @cur: the current XSLT stylesheet
245 * Find the next stylesheet in import precedence.
247 * Returns the next stylesheet or NULL if it was the last one
251 xsltNextImport(xsltStylesheetPtr cur
) {
254 if (cur
->imports
!= NULL
)
255 return(cur
->imports
);
256 if (cur
->next
!= NULL
)
260 if (cur
== NULL
) break;
261 if (cur
->next
!= NULL
) return(cur
->next
);
262 } while (cur
!= NULL
);
267 * xsltNeedElemSpaceHandling:
268 * @ctxt: an XSLT transformation context
270 * Checks whether that stylesheet requires white-space stripping
272 * Returns 1 if space should be stripped, 0 if not
276 xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt
) {
277 xsltStylesheetPtr style
;
282 while (style
!= NULL
) {
283 if (style
->stripSpaces
!= NULL
)
285 style
= xsltNextImport(style
);
291 * xsltFindElemSpaceHandling:
292 * @ctxt: an XSLT transformation context
295 * Find strip-space or preserve-space informations for an element
296 * respect the import precedence or the wildcards
298 * Returns 1 if space should be stripped, 0 if not, and 2 if everything
299 * should be CDTATA wrapped.
303 xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt
, xmlNodePtr node
) {
304 xsltStylesheetPtr style
;
307 if ((ctxt
== NULL
) || (node
== NULL
))
310 while (style
!= NULL
) {
311 if (node
->ns
!= NULL
) {
312 val
= (const xmlChar
*)
313 xmlHashLookup2(style
->stripSpaces
, node
->name
, node
->ns
->href
);
315 val
= (const xmlChar
*)
316 xmlHashLookup2(style
->stripSpaces
, BAD_CAST
"*",
320 val
= (const xmlChar
*)
321 xmlHashLookup2(style
->stripSpaces
, node
->name
, NULL
);
324 if (xmlStrEqual(val
, (xmlChar
*) "strip"))
326 if (xmlStrEqual(val
, (xmlChar
*) "preserve"))
329 if (style
->stripAll
== 1)
331 if (style
->stripAll
== -1)
334 style
= xsltNextImport(style
);
341 * @ctxt: an XSLT transformation context
342 * @name: the template name
343 * @nameURI: the template name URI
345 * Finds the named template, apply import precedence rule.
346 * REVISIT TODO: We'll change the nameURI fields of
347 * templates to be in the string dict, so if the
348 * specified @nameURI is in the same dict, then use pointer
349 * comparison. Check if this can be done in a sane way.
350 * Maybe this function is not needed internally at
351 * transformation-time if we hard-wire the called templates
354 * Returns the xsltTemplatePtr or NULL if not found
357 xsltFindTemplate(xsltTransformContextPtr ctxt
, const xmlChar
*name
,
358 const xmlChar
*nameURI
) {
360 xsltStylesheetPtr style
;
362 if ((ctxt
== NULL
) || (name
== NULL
))
365 while (style
!= NULL
) {
366 if (style
->namedTemplates
!= NULL
) {
367 cur
= (xsltTemplatePtr
)
368 xmlHashLookup2(style
->namedTemplates
, name
, nameURI
);
373 style
= xsltNextImport(style
);