source: trunk/third/libxslt/libxslt/imports.c @ 18543

Revision 18543, 7.1 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18542, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * imports.c: Implementation of the XSLT imports
3 *
4 * Reference:
5 *   http://www.w3.org/TR/1999/REC-xslt-19991116
6 *
7 * See Copyright for the status of this software.
8 *
9 * daniel@veillard.com
10 */
11
12#define IN_LIBXSLT
13#include "libxslt.h"
14
15#include <string.h>
16
17#ifdef HAVE_SYS_TYPES_H
18#include <sys/types.h>
19#endif
20#ifdef HAVE_MATH_H
21#include <math.h>
22#endif
23#ifdef HAVE_FLOAT_H
24#include <float.h>
25#endif
26#ifdef HAVE_IEEEFP_H
27#include <ieeefp.h>
28#endif
29#ifdef HAVE_NAN_H
30#include <nan.h>
31#endif
32#ifdef HAVE_CTYPE_H
33#include <ctype.h>
34#endif
35
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>
41#include "xslt.h"
42#include "xsltInternals.h"
43#include "xsltutils.h"
44#include "imports.h"
45#include "documents.h"
46#include "security.h"
47
48
49
50/************************************************************************
51 *                                                                      *
52 *                      Module interfaces                               *
53 *                                                                      *
54 ************************************************************************/
55
56/**
57 * xsltParseStylesheetImport:
58 * @style:  the XSLT stylesheet
59 * @cur:  the import element
60 *
61 * parse an XSLT stylesheet import element
62 *
63 * Returns 0 in case of success -1 in case of failure.
64 */
65
66int
67xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
68    int ret = -1;
69    xmlDocPtr import = NULL;
70    xmlChar *base = NULL;
71    xmlChar *uriRef = NULL;
72    xmlChar *URI = NULL;
73    xsltStylesheetPtr res;
74    xsltSecurityPrefsPtr sec;
75
76    if ((cur == NULL) || (style == NULL))
77        return (ret);
78
79    uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE);
80    if (uriRef == NULL) {
81        xsltTransformError(NULL, style, cur,
82            "xsl:import : missing href attribute\n");
83        goto error;
84    }
85
86    base = xmlNodeGetBase(style->doc, cur);
87    URI = xmlBuildURI(uriRef, base);
88    if (URI == NULL) {
89        xsltTransformError(NULL, style, cur,
90            "xsl:import : invalid URI reference %s\n", uriRef);
91        goto error;
92    }
93
94    /*
95     * Security framework check
96     */
97    sec = xsltGetDefaultSecurityPrefs();
98    if (sec != NULL) {
99        int secres;
100
101        secres = xsltCheckRead(sec, NULL, URI);
102        if (secres == 0) {
103            xsltTransformError(NULL, NULL, NULL,
104                 "xsl:import: read rights for %s denied\n",
105                             URI);
106            goto error;
107        }
108    }
109
110    import = xmlParseFile((const char *)URI);
111    if (import == NULL) {
112        xsltTransformError(NULL, style, cur,
113            "xsl:import : unable to load %s\n", URI);
114        goto error;
115    }
116
117    res = xsltParseStylesheetImportedDoc(import);
118    if (res != NULL) {
119        res->parent = style;
120        res->next = style->imports;
121        style->imports = res;
122        style->extrasNr += res->extrasNr;
123        ret = 0;
124    } else {
125        xmlFreeDoc(import);
126        }
127
128error:
129    if (uriRef != NULL)
130        xmlFree(uriRef);
131    if (base != NULL)
132        xmlFree(base);
133    if (URI != NULL)
134        xmlFree(URI);
135
136    return (ret);
137}
138
139/**
140 * xsltParseStylesheetInclude:
141 * @style:  the XSLT stylesheet
142 * @cur:  the include node
143 *
144 * parse an XSLT stylesheet include element
145 *
146 * Returns 0 in case of success -1 in case of failure
147 */
148
149int
150xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
151    int ret = -1;
152    xmlDocPtr oldDoc;
153    xmlChar *base = NULL;
154    xmlChar *uriRef = NULL;
155    xmlChar *URI = NULL;
156    xsltDocumentPtr include;
157
158    if ((cur == NULL) || (style == NULL))
159        return (ret);
160
161    uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE);
162    if (uriRef == NULL) {
163        xsltTransformError(NULL, style, cur,
164            "xsl:include : missing href attribute\n");
165        goto error;
166    }
167
168    base = xmlNodeGetBase(style->doc, cur);
169    URI = xmlBuildURI(uriRef, base);
170    if (URI == NULL) {
171        xsltTransformError(NULL, style, cur,
172            "xsl:include : invalid URI reference %s\n", uriRef);
173        goto error;
174    }
175
176    include = xsltLoadStyleDocument(style, URI);
177    if (include == NULL) {
178        xsltTransformError(NULL, style, cur,
179            "xsl:include : unable to load %s\n", URI);
180        goto error;
181    }
182
183    oldDoc = style->doc;
184    style->doc = include->doc;
185    ret = (int)xsltParseStylesheetProcess(style, include->doc);
186    style->doc = oldDoc;
187    if (ret == 0) {
188                ret = -1;
189                goto error;
190        }
191    ret = 0;
192
193error:
194    if (uriRef != NULL)
195        xmlFree(uriRef);
196    if (base != NULL)
197        xmlFree(base);
198    if (URI != NULL)
199        xmlFree(URI);
200
201    return (ret);
202}
203
204/**
205 * xsltNextImport:
206 * @cur:  the current XSLT stylesheet
207 *
208 * Find the next stylesheet in import precedence.
209 *
210 * Returns the next stylesheet or NULL if it was the last one
211 */
212
213xsltStylesheetPtr
214xsltNextImport(xsltStylesheetPtr cur) {
215    if (cur == NULL)
216        return(NULL);
217    if (cur->imports != NULL)
218        return(cur->imports);
219    if (cur->next != NULL)
220        return(cur->next) ;
221    do {
222        cur = cur->parent;
223        if (cur == NULL) return(NULL);
224        if (cur->next != NULL) return(cur->next);
225    } while (cur != NULL);
226    return(cur);
227}
228
229/**
230 * xsltNeedElemSpaceHandling:
231 * @ctxt:  an XSLT transformation context
232 *
233 * Checks whether that stylesheet requires white-space stripping
234 *
235 * Returns 1 if space should be stripped, 0 if not
236 */
237
238int
239xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt) {
240    xsltStylesheetPtr style;
241
242    if (ctxt == NULL)
243        return(0);
244    style = ctxt->style;
245    while (style != NULL) {
246        if (style->stripSpaces != NULL)
247            return(1);
248        style = xsltNextImport(style);
249    }
250    return(0);
251}
252
253/**
254 * xsltFindElemSpaceHandling:
255 * @ctxt:  an XSLT transformation context
256 * @node:  an XML node
257 *
258 * Find strip-space or preserve-space informations for an element
259 * respect the import precedence or the wildcards
260 *
261 * Returns 1 if space should be stripped, 0 if not, and 2 if everything
262 *         should be CDTATA wrapped.
263 */
264
265int
266xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) {
267    xsltStylesheetPtr style;
268    const xmlChar *val;
269
270    if ((ctxt == NULL) || (node == NULL))
271        return(0);
272    style = ctxt->style;
273    while (style != NULL) {
274        if (node->ns != NULL) {
275            val = (const xmlChar *)
276              xmlHashLookup2(style->stripSpaces, node->name, node->ns->href);
277        } else {
278            val = (const xmlChar *)
279                  xmlHashLookup2(style->stripSpaces, node->name, NULL);
280        }
281        if (val != NULL) {
282            if (xmlStrEqual(val, (xmlChar *) "strip"))
283                return(1);
284            if (xmlStrEqual(val, (xmlChar *) "preserve"))
285                return(0);
286        }
287        if (style->stripAll == 1)
288            return(1);
289        if (style->stripAll == -1)
290            return(0);
291
292        style = xsltNextImport(style);
293    }
294    return(0);
295}
296
297/**
298 * xsltFindTemplate:
299 * @ctxt:  an XSLT transformation context
300 * @name: the template name
301 * @nameURI: the template name URI
302 *
303 * Finds the named template, apply import precedence rule.
304 *
305 * Returns the xsltTemplatePtr or NULL if not found
306 */
307xsltTemplatePtr
308xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
309                 const xmlChar *nameURI) {
310    xsltTemplatePtr cur;
311    xsltStylesheetPtr style;
312
313    if ((ctxt == NULL) || (name == NULL))
314        return(NULL);
315    style = ctxt->style;
316    while (style != NULL) {
317        cur = style->templates;
318        while (cur != NULL) {
319            if (xmlStrEqual(name, cur->name)) {
320                if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
321                    ((nameURI != NULL) && (cur->nameURI != NULL) &&
322                     (xmlStrEqual(nameURI, cur->nameURI)))) {
323                    return(cur);
324                }
325            }
326            cur = cur->next;
327        }
328
329        style = xsltNextImport(style);
330    }
331    return(NULL);
332}
333
Note: See TracBrowser for help on using the repository browser.