Paul Cercueil / libxml2

Dependents:   libiio

Committer:
pcercuei
Date:
Thu Aug 25 10:05:35 2016 +0000
Revision:
0:03b5121a232e
Add basic C files of libxml2 2.9.4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pcercuei 0:03b5121a232e 1 /*
pcercuei 0:03b5121a232e 2 * xinclude.c : Code to implement XInclude processing
pcercuei 0:03b5121a232e 3 *
pcercuei 0:03b5121a232e 4 * World Wide Web Consortium W3C Last Call Working Draft 10 November 2003
pcercuei 0:03b5121a232e 5 * http://www.w3.org/TR/2003/WD-xinclude-20031110
pcercuei 0:03b5121a232e 6 *
pcercuei 0:03b5121a232e 7 * See Copyright for the status of this software.
pcercuei 0:03b5121a232e 8 *
pcercuei 0:03b5121a232e 9 * daniel@veillard.com
pcercuei 0:03b5121a232e 10 */
pcercuei 0:03b5121a232e 11
pcercuei 0:03b5121a232e 12 #define IN_LIBXML
pcercuei 0:03b5121a232e 13 #include "libxml.h"
pcercuei 0:03b5121a232e 14
pcercuei 0:03b5121a232e 15 #include <string.h>
pcercuei 0:03b5121a232e 16 #include <libxml/xmlmemory.h>
pcercuei 0:03b5121a232e 17 #include <libxml/tree.h>
pcercuei 0:03b5121a232e 18 #include <libxml/parser.h>
pcercuei 0:03b5121a232e 19 #include <libxml/uri.h>
pcercuei 0:03b5121a232e 20 #include <libxml/xpath.h>
pcercuei 0:03b5121a232e 21 #include <libxml/xpointer.h>
pcercuei 0:03b5121a232e 22 #include <libxml/parserInternals.h>
pcercuei 0:03b5121a232e 23 #include <libxml/xmlerror.h>
pcercuei 0:03b5121a232e 24 #include <libxml/encoding.h>
pcercuei 0:03b5121a232e 25 #include <libxml/globals.h>
pcercuei 0:03b5121a232e 26
pcercuei 0:03b5121a232e 27 #ifdef LIBXML_XINCLUDE_ENABLED
pcercuei 0:03b5121a232e 28 #include <libxml/xinclude.h>
pcercuei 0:03b5121a232e 29
pcercuei 0:03b5121a232e 30 #include "buf.h"
pcercuei 0:03b5121a232e 31
pcercuei 0:03b5121a232e 32 #define XINCLUDE_MAX_DEPTH 40
pcercuei 0:03b5121a232e 33
pcercuei 0:03b5121a232e 34 /* #define DEBUG_XINCLUDE */
pcercuei 0:03b5121a232e 35 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 36 #ifdef LIBXML_DEBUG_ENABLED
pcercuei 0:03b5121a232e 37 #include <libxml/debugXML.h>
pcercuei 0:03b5121a232e 38 #endif
pcercuei 0:03b5121a232e 39 #endif
pcercuei 0:03b5121a232e 40
pcercuei 0:03b5121a232e 41 /************************************************************************
pcercuei 0:03b5121a232e 42 * *
pcercuei 0:03b5121a232e 43 * XInclude context handling *
pcercuei 0:03b5121a232e 44 * *
pcercuei 0:03b5121a232e 45 ************************************************************************/
pcercuei 0:03b5121a232e 46
pcercuei 0:03b5121a232e 47 /*
pcercuei 0:03b5121a232e 48 * An XInclude context
pcercuei 0:03b5121a232e 49 */
pcercuei 0:03b5121a232e 50 typedef xmlChar *xmlURL;
pcercuei 0:03b5121a232e 51
pcercuei 0:03b5121a232e 52 typedef struct _xmlXIncludeRef xmlXIncludeRef;
pcercuei 0:03b5121a232e 53 typedef xmlXIncludeRef *xmlXIncludeRefPtr;
pcercuei 0:03b5121a232e 54 struct _xmlXIncludeRef {
pcercuei 0:03b5121a232e 55 xmlChar *URI; /* the fully resolved resource URL */
pcercuei 0:03b5121a232e 56 xmlChar *fragment; /* the fragment in the URI */
pcercuei 0:03b5121a232e 57 xmlDocPtr doc; /* the parsed document */
pcercuei 0:03b5121a232e 58 xmlNodePtr ref; /* the node making the reference in the source */
pcercuei 0:03b5121a232e 59 xmlNodePtr inc; /* the included copy */
pcercuei 0:03b5121a232e 60 int xml; /* xml or txt */
pcercuei 0:03b5121a232e 61 int count; /* how many refs use that specific doc */
pcercuei 0:03b5121a232e 62 xmlXPathObjectPtr xptr; /* the xpointer if needed */
pcercuei 0:03b5121a232e 63 int emptyFb; /* flag to show fallback empty */
pcercuei 0:03b5121a232e 64 };
pcercuei 0:03b5121a232e 65
pcercuei 0:03b5121a232e 66 struct _xmlXIncludeCtxt {
pcercuei 0:03b5121a232e 67 xmlDocPtr doc; /* the source document */
pcercuei 0:03b5121a232e 68 int incBase; /* the first include for this document */
pcercuei 0:03b5121a232e 69 int incNr; /* number of includes */
pcercuei 0:03b5121a232e 70 int incMax; /* size of includes tab */
pcercuei 0:03b5121a232e 71 xmlXIncludeRefPtr *incTab; /* array of included references */
pcercuei 0:03b5121a232e 72
pcercuei 0:03b5121a232e 73 int txtNr; /* number of unparsed documents */
pcercuei 0:03b5121a232e 74 int txtMax; /* size of unparsed documents tab */
pcercuei 0:03b5121a232e 75 xmlNodePtr *txtTab; /* array of unparsed text nodes */
pcercuei 0:03b5121a232e 76 xmlURL *txturlTab; /* array of unparsed text URLs */
pcercuei 0:03b5121a232e 77
pcercuei 0:03b5121a232e 78 xmlChar * url; /* the current URL processed */
pcercuei 0:03b5121a232e 79 int urlNr; /* number of URLs stacked */
pcercuei 0:03b5121a232e 80 int urlMax; /* size of URL stack */
pcercuei 0:03b5121a232e 81 xmlChar * *urlTab; /* URL stack */
pcercuei 0:03b5121a232e 82
pcercuei 0:03b5121a232e 83 int nbErrors; /* the number of errors detected */
pcercuei 0:03b5121a232e 84 int legacy; /* using XINCLUDE_OLD_NS */
pcercuei 0:03b5121a232e 85 int parseFlags; /* the flags used for parsing XML documents */
pcercuei 0:03b5121a232e 86 xmlChar * base; /* the current xml:base */
pcercuei 0:03b5121a232e 87
pcercuei 0:03b5121a232e 88 void *_private; /* application data */
pcercuei 0:03b5121a232e 89 };
pcercuei 0:03b5121a232e 90
pcercuei 0:03b5121a232e 91 static int
pcercuei 0:03b5121a232e 92 xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree);
pcercuei 0:03b5121a232e 93
pcercuei 0:03b5121a232e 94
pcercuei 0:03b5121a232e 95 /************************************************************************
pcercuei 0:03b5121a232e 96 * *
pcercuei 0:03b5121a232e 97 * XInclude error handler *
pcercuei 0:03b5121a232e 98 * *
pcercuei 0:03b5121a232e 99 ************************************************************************/
pcercuei 0:03b5121a232e 100
pcercuei 0:03b5121a232e 101 /**
pcercuei 0:03b5121a232e 102 * xmlXIncludeErrMemory:
pcercuei 0:03b5121a232e 103 * @extra: extra information
pcercuei 0:03b5121a232e 104 *
pcercuei 0:03b5121a232e 105 * Handle an out of memory condition
pcercuei 0:03b5121a232e 106 */
pcercuei 0:03b5121a232e 107 static void
pcercuei 0:03b5121a232e 108 xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node,
pcercuei 0:03b5121a232e 109 const char *extra)
pcercuei 0:03b5121a232e 110 {
pcercuei 0:03b5121a232e 111 if (ctxt != NULL)
pcercuei 0:03b5121a232e 112 ctxt->nbErrors++;
pcercuei 0:03b5121a232e 113 __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
pcercuei 0:03b5121a232e 114 XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0,
pcercuei 0:03b5121a232e 115 extra, NULL, NULL, 0, 0,
pcercuei 0:03b5121a232e 116 "Memory allocation failed : %s\n", extra);
pcercuei 0:03b5121a232e 117 }
pcercuei 0:03b5121a232e 118
pcercuei 0:03b5121a232e 119 /**
pcercuei 0:03b5121a232e 120 * xmlXIncludeErr:
pcercuei 0:03b5121a232e 121 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 122 * @node: the context node
pcercuei 0:03b5121a232e 123 * @msg: the error message
pcercuei 0:03b5121a232e 124 * @extra: extra information
pcercuei 0:03b5121a232e 125 *
pcercuei 0:03b5121a232e 126 * Handle an XInclude error
pcercuei 0:03b5121a232e 127 */
pcercuei 0:03b5121a232e 128 static void
pcercuei 0:03b5121a232e 129 xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
pcercuei 0:03b5121a232e 130 const char *msg, const xmlChar *extra)
pcercuei 0:03b5121a232e 131 {
pcercuei 0:03b5121a232e 132 if (ctxt != NULL)
pcercuei 0:03b5121a232e 133 ctxt->nbErrors++;
pcercuei 0:03b5121a232e 134 __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
pcercuei 0:03b5121a232e 135 error, XML_ERR_ERROR, NULL, 0,
pcercuei 0:03b5121a232e 136 (const char *) extra, NULL, NULL, 0, 0,
pcercuei 0:03b5121a232e 137 msg, (const char *) extra);
pcercuei 0:03b5121a232e 138 }
pcercuei 0:03b5121a232e 139
pcercuei 0:03b5121a232e 140 #if 0
pcercuei 0:03b5121a232e 141 /**
pcercuei 0:03b5121a232e 142 * xmlXIncludeWarn:
pcercuei 0:03b5121a232e 143 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 144 * @node: the context node
pcercuei 0:03b5121a232e 145 * @msg: the error message
pcercuei 0:03b5121a232e 146 * @extra: extra information
pcercuei 0:03b5121a232e 147 *
pcercuei 0:03b5121a232e 148 * Emit an XInclude warning.
pcercuei 0:03b5121a232e 149 */
pcercuei 0:03b5121a232e 150 static void
pcercuei 0:03b5121a232e 151 xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
pcercuei 0:03b5121a232e 152 const char *msg, const xmlChar *extra)
pcercuei 0:03b5121a232e 153 {
pcercuei 0:03b5121a232e 154 __xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE,
pcercuei 0:03b5121a232e 155 error, XML_ERR_WARNING, NULL, 0,
pcercuei 0:03b5121a232e 156 (const char *) extra, NULL, NULL, 0, 0,
pcercuei 0:03b5121a232e 157 msg, (const char *) extra);
pcercuei 0:03b5121a232e 158 }
pcercuei 0:03b5121a232e 159 #endif
pcercuei 0:03b5121a232e 160
pcercuei 0:03b5121a232e 161 /**
pcercuei 0:03b5121a232e 162 * xmlXIncludeGetProp:
pcercuei 0:03b5121a232e 163 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 164 * @cur: the node
pcercuei 0:03b5121a232e 165 * @name: the attribute name
pcercuei 0:03b5121a232e 166 *
pcercuei 0:03b5121a232e 167 * Get an XInclude attribute
pcercuei 0:03b5121a232e 168 *
pcercuei 0:03b5121a232e 169 * Returns the value (to be freed) or NULL if not found
pcercuei 0:03b5121a232e 170 */
pcercuei 0:03b5121a232e 171 static xmlChar *
pcercuei 0:03b5121a232e 172 xmlXIncludeGetProp(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,
pcercuei 0:03b5121a232e 173 const xmlChar *name) {
pcercuei 0:03b5121a232e 174 xmlChar *ret;
pcercuei 0:03b5121a232e 175
pcercuei 0:03b5121a232e 176 ret = xmlGetNsProp(cur, XINCLUDE_NS, name);
pcercuei 0:03b5121a232e 177 if (ret != NULL)
pcercuei 0:03b5121a232e 178 return(ret);
pcercuei 0:03b5121a232e 179 if (ctxt->legacy != 0) {
pcercuei 0:03b5121a232e 180 ret = xmlGetNsProp(cur, XINCLUDE_OLD_NS, name);
pcercuei 0:03b5121a232e 181 if (ret != NULL)
pcercuei 0:03b5121a232e 182 return(ret);
pcercuei 0:03b5121a232e 183 }
pcercuei 0:03b5121a232e 184 ret = xmlGetProp(cur, name);
pcercuei 0:03b5121a232e 185 return(ret);
pcercuei 0:03b5121a232e 186 }
pcercuei 0:03b5121a232e 187 /**
pcercuei 0:03b5121a232e 188 * xmlXIncludeFreeRef:
pcercuei 0:03b5121a232e 189 * @ref: the XInclude reference
pcercuei 0:03b5121a232e 190 *
pcercuei 0:03b5121a232e 191 * Free an XInclude reference
pcercuei 0:03b5121a232e 192 */
pcercuei 0:03b5121a232e 193 static void
pcercuei 0:03b5121a232e 194 xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
pcercuei 0:03b5121a232e 195 if (ref == NULL)
pcercuei 0:03b5121a232e 196 return;
pcercuei 0:03b5121a232e 197 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 198 xmlGenericError(xmlGenericErrorContext, "Freeing ref\n");
pcercuei 0:03b5121a232e 199 #endif
pcercuei 0:03b5121a232e 200 if (ref->doc != NULL) {
pcercuei 0:03b5121a232e 201 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 202 xmlGenericError(xmlGenericErrorContext, "Freeing doc %s\n", ref->URI);
pcercuei 0:03b5121a232e 203 #endif
pcercuei 0:03b5121a232e 204 xmlFreeDoc(ref->doc);
pcercuei 0:03b5121a232e 205 }
pcercuei 0:03b5121a232e 206 if (ref->URI != NULL)
pcercuei 0:03b5121a232e 207 xmlFree(ref->URI);
pcercuei 0:03b5121a232e 208 if (ref->fragment != NULL)
pcercuei 0:03b5121a232e 209 xmlFree(ref->fragment);
pcercuei 0:03b5121a232e 210 if (ref->xptr != NULL)
pcercuei 0:03b5121a232e 211 xmlXPathFreeObject(ref->xptr);
pcercuei 0:03b5121a232e 212 xmlFree(ref);
pcercuei 0:03b5121a232e 213 }
pcercuei 0:03b5121a232e 214
pcercuei 0:03b5121a232e 215 /**
pcercuei 0:03b5121a232e 216 * xmlXIncludeNewRef:
pcercuei 0:03b5121a232e 217 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 218 * @URI: the resource URI
pcercuei 0:03b5121a232e 219 *
pcercuei 0:03b5121a232e 220 * Creates a new reference within an XInclude context
pcercuei 0:03b5121a232e 221 *
pcercuei 0:03b5121a232e 222 * Returns the new set
pcercuei 0:03b5121a232e 223 */
pcercuei 0:03b5121a232e 224 static xmlXIncludeRefPtr
pcercuei 0:03b5121a232e 225 xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
pcercuei 0:03b5121a232e 226 xmlNodePtr ref) {
pcercuei 0:03b5121a232e 227 xmlXIncludeRefPtr ret;
pcercuei 0:03b5121a232e 228
pcercuei 0:03b5121a232e 229 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 230 xmlGenericError(xmlGenericErrorContext, "New ref %s\n", URI);
pcercuei 0:03b5121a232e 231 #endif
pcercuei 0:03b5121a232e 232 ret = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
pcercuei 0:03b5121a232e 233 if (ret == NULL) {
pcercuei 0:03b5121a232e 234 xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");
pcercuei 0:03b5121a232e 235 return(NULL);
pcercuei 0:03b5121a232e 236 }
pcercuei 0:03b5121a232e 237 memset(ret, 0, sizeof(xmlXIncludeRef));
pcercuei 0:03b5121a232e 238 if (URI == NULL)
pcercuei 0:03b5121a232e 239 ret->URI = NULL;
pcercuei 0:03b5121a232e 240 else
pcercuei 0:03b5121a232e 241 ret->URI = xmlStrdup(URI);
pcercuei 0:03b5121a232e 242 ret->fragment = NULL;
pcercuei 0:03b5121a232e 243 ret->ref = ref;
pcercuei 0:03b5121a232e 244 ret->doc = NULL;
pcercuei 0:03b5121a232e 245 ret->count = 0;
pcercuei 0:03b5121a232e 246 ret->xml = 0;
pcercuei 0:03b5121a232e 247 ret->inc = NULL;
pcercuei 0:03b5121a232e 248 if (ctxt->incMax == 0) {
pcercuei 0:03b5121a232e 249 ctxt->incMax = 4;
pcercuei 0:03b5121a232e 250 ctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(ctxt->incMax *
pcercuei 0:03b5121a232e 251 sizeof(ctxt->incTab[0]));
pcercuei 0:03b5121a232e 252 if (ctxt->incTab == NULL) {
pcercuei 0:03b5121a232e 253 xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");
pcercuei 0:03b5121a232e 254 xmlXIncludeFreeRef(ret);
pcercuei 0:03b5121a232e 255 return(NULL);
pcercuei 0:03b5121a232e 256 }
pcercuei 0:03b5121a232e 257 }
pcercuei 0:03b5121a232e 258 if (ctxt->incNr >= ctxt->incMax) {
pcercuei 0:03b5121a232e 259 ctxt->incMax *= 2;
pcercuei 0:03b5121a232e 260 ctxt->incTab = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
pcercuei 0:03b5121a232e 261 ctxt->incMax * sizeof(ctxt->incTab[0]));
pcercuei 0:03b5121a232e 262 if (ctxt->incTab == NULL) {
pcercuei 0:03b5121a232e 263 xmlXIncludeErrMemory(ctxt, ref, "growing XInclude context");
pcercuei 0:03b5121a232e 264 xmlXIncludeFreeRef(ret);
pcercuei 0:03b5121a232e 265 return(NULL);
pcercuei 0:03b5121a232e 266 }
pcercuei 0:03b5121a232e 267 }
pcercuei 0:03b5121a232e 268 ctxt->incTab[ctxt->incNr++] = ret;
pcercuei 0:03b5121a232e 269 return(ret);
pcercuei 0:03b5121a232e 270 }
pcercuei 0:03b5121a232e 271
pcercuei 0:03b5121a232e 272 /**
pcercuei 0:03b5121a232e 273 * xmlXIncludeNewContext:
pcercuei 0:03b5121a232e 274 * @doc: an XML Document
pcercuei 0:03b5121a232e 275 *
pcercuei 0:03b5121a232e 276 * Creates a new XInclude context
pcercuei 0:03b5121a232e 277 *
pcercuei 0:03b5121a232e 278 * Returns the new set
pcercuei 0:03b5121a232e 279 */
pcercuei 0:03b5121a232e 280 xmlXIncludeCtxtPtr
pcercuei 0:03b5121a232e 281 xmlXIncludeNewContext(xmlDocPtr doc) {
pcercuei 0:03b5121a232e 282 xmlXIncludeCtxtPtr ret;
pcercuei 0:03b5121a232e 283
pcercuei 0:03b5121a232e 284 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 285 xmlGenericError(xmlGenericErrorContext, "New context\n");
pcercuei 0:03b5121a232e 286 #endif
pcercuei 0:03b5121a232e 287 if (doc == NULL)
pcercuei 0:03b5121a232e 288 return(NULL);
pcercuei 0:03b5121a232e 289 ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
pcercuei 0:03b5121a232e 290 if (ret == NULL) {
pcercuei 0:03b5121a232e 291 xmlXIncludeErrMemory(NULL, (xmlNodePtr) doc,
pcercuei 0:03b5121a232e 292 "creating XInclude context");
pcercuei 0:03b5121a232e 293 return(NULL);
pcercuei 0:03b5121a232e 294 }
pcercuei 0:03b5121a232e 295 memset(ret, 0, sizeof(xmlXIncludeCtxt));
pcercuei 0:03b5121a232e 296 ret->doc = doc;
pcercuei 0:03b5121a232e 297 ret->incNr = 0;
pcercuei 0:03b5121a232e 298 ret->incBase = 0;
pcercuei 0:03b5121a232e 299 ret->incMax = 0;
pcercuei 0:03b5121a232e 300 ret->incTab = NULL;
pcercuei 0:03b5121a232e 301 ret->nbErrors = 0;
pcercuei 0:03b5121a232e 302 return(ret);
pcercuei 0:03b5121a232e 303 }
pcercuei 0:03b5121a232e 304
pcercuei 0:03b5121a232e 305 /**
pcercuei 0:03b5121a232e 306 * xmlXIncludeURLPush:
pcercuei 0:03b5121a232e 307 * @ctxt: the parser context
pcercuei 0:03b5121a232e 308 * @value: the url
pcercuei 0:03b5121a232e 309 *
pcercuei 0:03b5121a232e 310 * Pushes a new url on top of the url stack
pcercuei 0:03b5121a232e 311 *
pcercuei 0:03b5121a232e 312 * Returns -1 in case of error, the index in the stack otherwise
pcercuei 0:03b5121a232e 313 */
pcercuei 0:03b5121a232e 314 static int
pcercuei 0:03b5121a232e 315 xmlXIncludeURLPush(xmlXIncludeCtxtPtr ctxt,
pcercuei 0:03b5121a232e 316 const xmlChar *value)
pcercuei 0:03b5121a232e 317 {
pcercuei 0:03b5121a232e 318 if (ctxt->urlNr > XINCLUDE_MAX_DEPTH) {
pcercuei 0:03b5121a232e 319 xmlXIncludeErr(ctxt, NULL, XML_XINCLUDE_RECURSION,
pcercuei 0:03b5121a232e 320 "detected a recursion in %s\n", value);
pcercuei 0:03b5121a232e 321 return(-1);
pcercuei 0:03b5121a232e 322 }
pcercuei 0:03b5121a232e 323 if (ctxt->urlTab == NULL) {
pcercuei 0:03b5121a232e 324 ctxt->urlMax = 4;
pcercuei 0:03b5121a232e 325 ctxt->urlNr = 0;
pcercuei 0:03b5121a232e 326 ctxt->urlTab = (xmlChar * *) xmlMalloc(
pcercuei 0:03b5121a232e 327 ctxt->urlMax * sizeof(ctxt->urlTab[0]));
pcercuei 0:03b5121a232e 328 if (ctxt->urlTab == NULL) {
pcercuei 0:03b5121a232e 329 xmlXIncludeErrMemory(ctxt, NULL, "adding URL");
pcercuei 0:03b5121a232e 330 return (-1);
pcercuei 0:03b5121a232e 331 }
pcercuei 0:03b5121a232e 332 }
pcercuei 0:03b5121a232e 333 if (ctxt->urlNr >= ctxt->urlMax) {
pcercuei 0:03b5121a232e 334 ctxt->urlMax *= 2;
pcercuei 0:03b5121a232e 335 ctxt->urlTab =
pcercuei 0:03b5121a232e 336 (xmlChar * *) xmlRealloc(ctxt->urlTab,
pcercuei 0:03b5121a232e 337 ctxt->urlMax *
pcercuei 0:03b5121a232e 338 sizeof(ctxt->urlTab[0]));
pcercuei 0:03b5121a232e 339 if (ctxt->urlTab == NULL) {
pcercuei 0:03b5121a232e 340 xmlXIncludeErrMemory(ctxt, NULL, "adding URL");
pcercuei 0:03b5121a232e 341 return (-1);
pcercuei 0:03b5121a232e 342 }
pcercuei 0:03b5121a232e 343 }
pcercuei 0:03b5121a232e 344 ctxt->url = ctxt->urlTab[ctxt->urlNr] = xmlStrdup(value);
pcercuei 0:03b5121a232e 345 return (ctxt->urlNr++);
pcercuei 0:03b5121a232e 346 }
pcercuei 0:03b5121a232e 347
pcercuei 0:03b5121a232e 348 /**
pcercuei 0:03b5121a232e 349 * xmlXIncludeURLPop:
pcercuei 0:03b5121a232e 350 * @ctxt: the parser context
pcercuei 0:03b5121a232e 351 *
pcercuei 0:03b5121a232e 352 * Pops the top URL from the URL stack
pcercuei 0:03b5121a232e 353 */
pcercuei 0:03b5121a232e 354 static void
pcercuei 0:03b5121a232e 355 xmlXIncludeURLPop(xmlXIncludeCtxtPtr ctxt)
pcercuei 0:03b5121a232e 356 {
pcercuei 0:03b5121a232e 357 xmlChar * ret;
pcercuei 0:03b5121a232e 358
pcercuei 0:03b5121a232e 359 if (ctxt->urlNr <= 0)
pcercuei 0:03b5121a232e 360 return;
pcercuei 0:03b5121a232e 361 ctxt->urlNr--;
pcercuei 0:03b5121a232e 362 if (ctxt->urlNr > 0)
pcercuei 0:03b5121a232e 363 ctxt->url = ctxt->urlTab[ctxt->urlNr - 1];
pcercuei 0:03b5121a232e 364 else
pcercuei 0:03b5121a232e 365 ctxt->url = NULL;
pcercuei 0:03b5121a232e 366 ret = ctxt->urlTab[ctxt->urlNr];
pcercuei 0:03b5121a232e 367 ctxt->urlTab[ctxt->urlNr] = NULL;
pcercuei 0:03b5121a232e 368 if (ret != NULL)
pcercuei 0:03b5121a232e 369 xmlFree(ret);
pcercuei 0:03b5121a232e 370 }
pcercuei 0:03b5121a232e 371
pcercuei 0:03b5121a232e 372 /**
pcercuei 0:03b5121a232e 373 * xmlXIncludeFreeContext:
pcercuei 0:03b5121a232e 374 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 375 *
pcercuei 0:03b5121a232e 376 * Free an XInclude context
pcercuei 0:03b5121a232e 377 */
pcercuei 0:03b5121a232e 378 void
pcercuei 0:03b5121a232e 379 xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
pcercuei 0:03b5121a232e 380 int i;
pcercuei 0:03b5121a232e 381
pcercuei 0:03b5121a232e 382 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 383 xmlGenericError(xmlGenericErrorContext, "Freeing context\n");
pcercuei 0:03b5121a232e 384 #endif
pcercuei 0:03b5121a232e 385 if (ctxt == NULL)
pcercuei 0:03b5121a232e 386 return;
pcercuei 0:03b5121a232e 387 while (ctxt->urlNr > 0)
pcercuei 0:03b5121a232e 388 xmlXIncludeURLPop(ctxt);
pcercuei 0:03b5121a232e 389 if (ctxt->urlTab != NULL)
pcercuei 0:03b5121a232e 390 xmlFree(ctxt->urlTab);
pcercuei 0:03b5121a232e 391 for (i = 0;i < ctxt->incNr;i++) {
pcercuei 0:03b5121a232e 392 if (ctxt->incTab[i] != NULL)
pcercuei 0:03b5121a232e 393 xmlXIncludeFreeRef(ctxt->incTab[i]);
pcercuei 0:03b5121a232e 394 }
pcercuei 0:03b5121a232e 395 if (ctxt->txturlTab != NULL) {
pcercuei 0:03b5121a232e 396 for (i = 0;i < ctxt->txtNr;i++) {
pcercuei 0:03b5121a232e 397 if (ctxt->txturlTab[i] != NULL)
pcercuei 0:03b5121a232e 398 xmlFree(ctxt->txturlTab[i]);
pcercuei 0:03b5121a232e 399 }
pcercuei 0:03b5121a232e 400 }
pcercuei 0:03b5121a232e 401 if (ctxt->incTab != NULL)
pcercuei 0:03b5121a232e 402 xmlFree(ctxt->incTab);
pcercuei 0:03b5121a232e 403 if (ctxt->txtTab != NULL)
pcercuei 0:03b5121a232e 404 xmlFree(ctxt->txtTab);
pcercuei 0:03b5121a232e 405 if (ctxt->txturlTab != NULL)
pcercuei 0:03b5121a232e 406 xmlFree(ctxt->txturlTab);
pcercuei 0:03b5121a232e 407 if (ctxt->base != NULL) {
pcercuei 0:03b5121a232e 408 xmlFree(ctxt->base);
pcercuei 0:03b5121a232e 409 }
pcercuei 0:03b5121a232e 410 xmlFree(ctxt);
pcercuei 0:03b5121a232e 411 }
pcercuei 0:03b5121a232e 412
pcercuei 0:03b5121a232e 413 /**
pcercuei 0:03b5121a232e 414 * xmlXIncludeParseFile:
pcercuei 0:03b5121a232e 415 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 416 * @URL: the URL or file path
pcercuei 0:03b5121a232e 417 *
pcercuei 0:03b5121a232e 418 * parse a document for XInclude
pcercuei 0:03b5121a232e 419 */
pcercuei 0:03b5121a232e 420 static xmlDocPtr
pcercuei 0:03b5121a232e 421 xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
pcercuei 0:03b5121a232e 422 xmlDocPtr ret;
pcercuei 0:03b5121a232e 423 xmlParserCtxtPtr pctxt;
pcercuei 0:03b5121a232e 424 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 425
pcercuei 0:03b5121a232e 426 xmlInitParser();
pcercuei 0:03b5121a232e 427
pcercuei 0:03b5121a232e 428 pctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 429 if (pctxt == NULL) {
pcercuei 0:03b5121a232e 430 xmlXIncludeErrMemory(ctxt, NULL, "cannot allocate parser context");
pcercuei 0:03b5121a232e 431 return(NULL);
pcercuei 0:03b5121a232e 432 }
pcercuei 0:03b5121a232e 433
pcercuei 0:03b5121a232e 434 /*
pcercuei 0:03b5121a232e 435 * pass in the application data to the parser context.
pcercuei 0:03b5121a232e 436 */
pcercuei 0:03b5121a232e 437 pctxt->_private = ctxt->_private;
pcercuei 0:03b5121a232e 438
pcercuei 0:03b5121a232e 439 /*
pcercuei 0:03b5121a232e 440 * try to ensure that new documents included are actually
pcercuei 0:03b5121a232e 441 * built with the same dictionary as the including document.
pcercuei 0:03b5121a232e 442 */
pcercuei 0:03b5121a232e 443 if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL)) {
pcercuei 0:03b5121a232e 444 if (pctxt->dict != NULL)
pcercuei 0:03b5121a232e 445 xmlDictFree(pctxt->dict);
pcercuei 0:03b5121a232e 446 pctxt->dict = ctxt->doc->dict;
pcercuei 0:03b5121a232e 447 xmlDictReference(pctxt->dict);
pcercuei 0:03b5121a232e 448 }
pcercuei 0:03b5121a232e 449
pcercuei 0:03b5121a232e 450 xmlCtxtUseOptions(pctxt, ctxt->parseFlags | XML_PARSE_DTDLOAD);
pcercuei 0:03b5121a232e 451
pcercuei 0:03b5121a232e 452 inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);
pcercuei 0:03b5121a232e 453 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 454 xmlFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 455 return(NULL);
pcercuei 0:03b5121a232e 456 }
pcercuei 0:03b5121a232e 457
pcercuei 0:03b5121a232e 458 inputPush(pctxt, inputStream);
pcercuei 0:03b5121a232e 459
pcercuei 0:03b5121a232e 460 if (pctxt->directory == NULL)
pcercuei 0:03b5121a232e 461 pctxt->directory = xmlParserGetDirectory(URL);
pcercuei 0:03b5121a232e 462
pcercuei 0:03b5121a232e 463 pctxt->loadsubset |= XML_DETECT_IDS;
pcercuei 0:03b5121a232e 464
pcercuei 0:03b5121a232e 465 xmlParseDocument(pctxt);
pcercuei 0:03b5121a232e 466
pcercuei 0:03b5121a232e 467 if (pctxt->wellFormed) {
pcercuei 0:03b5121a232e 468 ret = pctxt->myDoc;
pcercuei 0:03b5121a232e 469 }
pcercuei 0:03b5121a232e 470 else {
pcercuei 0:03b5121a232e 471 ret = NULL;
pcercuei 0:03b5121a232e 472 if (pctxt->myDoc != NULL)
pcercuei 0:03b5121a232e 473 xmlFreeDoc(pctxt->myDoc);
pcercuei 0:03b5121a232e 474 pctxt->myDoc = NULL;
pcercuei 0:03b5121a232e 475 }
pcercuei 0:03b5121a232e 476 xmlFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 477
pcercuei 0:03b5121a232e 478 return(ret);
pcercuei 0:03b5121a232e 479 }
pcercuei 0:03b5121a232e 480
pcercuei 0:03b5121a232e 481 /**
pcercuei 0:03b5121a232e 482 * xmlXIncludeAddNode:
pcercuei 0:03b5121a232e 483 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 484 * @cur: the new node
pcercuei 0:03b5121a232e 485 *
pcercuei 0:03b5121a232e 486 * Add a new node to process to an XInclude context
pcercuei 0:03b5121a232e 487 */
pcercuei 0:03b5121a232e 488 static int
pcercuei 0:03b5121a232e 489 xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
pcercuei 0:03b5121a232e 490 xmlXIncludeRefPtr ref;
pcercuei 0:03b5121a232e 491 xmlURIPtr uri;
pcercuei 0:03b5121a232e 492 xmlChar *URL;
pcercuei 0:03b5121a232e 493 xmlChar *fragment = NULL;
pcercuei 0:03b5121a232e 494 xmlChar *href;
pcercuei 0:03b5121a232e 495 xmlChar *parse;
pcercuei 0:03b5121a232e 496 xmlChar *base;
pcercuei 0:03b5121a232e 497 xmlChar *URI;
pcercuei 0:03b5121a232e 498 int xml = 1, i; /* default Issue 64 */
pcercuei 0:03b5121a232e 499 int local = 0;
pcercuei 0:03b5121a232e 500
pcercuei 0:03b5121a232e 501
pcercuei 0:03b5121a232e 502 if (ctxt == NULL)
pcercuei 0:03b5121a232e 503 return(-1);
pcercuei 0:03b5121a232e 504 if (cur == NULL)
pcercuei 0:03b5121a232e 505 return(-1);
pcercuei 0:03b5121a232e 506
pcercuei 0:03b5121a232e 507 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 508 xmlGenericError(xmlGenericErrorContext, "Add node\n");
pcercuei 0:03b5121a232e 509 #endif
pcercuei 0:03b5121a232e 510 /*
pcercuei 0:03b5121a232e 511 * read the attributes
pcercuei 0:03b5121a232e 512 */
pcercuei 0:03b5121a232e 513 href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
pcercuei 0:03b5121a232e 514 if (href == NULL) {
pcercuei 0:03b5121a232e 515 href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
pcercuei 0:03b5121a232e 516 if (href == NULL)
pcercuei 0:03b5121a232e 517 return(-1);
pcercuei 0:03b5121a232e 518 }
pcercuei 0:03b5121a232e 519 if ((href[0] == '#') || (href[0] == 0))
pcercuei 0:03b5121a232e 520 local = 1;
pcercuei 0:03b5121a232e 521 parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
pcercuei 0:03b5121a232e 522 if (parse != NULL) {
pcercuei 0:03b5121a232e 523 if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
pcercuei 0:03b5121a232e 524 xml = 1;
pcercuei 0:03b5121a232e 525 else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
pcercuei 0:03b5121a232e 526 xml = 0;
pcercuei 0:03b5121a232e 527 else {
pcercuei 0:03b5121a232e 528 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
pcercuei 0:03b5121a232e 529 "invalid value %s for 'parse'\n", parse);
pcercuei 0:03b5121a232e 530 if (href != NULL)
pcercuei 0:03b5121a232e 531 xmlFree(href);
pcercuei 0:03b5121a232e 532 if (parse != NULL)
pcercuei 0:03b5121a232e 533 xmlFree(parse);
pcercuei 0:03b5121a232e 534 return(-1);
pcercuei 0:03b5121a232e 535 }
pcercuei 0:03b5121a232e 536 }
pcercuei 0:03b5121a232e 537
pcercuei 0:03b5121a232e 538 /*
pcercuei 0:03b5121a232e 539 * compute the URI
pcercuei 0:03b5121a232e 540 */
pcercuei 0:03b5121a232e 541 base = xmlNodeGetBase(ctxt->doc, cur);
pcercuei 0:03b5121a232e 542 if (base == NULL) {
pcercuei 0:03b5121a232e 543 URI = xmlBuildURI(href, ctxt->doc->URL);
pcercuei 0:03b5121a232e 544 } else {
pcercuei 0:03b5121a232e 545 URI = xmlBuildURI(href, base);
pcercuei 0:03b5121a232e 546 }
pcercuei 0:03b5121a232e 547 if (URI == NULL) {
pcercuei 0:03b5121a232e 548 xmlChar *escbase;
pcercuei 0:03b5121a232e 549 xmlChar *eschref;
pcercuei 0:03b5121a232e 550 /*
pcercuei 0:03b5121a232e 551 * Some escaping may be needed
pcercuei 0:03b5121a232e 552 */
pcercuei 0:03b5121a232e 553 escbase = xmlURIEscape(base);
pcercuei 0:03b5121a232e 554 eschref = xmlURIEscape(href);
pcercuei 0:03b5121a232e 555 URI = xmlBuildURI(eschref, escbase);
pcercuei 0:03b5121a232e 556 if (escbase != NULL)
pcercuei 0:03b5121a232e 557 xmlFree(escbase);
pcercuei 0:03b5121a232e 558 if (eschref != NULL)
pcercuei 0:03b5121a232e 559 xmlFree(eschref);
pcercuei 0:03b5121a232e 560 }
pcercuei 0:03b5121a232e 561 if (parse != NULL)
pcercuei 0:03b5121a232e 562 xmlFree(parse);
pcercuei 0:03b5121a232e 563 if (href != NULL)
pcercuei 0:03b5121a232e 564 xmlFree(href);
pcercuei 0:03b5121a232e 565 if (base != NULL)
pcercuei 0:03b5121a232e 566 xmlFree(base);
pcercuei 0:03b5121a232e 567 if (URI == NULL) {
pcercuei 0:03b5121a232e 568 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 569 "failed build URL\n", NULL);
pcercuei 0:03b5121a232e 570 return(-1);
pcercuei 0:03b5121a232e 571 }
pcercuei 0:03b5121a232e 572 fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);
pcercuei 0:03b5121a232e 573
pcercuei 0:03b5121a232e 574 /*
pcercuei 0:03b5121a232e 575 * Check the URL and remove any fragment identifier
pcercuei 0:03b5121a232e 576 */
pcercuei 0:03b5121a232e 577 uri = xmlParseURI((const char *)URI);
pcercuei 0:03b5121a232e 578 if (uri == NULL) {
pcercuei 0:03b5121a232e 579 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 580 "invalid value URI %s\n", URI);
pcercuei 0:03b5121a232e 581 if (fragment != NULL)
pcercuei 0:03b5121a232e 582 xmlFree(fragment);
pcercuei 0:03b5121a232e 583 xmlFree(URI);
pcercuei 0:03b5121a232e 584 return(-1);
pcercuei 0:03b5121a232e 585 }
pcercuei 0:03b5121a232e 586
pcercuei 0:03b5121a232e 587 if (uri->fragment != NULL) {
pcercuei 0:03b5121a232e 588 if (ctxt->legacy != 0) {
pcercuei 0:03b5121a232e 589 if (fragment == NULL) {
pcercuei 0:03b5121a232e 590 fragment = (xmlChar *) uri->fragment;
pcercuei 0:03b5121a232e 591 } else {
pcercuei 0:03b5121a232e 592 xmlFree(uri->fragment);
pcercuei 0:03b5121a232e 593 }
pcercuei 0:03b5121a232e 594 } else {
pcercuei 0:03b5121a232e 595 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_FRAGMENT_ID,
pcercuei 0:03b5121a232e 596 "Invalid fragment identifier in URI %s use the xpointer attribute\n",
pcercuei 0:03b5121a232e 597 URI);
pcercuei 0:03b5121a232e 598 if (fragment != NULL)
pcercuei 0:03b5121a232e 599 xmlFree(fragment);
pcercuei 0:03b5121a232e 600 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 601 xmlFree(URI);
pcercuei 0:03b5121a232e 602 return(-1);
pcercuei 0:03b5121a232e 603 }
pcercuei 0:03b5121a232e 604 uri->fragment = NULL;
pcercuei 0:03b5121a232e 605 }
pcercuei 0:03b5121a232e 606 URL = xmlSaveUri(uri);
pcercuei 0:03b5121a232e 607 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 608 xmlFree(URI);
pcercuei 0:03b5121a232e 609 if (URL == NULL) {
pcercuei 0:03b5121a232e 610 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 611 "invalid value URI %s\n", URI);
pcercuei 0:03b5121a232e 612 if (fragment != NULL)
pcercuei 0:03b5121a232e 613 xmlFree(fragment);
pcercuei 0:03b5121a232e 614 return(-1);
pcercuei 0:03b5121a232e 615 }
pcercuei 0:03b5121a232e 616
pcercuei 0:03b5121a232e 617 /*
pcercuei 0:03b5121a232e 618 * If local and xml then we need a fragment
pcercuei 0:03b5121a232e 619 */
pcercuei 0:03b5121a232e 620 if ((local == 1) && (xml == 1) &&
pcercuei 0:03b5121a232e 621 ((fragment == NULL) || (fragment[0] == 0))) {
pcercuei 0:03b5121a232e 622 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION,
pcercuei 0:03b5121a232e 623 "detected a local recursion with no xpointer in %s\n",
pcercuei 0:03b5121a232e 624 URL);
pcercuei 0:03b5121a232e 625 if (fragment != NULL)
pcercuei 0:03b5121a232e 626 xmlFree(fragment);
pcercuei 0:03b5121a232e 627 return(-1);
pcercuei 0:03b5121a232e 628 }
pcercuei 0:03b5121a232e 629
pcercuei 0:03b5121a232e 630 /*
pcercuei 0:03b5121a232e 631 * Check the URL against the stack for recursions
pcercuei 0:03b5121a232e 632 */
pcercuei 0:03b5121a232e 633 if ((!local) && (xml == 1)) {
pcercuei 0:03b5121a232e 634 for (i = 0;i < ctxt->urlNr;i++) {
pcercuei 0:03b5121a232e 635 if (xmlStrEqual(URL, ctxt->urlTab[i])) {
pcercuei 0:03b5121a232e 636 xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION,
pcercuei 0:03b5121a232e 637 "detected a recursion in %s\n", URL);
pcercuei 0:03b5121a232e 638 return(-1);
pcercuei 0:03b5121a232e 639 }
pcercuei 0:03b5121a232e 640 }
pcercuei 0:03b5121a232e 641 }
pcercuei 0:03b5121a232e 642
pcercuei 0:03b5121a232e 643 ref = xmlXIncludeNewRef(ctxt, URL, cur);
pcercuei 0:03b5121a232e 644 if (ref == NULL) {
pcercuei 0:03b5121a232e 645 return(-1);
pcercuei 0:03b5121a232e 646 }
pcercuei 0:03b5121a232e 647 ref->fragment = fragment;
pcercuei 0:03b5121a232e 648 ref->doc = NULL;
pcercuei 0:03b5121a232e 649 ref->xml = xml;
pcercuei 0:03b5121a232e 650 ref->count = 1;
pcercuei 0:03b5121a232e 651 xmlFree(URL);
pcercuei 0:03b5121a232e 652 return(0);
pcercuei 0:03b5121a232e 653 }
pcercuei 0:03b5121a232e 654
pcercuei 0:03b5121a232e 655 /**
pcercuei 0:03b5121a232e 656 * xmlXIncludeRecurseDoc:
pcercuei 0:03b5121a232e 657 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 658 * @doc: the new document
pcercuei 0:03b5121a232e 659 * @url: the associated URL
pcercuei 0:03b5121a232e 660 *
pcercuei 0:03b5121a232e 661 * The XInclude recursive nature is handled at this point.
pcercuei 0:03b5121a232e 662 */
pcercuei 0:03b5121a232e 663 static void
pcercuei 0:03b5121a232e 664 xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
pcercuei 0:03b5121a232e 665 const xmlURL url ATTRIBUTE_UNUSED) {
pcercuei 0:03b5121a232e 666 xmlXIncludeCtxtPtr newctxt;
pcercuei 0:03b5121a232e 667 int i;
pcercuei 0:03b5121a232e 668
pcercuei 0:03b5121a232e 669 /*
pcercuei 0:03b5121a232e 670 * Avoid recursion in already substitued resources
pcercuei 0:03b5121a232e 671 for (i = 0;i < ctxt->urlNr;i++) {
pcercuei 0:03b5121a232e 672 if (xmlStrEqual(doc->URL, ctxt->urlTab[i]))
pcercuei 0:03b5121a232e 673 return;
pcercuei 0:03b5121a232e 674 }
pcercuei 0:03b5121a232e 675 */
pcercuei 0:03b5121a232e 676
pcercuei 0:03b5121a232e 677 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 678 xmlGenericError(xmlGenericErrorContext, "Recursing in doc %s\n", doc->URL);
pcercuei 0:03b5121a232e 679 #endif
pcercuei 0:03b5121a232e 680 /*
pcercuei 0:03b5121a232e 681 * Handle recursion here.
pcercuei 0:03b5121a232e 682 */
pcercuei 0:03b5121a232e 683
pcercuei 0:03b5121a232e 684 newctxt = xmlXIncludeNewContext(doc);
pcercuei 0:03b5121a232e 685 if (newctxt != NULL) {
pcercuei 0:03b5121a232e 686 /*
pcercuei 0:03b5121a232e 687 * Copy the private user data
pcercuei 0:03b5121a232e 688 */
pcercuei 0:03b5121a232e 689 newctxt->_private = ctxt->_private;
pcercuei 0:03b5121a232e 690 /*
pcercuei 0:03b5121a232e 691 * Copy the existing document set
pcercuei 0:03b5121a232e 692 */
pcercuei 0:03b5121a232e 693 newctxt->incMax = ctxt->incMax;
pcercuei 0:03b5121a232e 694 newctxt->incNr = ctxt->incNr;
pcercuei 0:03b5121a232e 695 newctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(newctxt->incMax *
pcercuei 0:03b5121a232e 696 sizeof(newctxt->incTab[0]));
pcercuei 0:03b5121a232e 697 if (newctxt->incTab == NULL) {
pcercuei 0:03b5121a232e 698 xmlXIncludeErrMemory(ctxt, (xmlNodePtr) doc, "processing doc");
pcercuei 0:03b5121a232e 699 xmlFree(newctxt);
pcercuei 0:03b5121a232e 700 return;
pcercuei 0:03b5121a232e 701 }
pcercuei 0:03b5121a232e 702 /*
pcercuei 0:03b5121a232e 703 * copy the urlTab
pcercuei 0:03b5121a232e 704 */
pcercuei 0:03b5121a232e 705 newctxt->urlMax = ctxt->urlMax;
pcercuei 0:03b5121a232e 706 newctxt->urlNr = ctxt->urlNr;
pcercuei 0:03b5121a232e 707 newctxt->urlTab = ctxt->urlTab;
pcercuei 0:03b5121a232e 708
pcercuei 0:03b5121a232e 709 /*
pcercuei 0:03b5121a232e 710 * Inherit the existing base
pcercuei 0:03b5121a232e 711 */
pcercuei 0:03b5121a232e 712 newctxt->base = xmlStrdup(ctxt->base);
pcercuei 0:03b5121a232e 713
pcercuei 0:03b5121a232e 714 /*
pcercuei 0:03b5121a232e 715 * Inherit the documents already in use by other includes
pcercuei 0:03b5121a232e 716 */
pcercuei 0:03b5121a232e 717 newctxt->incBase = ctxt->incNr;
pcercuei 0:03b5121a232e 718 for (i = 0;i < ctxt->incNr;i++) {
pcercuei 0:03b5121a232e 719 newctxt->incTab[i] = ctxt->incTab[i];
pcercuei 0:03b5121a232e 720 newctxt->incTab[i]->count++; /* prevent the recursion from
pcercuei 0:03b5121a232e 721 freeing it */
pcercuei 0:03b5121a232e 722 }
pcercuei 0:03b5121a232e 723 /*
pcercuei 0:03b5121a232e 724 * The new context should also inherit the Parse Flags
pcercuei 0:03b5121a232e 725 * (bug 132597)
pcercuei 0:03b5121a232e 726 */
pcercuei 0:03b5121a232e 727 newctxt->parseFlags = ctxt->parseFlags;
pcercuei 0:03b5121a232e 728 xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc));
pcercuei 0:03b5121a232e 729 for (i = 0;i < ctxt->incNr;i++) {
pcercuei 0:03b5121a232e 730 newctxt->incTab[i]->count--;
pcercuei 0:03b5121a232e 731 newctxt->incTab[i] = NULL;
pcercuei 0:03b5121a232e 732 }
pcercuei 0:03b5121a232e 733
pcercuei 0:03b5121a232e 734 /* urlTab may have been reallocated */
pcercuei 0:03b5121a232e 735 ctxt->urlTab = newctxt->urlTab;
pcercuei 0:03b5121a232e 736 ctxt->urlMax = newctxt->urlMax;
pcercuei 0:03b5121a232e 737
pcercuei 0:03b5121a232e 738 newctxt->urlMax = 0;
pcercuei 0:03b5121a232e 739 newctxt->urlNr = 0;
pcercuei 0:03b5121a232e 740 newctxt->urlTab = NULL;
pcercuei 0:03b5121a232e 741
pcercuei 0:03b5121a232e 742 xmlXIncludeFreeContext(newctxt);
pcercuei 0:03b5121a232e 743 }
pcercuei 0:03b5121a232e 744 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 745 xmlGenericError(xmlGenericErrorContext, "Done recursing in doc %s\n", url);
pcercuei 0:03b5121a232e 746 #endif
pcercuei 0:03b5121a232e 747 }
pcercuei 0:03b5121a232e 748
pcercuei 0:03b5121a232e 749 /**
pcercuei 0:03b5121a232e 750 * xmlXIncludeAddTxt:
pcercuei 0:03b5121a232e 751 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 752 * @txt: the new text node
pcercuei 0:03b5121a232e 753 * @url: the associated URL
pcercuei 0:03b5121a232e 754 *
pcercuei 0:03b5121a232e 755 * Add a new txtument to the list
pcercuei 0:03b5121a232e 756 */
pcercuei 0:03b5121a232e 757 static void
pcercuei 0:03b5121a232e 758 xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) {
pcercuei 0:03b5121a232e 759 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 760 xmlGenericError(xmlGenericErrorContext, "Adding text %s\n", url);
pcercuei 0:03b5121a232e 761 #endif
pcercuei 0:03b5121a232e 762 if (ctxt->txtMax == 0) {
pcercuei 0:03b5121a232e 763 ctxt->txtMax = 4;
pcercuei 0:03b5121a232e 764 ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
pcercuei 0:03b5121a232e 765 sizeof(ctxt->txtTab[0]));
pcercuei 0:03b5121a232e 766 if (ctxt->txtTab == NULL) {
pcercuei 0:03b5121a232e 767 xmlXIncludeErrMemory(ctxt, NULL, "processing text");
pcercuei 0:03b5121a232e 768 return;
pcercuei 0:03b5121a232e 769 }
pcercuei 0:03b5121a232e 770 ctxt->txturlTab = (xmlURL *) xmlMalloc(ctxt->txtMax *
pcercuei 0:03b5121a232e 771 sizeof(ctxt->txturlTab[0]));
pcercuei 0:03b5121a232e 772 if (ctxt->txturlTab == NULL) {
pcercuei 0:03b5121a232e 773 xmlXIncludeErrMemory(ctxt, NULL, "processing text");
pcercuei 0:03b5121a232e 774 return;
pcercuei 0:03b5121a232e 775 }
pcercuei 0:03b5121a232e 776 }
pcercuei 0:03b5121a232e 777 if (ctxt->txtNr >= ctxt->txtMax) {
pcercuei 0:03b5121a232e 778 ctxt->txtMax *= 2;
pcercuei 0:03b5121a232e 779 ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
pcercuei 0:03b5121a232e 780 ctxt->txtMax * sizeof(ctxt->txtTab[0]));
pcercuei 0:03b5121a232e 781 if (ctxt->txtTab == NULL) {
pcercuei 0:03b5121a232e 782 xmlXIncludeErrMemory(ctxt, NULL, "processing text");
pcercuei 0:03b5121a232e 783 return;
pcercuei 0:03b5121a232e 784 }
pcercuei 0:03b5121a232e 785 ctxt->txturlTab = (xmlURL *) xmlRealloc(ctxt->txturlTab,
pcercuei 0:03b5121a232e 786 ctxt->txtMax * sizeof(ctxt->txturlTab[0]));
pcercuei 0:03b5121a232e 787 if (ctxt->txturlTab == NULL) {
pcercuei 0:03b5121a232e 788 xmlXIncludeErrMemory(ctxt, NULL, "processing text");
pcercuei 0:03b5121a232e 789 return;
pcercuei 0:03b5121a232e 790 }
pcercuei 0:03b5121a232e 791 }
pcercuei 0:03b5121a232e 792 ctxt->txtTab[ctxt->txtNr] = txt;
pcercuei 0:03b5121a232e 793 ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url);
pcercuei 0:03b5121a232e 794 ctxt->txtNr++;
pcercuei 0:03b5121a232e 795 }
pcercuei 0:03b5121a232e 796
pcercuei 0:03b5121a232e 797 /************************************************************************
pcercuei 0:03b5121a232e 798 * *
pcercuei 0:03b5121a232e 799 * Node copy with specific semantic *
pcercuei 0:03b5121a232e 800 * *
pcercuei 0:03b5121a232e 801 ************************************************************************/
pcercuei 0:03b5121a232e 802
pcercuei 0:03b5121a232e 803 static xmlNodePtr
pcercuei 0:03b5121a232e 804 xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
pcercuei 0:03b5121a232e 805 xmlDocPtr source, xmlNodePtr elem);
pcercuei 0:03b5121a232e 806
pcercuei 0:03b5121a232e 807 /**
pcercuei 0:03b5121a232e 808 * xmlXIncludeCopyNode:
pcercuei 0:03b5121a232e 809 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 810 * @target: the document target
pcercuei 0:03b5121a232e 811 * @source: the document source
pcercuei 0:03b5121a232e 812 * @elem: the element
pcercuei 0:03b5121a232e 813 *
pcercuei 0:03b5121a232e 814 * Make a copy of the node while preserving the XInclude semantic
pcercuei 0:03b5121a232e 815 * of the Infoset copy
pcercuei 0:03b5121a232e 816 */
pcercuei 0:03b5121a232e 817 static xmlNodePtr
pcercuei 0:03b5121a232e 818 xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
pcercuei 0:03b5121a232e 819 xmlDocPtr source, xmlNodePtr elem) {
pcercuei 0:03b5121a232e 820 xmlNodePtr result = NULL;
pcercuei 0:03b5121a232e 821
pcercuei 0:03b5121a232e 822 if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
pcercuei 0:03b5121a232e 823 (elem == NULL))
pcercuei 0:03b5121a232e 824 return(NULL);
pcercuei 0:03b5121a232e 825 if (elem->type == XML_DTD_NODE)
pcercuei 0:03b5121a232e 826 return(NULL);
pcercuei 0:03b5121a232e 827 if (elem->type == XML_DOCUMENT_NODE)
pcercuei 0:03b5121a232e 828 result = xmlXIncludeCopyNodeList(ctxt, target, source, elem->children);
pcercuei 0:03b5121a232e 829 else
pcercuei 0:03b5121a232e 830 result = xmlDocCopyNode(elem, target, 1);
pcercuei 0:03b5121a232e 831 return(result);
pcercuei 0:03b5121a232e 832 }
pcercuei 0:03b5121a232e 833
pcercuei 0:03b5121a232e 834 /**
pcercuei 0:03b5121a232e 835 * xmlXIncludeCopyNodeList:
pcercuei 0:03b5121a232e 836 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 837 * @target: the document target
pcercuei 0:03b5121a232e 838 * @source: the document source
pcercuei 0:03b5121a232e 839 * @elem: the element list
pcercuei 0:03b5121a232e 840 *
pcercuei 0:03b5121a232e 841 * Make a copy of the node list while preserving the XInclude semantic
pcercuei 0:03b5121a232e 842 * of the Infoset copy
pcercuei 0:03b5121a232e 843 */
pcercuei 0:03b5121a232e 844 static xmlNodePtr
pcercuei 0:03b5121a232e 845 xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
pcercuei 0:03b5121a232e 846 xmlDocPtr source, xmlNodePtr elem) {
pcercuei 0:03b5121a232e 847 xmlNodePtr cur, res, result = NULL, last = NULL;
pcercuei 0:03b5121a232e 848
pcercuei 0:03b5121a232e 849 if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
pcercuei 0:03b5121a232e 850 (elem == NULL))
pcercuei 0:03b5121a232e 851 return(NULL);
pcercuei 0:03b5121a232e 852 cur = elem;
pcercuei 0:03b5121a232e 853 while (cur != NULL) {
pcercuei 0:03b5121a232e 854 res = xmlXIncludeCopyNode(ctxt, target, source, cur);
pcercuei 0:03b5121a232e 855 if (res != NULL) {
pcercuei 0:03b5121a232e 856 if (result == NULL) {
pcercuei 0:03b5121a232e 857 result = last = res;
pcercuei 0:03b5121a232e 858 } else {
pcercuei 0:03b5121a232e 859 last->next = res;
pcercuei 0:03b5121a232e 860 res->prev = last;
pcercuei 0:03b5121a232e 861 last = res;
pcercuei 0:03b5121a232e 862 }
pcercuei 0:03b5121a232e 863 }
pcercuei 0:03b5121a232e 864 cur = cur->next;
pcercuei 0:03b5121a232e 865 }
pcercuei 0:03b5121a232e 866 return(result);
pcercuei 0:03b5121a232e 867 }
pcercuei 0:03b5121a232e 868
pcercuei 0:03b5121a232e 869 /**
pcercuei 0:03b5121a232e 870 * xmlXIncludeGetNthChild:
pcercuei 0:03b5121a232e 871 * @cur: the node
pcercuei 0:03b5121a232e 872 * @no: the child number
pcercuei 0:03b5121a232e 873 *
pcercuei 0:03b5121a232e 874 * Returns the @n'th element child of @cur or NULL
pcercuei 0:03b5121a232e 875 */
pcercuei 0:03b5121a232e 876 static xmlNodePtr
pcercuei 0:03b5121a232e 877 xmlXIncludeGetNthChild(xmlNodePtr cur, int no) {
pcercuei 0:03b5121a232e 878 int i;
pcercuei 0:03b5121a232e 879 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
pcercuei 0:03b5121a232e 880 return(NULL);
pcercuei 0:03b5121a232e 881 cur = cur->children;
pcercuei 0:03b5121a232e 882 for (i = 0;i <= no;cur = cur->next) {
pcercuei 0:03b5121a232e 883 if (cur == NULL)
pcercuei 0:03b5121a232e 884 return(cur);
pcercuei 0:03b5121a232e 885 if ((cur->type == XML_ELEMENT_NODE) ||
pcercuei 0:03b5121a232e 886 (cur->type == XML_DOCUMENT_NODE) ||
pcercuei 0:03b5121a232e 887 (cur->type == XML_HTML_DOCUMENT_NODE)) {
pcercuei 0:03b5121a232e 888 i++;
pcercuei 0:03b5121a232e 889 if (i == no)
pcercuei 0:03b5121a232e 890 break;
pcercuei 0:03b5121a232e 891 }
pcercuei 0:03b5121a232e 892 }
pcercuei 0:03b5121a232e 893 return(cur);
pcercuei 0:03b5121a232e 894 }
pcercuei 0:03b5121a232e 895
pcercuei 0:03b5121a232e 896 xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); /* in xpointer.c */
pcercuei 0:03b5121a232e 897 /**
pcercuei 0:03b5121a232e 898 * xmlXIncludeCopyRange:
pcercuei 0:03b5121a232e 899 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 900 * @target: the document target
pcercuei 0:03b5121a232e 901 * @source: the document source
pcercuei 0:03b5121a232e 902 * @obj: the XPointer result from the evaluation.
pcercuei 0:03b5121a232e 903 *
pcercuei 0:03b5121a232e 904 * Build a node list tree copy of the XPointer result.
pcercuei 0:03b5121a232e 905 *
pcercuei 0:03b5121a232e 906 * Returns an xmlNodePtr list or NULL.
pcercuei 0:03b5121a232e 907 * The caller has to free the node tree.
pcercuei 0:03b5121a232e 908 */
pcercuei 0:03b5121a232e 909 static xmlNodePtr
pcercuei 0:03b5121a232e 910 xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
pcercuei 0:03b5121a232e 911 xmlDocPtr source, xmlXPathObjectPtr range) {
pcercuei 0:03b5121a232e 912 /* pointers to generated nodes */
pcercuei 0:03b5121a232e 913 xmlNodePtr list = NULL, last = NULL, listParent = NULL;
pcercuei 0:03b5121a232e 914 xmlNodePtr tmp, tmp2;
pcercuei 0:03b5121a232e 915 /* pointers to traversal nodes */
pcercuei 0:03b5121a232e 916 xmlNodePtr start, cur, end;
pcercuei 0:03b5121a232e 917 int index1, index2;
pcercuei 0:03b5121a232e 918 int level = 0, lastLevel = 0, endLevel = 0, endFlag = 0;
pcercuei 0:03b5121a232e 919
pcercuei 0:03b5121a232e 920 if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
pcercuei 0:03b5121a232e 921 (range == NULL))
pcercuei 0:03b5121a232e 922 return(NULL);
pcercuei 0:03b5121a232e 923 if (range->type != XPATH_RANGE)
pcercuei 0:03b5121a232e 924 return(NULL);
pcercuei 0:03b5121a232e 925 start = (xmlNodePtr) range->user;
pcercuei 0:03b5121a232e 926
pcercuei 0:03b5121a232e 927 if ((start == NULL) || (start->type == XML_NAMESPACE_DECL))
pcercuei 0:03b5121a232e 928 return(NULL);
pcercuei 0:03b5121a232e 929 end = range->user2;
pcercuei 0:03b5121a232e 930 if (end == NULL)
pcercuei 0:03b5121a232e 931 return(xmlDocCopyNode(start, target, 1));
pcercuei 0:03b5121a232e 932 if (end->type == XML_NAMESPACE_DECL)
pcercuei 0:03b5121a232e 933 return(NULL);
pcercuei 0:03b5121a232e 934
pcercuei 0:03b5121a232e 935 cur = start;
pcercuei 0:03b5121a232e 936 index1 = range->index;
pcercuei 0:03b5121a232e 937 index2 = range->index2;
pcercuei 0:03b5121a232e 938 /*
pcercuei 0:03b5121a232e 939 * level is depth of the current node under consideration
pcercuei 0:03b5121a232e 940 * list is the pointer to the root of the output tree
pcercuei 0:03b5121a232e 941 * listParent is a pointer to the parent of output tree (within
pcercuei 0:03b5121a232e 942 the included file) in case we need to add another level
pcercuei 0:03b5121a232e 943 * last is a pointer to the last node added to the output tree
pcercuei 0:03b5121a232e 944 * lastLevel is the depth of last (relative to the root)
pcercuei 0:03b5121a232e 945 */
pcercuei 0:03b5121a232e 946 while (cur != NULL) {
pcercuei 0:03b5121a232e 947 /*
pcercuei 0:03b5121a232e 948 * Check if our output tree needs a parent
pcercuei 0:03b5121a232e 949 */
pcercuei 0:03b5121a232e 950 if (level < 0) {
pcercuei 0:03b5121a232e 951 while (level < 0) {
pcercuei 0:03b5121a232e 952 /* copy must include namespaces and properties */
pcercuei 0:03b5121a232e 953 tmp2 = xmlDocCopyNode(listParent, target, 2);
pcercuei 0:03b5121a232e 954 xmlAddChild(tmp2, list);
pcercuei 0:03b5121a232e 955 list = tmp2;
pcercuei 0:03b5121a232e 956 listParent = listParent->parent;
pcercuei 0:03b5121a232e 957 level++;
pcercuei 0:03b5121a232e 958 }
pcercuei 0:03b5121a232e 959 last = list;
pcercuei 0:03b5121a232e 960 lastLevel = 0;
pcercuei 0:03b5121a232e 961 }
pcercuei 0:03b5121a232e 962 /*
pcercuei 0:03b5121a232e 963 * Check whether we need to change our insertion point
pcercuei 0:03b5121a232e 964 */
pcercuei 0:03b5121a232e 965 while (level < lastLevel) {
pcercuei 0:03b5121a232e 966 last = last->parent;
pcercuei 0:03b5121a232e 967 lastLevel --;
pcercuei 0:03b5121a232e 968 }
pcercuei 0:03b5121a232e 969 if (cur == end) { /* Are we at the end of the range? */
pcercuei 0:03b5121a232e 970 if (cur->type == XML_TEXT_NODE) {
pcercuei 0:03b5121a232e 971 const xmlChar *content = cur->content;
pcercuei 0:03b5121a232e 972 int len;
pcercuei 0:03b5121a232e 973
pcercuei 0:03b5121a232e 974 if (content == NULL) {
pcercuei 0:03b5121a232e 975 tmp = xmlNewTextLen(NULL, 0);
pcercuei 0:03b5121a232e 976 } else {
pcercuei 0:03b5121a232e 977 len = index2;
pcercuei 0:03b5121a232e 978 if ((cur == start) && (index1 > 1)) {
pcercuei 0:03b5121a232e 979 content += (index1 - 1);
pcercuei 0:03b5121a232e 980 len -= (index1 - 1);
pcercuei 0:03b5121a232e 981 } else {
pcercuei 0:03b5121a232e 982 len = index2;
pcercuei 0:03b5121a232e 983 }
pcercuei 0:03b5121a232e 984 tmp = xmlNewTextLen(content, len);
pcercuei 0:03b5121a232e 985 }
pcercuei 0:03b5121a232e 986 /* single sub text node selection */
pcercuei 0:03b5121a232e 987 if (list == NULL)
pcercuei 0:03b5121a232e 988 return(tmp);
pcercuei 0:03b5121a232e 989 /* prune and return full set */
pcercuei 0:03b5121a232e 990 if (level == lastLevel)
pcercuei 0:03b5121a232e 991 xmlAddNextSibling(last, tmp);
pcercuei 0:03b5121a232e 992 else
pcercuei 0:03b5121a232e 993 xmlAddChild(last, tmp);
pcercuei 0:03b5121a232e 994 return(list);
pcercuei 0:03b5121a232e 995 } else { /* ending node not a text node */
pcercuei 0:03b5121a232e 996 endLevel = level; /* remember the level of the end node */
pcercuei 0:03b5121a232e 997 endFlag = 1;
pcercuei 0:03b5121a232e 998 /* last node - need to take care of properties + namespaces */
pcercuei 0:03b5121a232e 999 tmp = xmlDocCopyNode(cur, target, 2);
pcercuei 0:03b5121a232e 1000 if (list == NULL) {
pcercuei 0:03b5121a232e 1001 list = tmp;
pcercuei 0:03b5121a232e 1002 listParent = cur->parent;
pcercuei 0:03b5121a232e 1003 } else {
pcercuei 0:03b5121a232e 1004 if (level == lastLevel)
pcercuei 0:03b5121a232e 1005 xmlAddNextSibling(last, tmp);
pcercuei 0:03b5121a232e 1006 else {
pcercuei 0:03b5121a232e 1007 xmlAddChild(last, tmp);
pcercuei 0:03b5121a232e 1008 lastLevel = level;
pcercuei 0:03b5121a232e 1009 }
pcercuei 0:03b5121a232e 1010 }
pcercuei 0:03b5121a232e 1011 last = tmp;
pcercuei 0:03b5121a232e 1012
pcercuei 0:03b5121a232e 1013 if (index2 > 1) {
pcercuei 0:03b5121a232e 1014 end = xmlXIncludeGetNthChild(cur, index2 - 1);
pcercuei 0:03b5121a232e 1015 index2 = 0;
pcercuei 0:03b5121a232e 1016 }
pcercuei 0:03b5121a232e 1017 if ((cur == start) && (index1 > 1)) {
pcercuei 0:03b5121a232e 1018 cur = xmlXIncludeGetNthChild(cur, index1 - 1);
pcercuei 0:03b5121a232e 1019 index1 = 0;
pcercuei 0:03b5121a232e 1020 } else {
pcercuei 0:03b5121a232e 1021 cur = cur->children;
pcercuei 0:03b5121a232e 1022 }
pcercuei 0:03b5121a232e 1023 level++; /* increment level to show change */
pcercuei 0:03b5121a232e 1024 /*
pcercuei 0:03b5121a232e 1025 * Now gather the remaining nodes from cur to end
pcercuei 0:03b5121a232e 1026 */
pcercuei 0:03b5121a232e 1027 continue; /* while */
pcercuei 0:03b5121a232e 1028 }
pcercuei 0:03b5121a232e 1029 } else if (cur == start) { /* Not at the end, are we at start? */
pcercuei 0:03b5121a232e 1030 if ((cur->type == XML_TEXT_NODE) ||
pcercuei 0:03b5121a232e 1031 (cur->type == XML_CDATA_SECTION_NODE)) {
pcercuei 0:03b5121a232e 1032 const xmlChar *content = cur->content;
pcercuei 0:03b5121a232e 1033
pcercuei 0:03b5121a232e 1034 if (content == NULL) {
pcercuei 0:03b5121a232e 1035 tmp = xmlNewTextLen(NULL, 0);
pcercuei 0:03b5121a232e 1036 } else {
pcercuei 0:03b5121a232e 1037 if (index1 > 1) {
pcercuei 0:03b5121a232e 1038 content += (index1 - 1);
pcercuei 0:03b5121a232e 1039 index1 = 0;
pcercuei 0:03b5121a232e 1040 }
pcercuei 0:03b5121a232e 1041 tmp = xmlNewText(content);
pcercuei 0:03b5121a232e 1042 }
pcercuei 0:03b5121a232e 1043 last = list = tmp;
pcercuei 0:03b5121a232e 1044 listParent = cur->parent;
pcercuei 0:03b5121a232e 1045 } else { /* Not text node */
pcercuei 0:03b5121a232e 1046 /*
pcercuei 0:03b5121a232e 1047 * start of the range - need to take care of
pcercuei 0:03b5121a232e 1048 * properties and namespaces
pcercuei 0:03b5121a232e 1049 */
pcercuei 0:03b5121a232e 1050 tmp = xmlDocCopyNode(cur, target, 2);
pcercuei 0:03b5121a232e 1051 list = last = tmp;
pcercuei 0:03b5121a232e 1052 listParent = cur->parent;
pcercuei 0:03b5121a232e 1053 if (index1 > 1) { /* Do we need to position? */
pcercuei 0:03b5121a232e 1054 cur = xmlXIncludeGetNthChild(cur, index1 - 1);
pcercuei 0:03b5121a232e 1055 level = lastLevel = 1;
pcercuei 0:03b5121a232e 1056 index1 = 0;
pcercuei 0:03b5121a232e 1057 /*
pcercuei 0:03b5121a232e 1058 * Now gather the remaining nodes from cur to end
pcercuei 0:03b5121a232e 1059 */
pcercuei 0:03b5121a232e 1060 continue; /* while */
pcercuei 0:03b5121a232e 1061 }
pcercuei 0:03b5121a232e 1062 }
pcercuei 0:03b5121a232e 1063 } else {
pcercuei 0:03b5121a232e 1064 tmp = NULL;
pcercuei 0:03b5121a232e 1065 switch (cur->type) {
pcercuei 0:03b5121a232e 1066 case XML_DTD_NODE:
pcercuei 0:03b5121a232e 1067 case XML_ELEMENT_DECL:
pcercuei 0:03b5121a232e 1068 case XML_ATTRIBUTE_DECL:
pcercuei 0:03b5121a232e 1069 case XML_ENTITY_NODE:
pcercuei 0:03b5121a232e 1070 /* Do not copy DTD informations */
pcercuei 0:03b5121a232e 1071 break;
pcercuei 0:03b5121a232e 1072 case XML_ENTITY_DECL:
pcercuei 0:03b5121a232e 1073 /* handle crossing entities -> stack needed */
pcercuei 0:03b5121a232e 1074 break;
pcercuei 0:03b5121a232e 1075 case XML_XINCLUDE_START:
pcercuei 0:03b5121a232e 1076 case XML_XINCLUDE_END:
pcercuei 0:03b5121a232e 1077 /* don't consider it part of the tree content */
pcercuei 0:03b5121a232e 1078 break;
pcercuei 0:03b5121a232e 1079 case XML_ATTRIBUTE_NODE:
pcercuei 0:03b5121a232e 1080 /* Humm, should not happen ! */
pcercuei 0:03b5121a232e 1081 break;
pcercuei 0:03b5121a232e 1082 default:
pcercuei 0:03b5121a232e 1083 /*
pcercuei 0:03b5121a232e 1084 * Middle of the range - need to take care of
pcercuei 0:03b5121a232e 1085 * properties and namespaces
pcercuei 0:03b5121a232e 1086 */
pcercuei 0:03b5121a232e 1087 tmp = xmlDocCopyNode(cur, target, 2);
pcercuei 0:03b5121a232e 1088 break;
pcercuei 0:03b5121a232e 1089 }
pcercuei 0:03b5121a232e 1090 if (tmp != NULL) {
pcercuei 0:03b5121a232e 1091 if (level == lastLevel)
pcercuei 0:03b5121a232e 1092 xmlAddNextSibling(last, tmp);
pcercuei 0:03b5121a232e 1093 else {
pcercuei 0:03b5121a232e 1094 xmlAddChild(last, tmp);
pcercuei 0:03b5121a232e 1095 lastLevel = level;
pcercuei 0:03b5121a232e 1096 }
pcercuei 0:03b5121a232e 1097 last = tmp;
pcercuei 0:03b5121a232e 1098 }
pcercuei 0:03b5121a232e 1099 }
pcercuei 0:03b5121a232e 1100 /*
pcercuei 0:03b5121a232e 1101 * Skip to next node in document order
pcercuei 0:03b5121a232e 1102 */
pcercuei 0:03b5121a232e 1103 cur = xmlXPtrAdvanceNode(cur, &level);
pcercuei 0:03b5121a232e 1104 if (endFlag && (level >= endLevel))
pcercuei 0:03b5121a232e 1105 break;
pcercuei 0:03b5121a232e 1106 }
pcercuei 0:03b5121a232e 1107 return(list);
pcercuei 0:03b5121a232e 1108 }
pcercuei 0:03b5121a232e 1109
pcercuei 0:03b5121a232e 1110 /**
pcercuei 0:03b5121a232e 1111 * xmlXIncludeBuildNodeList:
pcercuei 0:03b5121a232e 1112 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 1113 * @target: the document target
pcercuei 0:03b5121a232e 1114 * @source: the document source
pcercuei 0:03b5121a232e 1115 * @obj: the XPointer result from the evaluation.
pcercuei 0:03b5121a232e 1116 *
pcercuei 0:03b5121a232e 1117 * Build a node list tree copy of the XPointer result.
pcercuei 0:03b5121a232e 1118 * This will drop Attributes and Namespace declarations.
pcercuei 0:03b5121a232e 1119 *
pcercuei 0:03b5121a232e 1120 * Returns an xmlNodePtr list or NULL.
pcercuei 0:03b5121a232e 1121 * the caller has to free the node tree.
pcercuei 0:03b5121a232e 1122 */
pcercuei 0:03b5121a232e 1123 static xmlNodePtr
pcercuei 0:03b5121a232e 1124 xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
pcercuei 0:03b5121a232e 1125 xmlDocPtr source, xmlXPathObjectPtr obj) {
pcercuei 0:03b5121a232e 1126 xmlNodePtr list = NULL, last = NULL;
pcercuei 0:03b5121a232e 1127 int i;
pcercuei 0:03b5121a232e 1128
pcercuei 0:03b5121a232e 1129 if (source == NULL)
pcercuei 0:03b5121a232e 1130 source = ctxt->doc;
pcercuei 0:03b5121a232e 1131 if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
pcercuei 0:03b5121a232e 1132 (obj == NULL))
pcercuei 0:03b5121a232e 1133 return(NULL);
pcercuei 0:03b5121a232e 1134 switch (obj->type) {
pcercuei 0:03b5121a232e 1135 case XPATH_NODESET: {
pcercuei 0:03b5121a232e 1136 xmlNodeSetPtr set = obj->nodesetval;
pcercuei 0:03b5121a232e 1137 if (set == NULL)
pcercuei 0:03b5121a232e 1138 return(NULL);
pcercuei 0:03b5121a232e 1139 for (i = 0;i < set->nodeNr;i++) {
pcercuei 0:03b5121a232e 1140 if (set->nodeTab[i] == NULL)
pcercuei 0:03b5121a232e 1141 continue;
pcercuei 0:03b5121a232e 1142 switch (set->nodeTab[i]->type) {
pcercuei 0:03b5121a232e 1143 case XML_TEXT_NODE:
pcercuei 0:03b5121a232e 1144 case XML_CDATA_SECTION_NODE:
pcercuei 0:03b5121a232e 1145 case XML_ELEMENT_NODE:
pcercuei 0:03b5121a232e 1146 case XML_ENTITY_REF_NODE:
pcercuei 0:03b5121a232e 1147 case XML_ENTITY_NODE:
pcercuei 0:03b5121a232e 1148 case XML_PI_NODE:
pcercuei 0:03b5121a232e 1149 case XML_COMMENT_NODE:
pcercuei 0:03b5121a232e 1150 case XML_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 1151 case XML_HTML_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 1152 #ifdef LIBXML_DOCB_ENABLED
pcercuei 0:03b5121a232e 1153 case XML_DOCB_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 1154 #endif
pcercuei 0:03b5121a232e 1155 case XML_XINCLUDE_END:
pcercuei 0:03b5121a232e 1156 break;
pcercuei 0:03b5121a232e 1157 case XML_XINCLUDE_START: {
pcercuei 0:03b5121a232e 1158 xmlNodePtr tmp, cur = set->nodeTab[i];
pcercuei 0:03b5121a232e 1159
pcercuei 0:03b5121a232e 1160 cur = cur->next;
pcercuei 0:03b5121a232e 1161 while (cur != NULL) {
pcercuei 0:03b5121a232e 1162 switch(cur->type) {
pcercuei 0:03b5121a232e 1163 case XML_TEXT_NODE:
pcercuei 0:03b5121a232e 1164 case XML_CDATA_SECTION_NODE:
pcercuei 0:03b5121a232e 1165 case XML_ELEMENT_NODE:
pcercuei 0:03b5121a232e 1166 case XML_ENTITY_REF_NODE:
pcercuei 0:03b5121a232e 1167 case XML_ENTITY_NODE:
pcercuei 0:03b5121a232e 1168 case XML_PI_NODE:
pcercuei 0:03b5121a232e 1169 case XML_COMMENT_NODE:
pcercuei 0:03b5121a232e 1170 tmp = xmlXIncludeCopyNode(ctxt, target,
pcercuei 0:03b5121a232e 1171 source, cur);
pcercuei 0:03b5121a232e 1172 if (last == NULL) {
pcercuei 0:03b5121a232e 1173 list = last = tmp;
pcercuei 0:03b5121a232e 1174 } else {
pcercuei 0:03b5121a232e 1175 xmlAddNextSibling(last, tmp);
pcercuei 0:03b5121a232e 1176 last = tmp;
pcercuei 0:03b5121a232e 1177 }
pcercuei 0:03b5121a232e 1178 cur = cur->next;
pcercuei 0:03b5121a232e 1179 continue;
pcercuei 0:03b5121a232e 1180 default:
pcercuei 0:03b5121a232e 1181 break;
pcercuei 0:03b5121a232e 1182 }
pcercuei 0:03b5121a232e 1183 break;
pcercuei 0:03b5121a232e 1184 }
pcercuei 0:03b5121a232e 1185 continue;
pcercuei 0:03b5121a232e 1186 }
pcercuei 0:03b5121a232e 1187 case XML_ATTRIBUTE_NODE:
pcercuei 0:03b5121a232e 1188 case XML_NAMESPACE_DECL:
pcercuei 0:03b5121a232e 1189 case XML_DOCUMENT_TYPE_NODE:
pcercuei 0:03b5121a232e 1190 case XML_DOCUMENT_FRAG_NODE:
pcercuei 0:03b5121a232e 1191 case XML_NOTATION_NODE:
pcercuei 0:03b5121a232e 1192 case XML_DTD_NODE:
pcercuei 0:03b5121a232e 1193 case XML_ELEMENT_DECL:
pcercuei 0:03b5121a232e 1194 case XML_ATTRIBUTE_DECL:
pcercuei 0:03b5121a232e 1195 case XML_ENTITY_DECL:
pcercuei 0:03b5121a232e 1196 continue; /* for */
pcercuei 0:03b5121a232e 1197 }
pcercuei 0:03b5121a232e 1198 if (last == NULL)
pcercuei 0:03b5121a232e 1199 list = last = xmlXIncludeCopyNode(ctxt, target, source,
pcercuei 0:03b5121a232e 1200 set->nodeTab[i]);
pcercuei 0:03b5121a232e 1201 else {
pcercuei 0:03b5121a232e 1202 xmlAddNextSibling(last,
pcercuei 0:03b5121a232e 1203 xmlXIncludeCopyNode(ctxt, target, source,
pcercuei 0:03b5121a232e 1204 set->nodeTab[i]));
pcercuei 0:03b5121a232e 1205 if (last->next != NULL)
pcercuei 0:03b5121a232e 1206 last = last->next;
pcercuei 0:03b5121a232e 1207 }
pcercuei 0:03b5121a232e 1208 }
pcercuei 0:03b5121a232e 1209 break;
pcercuei 0:03b5121a232e 1210 }
pcercuei 0:03b5121a232e 1211 #ifdef LIBXML_XPTR_ENABLED
pcercuei 0:03b5121a232e 1212 case XPATH_LOCATIONSET: {
pcercuei 0:03b5121a232e 1213 xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
pcercuei 0:03b5121a232e 1214 if (set == NULL)
pcercuei 0:03b5121a232e 1215 return(NULL);
pcercuei 0:03b5121a232e 1216 for (i = 0;i < set->locNr;i++) {
pcercuei 0:03b5121a232e 1217 if (last == NULL)
pcercuei 0:03b5121a232e 1218 list = last = xmlXIncludeCopyXPointer(ctxt, target, source,
pcercuei 0:03b5121a232e 1219 set->locTab[i]);
pcercuei 0:03b5121a232e 1220 else
pcercuei 0:03b5121a232e 1221 xmlAddNextSibling(last,
pcercuei 0:03b5121a232e 1222 xmlXIncludeCopyXPointer(ctxt, target, source,
pcercuei 0:03b5121a232e 1223 set->locTab[i]));
pcercuei 0:03b5121a232e 1224 if (last != NULL) {
pcercuei 0:03b5121a232e 1225 while (last->next != NULL)
pcercuei 0:03b5121a232e 1226 last = last->next;
pcercuei 0:03b5121a232e 1227 }
pcercuei 0:03b5121a232e 1228 }
pcercuei 0:03b5121a232e 1229 break;
pcercuei 0:03b5121a232e 1230 }
pcercuei 0:03b5121a232e 1231 case XPATH_RANGE:
pcercuei 0:03b5121a232e 1232 return(xmlXIncludeCopyRange(ctxt, target, source, obj));
pcercuei 0:03b5121a232e 1233 #endif
pcercuei 0:03b5121a232e 1234 case XPATH_POINT:
pcercuei 0:03b5121a232e 1235 /* points are ignored in XInclude */
pcercuei 0:03b5121a232e 1236 break;
pcercuei 0:03b5121a232e 1237 default:
pcercuei 0:03b5121a232e 1238 break;
pcercuei 0:03b5121a232e 1239 }
pcercuei 0:03b5121a232e 1240 return(list);
pcercuei 0:03b5121a232e 1241 }
pcercuei 0:03b5121a232e 1242 /************************************************************************
pcercuei 0:03b5121a232e 1243 * *
pcercuei 0:03b5121a232e 1244 * XInclude I/O handling *
pcercuei 0:03b5121a232e 1245 * *
pcercuei 0:03b5121a232e 1246 ************************************************************************/
pcercuei 0:03b5121a232e 1247
pcercuei 0:03b5121a232e 1248 typedef struct _xmlXIncludeMergeData xmlXIncludeMergeData;
pcercuei 0:03b5121a232e 1249 typedef xmlXIncludeMergeData *xmlXIncludeMergeDataPtr;
pcercuei 0:03b5121a232e 1250 struct _xmlXIncludeMergeData {
pcercuei 0:03b5121a232e 1251 xmlDocPtr doc;
pcercuei 0:03b5121a232e 1252 xmlXIncludeCtxtPtr ctxt;
pcercuei 0:03b5121a232e 1253 };
pcercuei 0:03b5121a232e 1254
pcercuei 0:03b5121a232e 1255 /**
pcercuei 0:03b5121a232e 1256 * xmlXIncludeMergeOneEntity:
pcercuei 0:03b5121a232e 1257 * @ent: the entity
pcercuei 0:03b5121a232e 1258 * @doc: the including doc
pcercuei 0:03b5121a232e 1259 * @nr: the entity name
pcercuei 0:03b5121a232e 1260 *
pcercuei 0:03b5121a232e 1261 * Inplements the merge of one entity
pcercuei 0:03b5121a232e 1262 */
pcercuei 0:03b5121a232e 1263 static void
pcercuei 0:03b5121a232e 1264 xmlXIncludeMergeEntity(xmlEntityPtr ent, xmlXIncludeMergeDataPtr data,
pcercuei 0:03b5121a232e 1265 xmlChar *name ATTRIBUTE_UNUSED) {
pcercuei 0:03b5121a232e 1266 xmlEntityPtr ret, prev;
pcercuei 0:03b5121a232e 1267 xmlDocPtr doc;
pcercuei 0:03b5121a232e 1268 xmlXIncludeCtxtPtr ctxt;
pcercuei 0:03b5121a232e 1269
pcercuei 0:03b5121a232e 1270 if ((ent == NULL) || (data == NULL))
pcercuei 0:03b5121a232e 1271 return;
pcercuei 0:03b5121a232e 1272 ctxt = data->ctxt;
pcercuei 0:03b5121a232e 1273 doc = data->doc;
pcercuei 0:03b5121a232e 1274 if ((ctxt == NULL) || (doc == NULL))
pcercuei 0:03b5121a232e 1275 return;
pcercuei 0:03b5121a232e 1276 switch (ent->etype) {
pcercuei 0:03b5121a232e 1277 case XML_INTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 1278 case XML_EXTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 1279 case XML_INTERNAL_PREDEFINED_ENTITY:
pcercuei 0:03b5121a232e 1280 return;
pcercuei 0:03b5121a232e 1281 case XML_INTERNAL_GENERAL_ENTITY:
pcercuei 0:03b5121a232e 1282 case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
pcercuei 0:03b5121a232e 1283 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
pcercuei 0:03b5121a232e 1284 break;
pcercuei 0:03b5121a232e 1285 }
pcercuei 0:03b5121a232e 1286 ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
pcercuei 0:03b5121a232e 1287 ent->SystemID, ent->content);
pcercuei 0:03b5121a232e 1288 if (ret != NULL) {
pcercuei 0:03b5121a232e 1289 if (ent->URI != NULL)
pcercuei 0:03b5121a232e 1290 ret->URI = xmlStrdup(ent->URI);
pcercuei 0:03b5121a232e 1291 } else {
pcercuei 0:03b5121a232e 1292 prev = xmlGetDocEntity(doc, ent->name);
pcercuei 0:03b5121a232e 1293 if (prev != NULL) {
pcercuei 0:03b5121a232e 1294 if (ent->etype != prev->etype)
pcercuei 0:03b5121a232e 1295 goto error;
pcercuei 0:03b5121a232e 1296
pcercuei 0:03b5121a232e 1297 if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
pcercuei 0:03b5121a232e 1298 if (!xmlStrEqual(ent->SystemID, prev->SystemID))
pcercuei 0:03b5121a232e 1299 goto error;
pcercuei 0:03b5121a232e 1300 } else if ((ent->ExternalID != NULL) &&
pcercuei 0:03b5121a232e 1301 (prev->ExternalID != NULL)) {
pcercuei 0:03b5121a232e 1302 if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
pcercuei 0:03b5121a232e 1303 goto error;
pcercuei 0:03b5121a232e 1304 } else if ((ent->content != NULL) && (prev->content != NULL)) {
pcercuei 0:03b5121a232e 1305 if (!xmlStrEqual(ent->content, prev->content))
pcercuei 0:03b5121a232e 1306 goto error;
pcercuei 0:03b5121a232e 1307 } else {
pcercuei 0:03b5121a232e 1308 goto error;
pcercuei 0:03b5121a232e 1309 }
pcercuei 0:03b5121a232e 1310
pcercuei 0:03b5121a232e 1311 }
pcercuei 0:03b5121a232e 1312 }
pcercuei 0:03b5121a232e 1313 return;
pcercuei 0:03b5121a232e 1314 error:
pcercuei 0:03b5121a232e 1315 switch (ent->etype) {
pcercuei 0:03b5121a232e 1316 case XML_INTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 1317 case XML_EXTERNAL_PARAMETER_ENTITY:
pcercuei 0:03b5121a232e 1318 case XML_INTERNAL_PREDEFINED_ENTITY:
pcercuei 0:03b5121a232e 1319 case XML_INTERNAL_GENERAL_ENTITY:
pcercuei 0:03b5121a232e 1320 case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
pcercuei 0:03b5121a232e 1321 return;
pcercuei 0:03b5121a232e 1322 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
pcercuei 0:03b5121a232e 1323 break;
pcercuei 0:03b5121a232e 1324 }
pcercuei 0:03b5121a232e 1325 xmlXIncludeErr(ctxt, (xmlNodePtr) ent, XML_XINCLUDE_ENTITY_DEF_MISMATCH,
pcercuei 0:03b5121a232e 1326 "mismatch in redefinition of entity %s\n",
pcercuei 0:03b5121a232e 1327 ent->name);
pcercuei 0:03b5121a232e 1328 }
pcercuei 0:03b5121a232e 1329
pcercuei 0:03b5121a232e 1330 /**
pcercuei 0:03b5121a232e 1331 * xmlXIncludeMergeEntities:
pcercuei 0:03b5121a232e 1332 * @ctxt: an XInclude context
pcercuei 0:03b5121a232e 1333 * @doc: the including doc
pcercuei 0:03b5121a232e 1334 * @from: the included doc
pcercuei 0:03b5121a232e 1335 *
pcercuei 0:03b5121a232e 1336 * Inplements the entity merge
pcercuei 0:03b5121a232e 1337 *
pcercuei 0:03b5121a232e 1338 * Returns 0 if merge succeeded, -1 if some processing failed
pcercuei 0:03b5121a232e 1339 */
pcercuei 0:03b5121a232e 1340 static int
pcercuei 0:03b5121a232e 1341 xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
pcercuei 0:03b5121a232e 1342 xmlDocPtr from) {
pcercuei 0:03b5121a232e 1343 xmlNodePtr cur;
pcercuei 0:03b5121a232e 1344 xmlDtdPtr target, source;
pcercuei 0:03b5121a232e 1345
pcercuei 0:03b5121a232e 1346 if (ctxt == NULL)
pcercuei 0:03b5121a232e 1347 return(-1);
pcercuei 0:03b5121a232e 1348
pcercuei 0:03b5121a232e 1349 if ((from == NULL) || (from->intSubset == NULL))
pcercuei 0:03b5121a232e 1350 return(0);
pcercuei 0:03b5121a232e 1351
pcercuei 0:03b5121a232e 1352 target = doc->intSubset;
pcercuei 0:03b5121a232e 1353 if (target == NULL) {
pcercuei 0:03b5121a232e 1354 cur = xmlDocGetRootElement(doc);
pcercuei 0:03b5121a232e 1355 if (cur == NULL)
pcercuei 0:03b5121a232e 1356 return(-1);
pcercuei 0:03b5121a232e 1357 target = xmlCreateIntSubset(doc, cur->name, NULL, NULL);
pcercuei 0:03b5121a232e 1358 if (target == NULL)
pcercuei 0:03b5121a232e 1359 return(-1);
pcercuei 0:03b5121a232e 1360 }
pcercuei 0:03b5121a232e 1361
pcercuei 0:03b5121a232e 1362 source = from->intSubset;
pcercuei 0:03b5121a232e 1363 if ((source != NULL) && (source->entities != NULL)) {
pcercuei 0:03b5121a232e 1364 xmlXIncludeMergeData data;
pcercuei 0:03b5121a232e 1365
pcercuei 0:03b5121a232e 1366 data.ctxt = ctxt;
pcercuei 0:03b5121a232e 1367 data.doc = doc;
pcercuei 0:03b5121a232e 1368
pcercuei 0:03b5121a232e 1369 xmlHashScan((xmlHashTablePtr) source->entities,
pcercuei 0:03b5121a232e 1370 (xmlHashScanner) xmlXIncludeMergeEntity, &data);
pcercuei 0:03b5121a232e 1371 }
pcercuei 0:03b5121a232e 1372 source = from->extSubset;
pcercuei 0:03b5121a232e 1373 if ((source != NULL) && (source->entities != NULL)) {
pcercuei 0:03b5121a232e 1374 xmlXIncludeMergeData data;
pcercuei 0:03b5121a232e 1375
pcercuei 0:03b5121a232e 1376 data.ctxt = ctxt;
pcercuei 0:03b5121a232e 1377 data.doc = doc;
pcercuei 0:03b5121a232e 1378
pcercuei 0:03b5121a232e 1379 /*
pcercuei 0:03b5121a232e 1380 * don't duplicate existing stuff when external subsets are the same
pcercuei 0:03b5121a232e 1381 */
pcercuei 0:03b5121a232e 1382 if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) &&
pcercuei 0:03b5121a232e 1383 (!xmlStrEqual(target->SystemID, source->SystemID))) {
pcercuei 0:03b5121a232e 1384 xmlHashScan((xmlHashTablePtr) source->entities,
pcercuei 0:03b5121a232e 1385 (xmlHashScanner) xmlXIncludeMergeEntity, &data);
pcercuei 0:03b5121a232e 1386 }
pcercuei 0:03b5121a232e 1387 }
pcercuei 0:03b5121a232e 1388 return(0);
pcercuei 0:03b5121a232e 1389 }
pcercuei 0:03b5121a232e 1390
pcercuei 0:03b5121a232e 1391 /**
pcercuei 0:03b5121a232e 1392 * xmlXIncludeLoadDoc:
pcercuei 0:03b5121a232e 1393 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 1394 * @url: the associated URL
pcercuei 0:03b5121a232e 1395 * @nr: the xinclude node number
pcercuei 0:03b5121a232e 1396 *
pcercuei 0:03b5121a232e 1397 * Load the document, and store the result in the XInclude context
pcercuei 0:03b5121a232e 1398 *
pcercuei 0:03b5121a232e 1399 * Returns 0 in case of success, -1 in case of failure
pcercuei 0:03b5121a232e 1400 */
pcercuei 0:03b5121a232e 1401 static int
pcercuei 0:03b5121a232e 1402 xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
pcercuei 0:03b5121a232e 1403 xmlDocPtr doc;
pcercuei 0:03b5121a232e 1404 xmlURIPtr uri;
pcercuei 0:03b5121a232e 1405 xmlChar *URL;
pcercuei 0:03b5121a232e 1406 xmlChar *fragment = NULL;
pcercuei 0:03b5121a232e 1407 int i = 0;
pcercuei 0:03b5121a232e 1408 #ifdef LIBXML_XPTR_ENABLED
pcercuei 0:03b5121a232e 1409 int saveFlags;
pcercuei 0:03b5121a232e 1410 #endif
pcercuei 0:03b5121a232e 1411
pcercuei 0:03b5121a232e 1412 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 1413 xmlGenericError(xmlGenericErrorContext, "Loading doc %s:%d\n", url, nr);
pcercuei 0:03b5121a232e 1414 #endif
pcercuei 0:03b5121a232e 1415 /*
pcercuei 0:03b5121a232e 1416 * Check the URL and remove any fragment identifier
pcercuei 0:03b5121a232e 1417 */
pcercuei 0:03b5121a232e 1418 uri = xmlParseURI((const char *)url);
pcercuei 0:03b5121a232e 1419 if (uri == NULL) {
pcercuei 0:03b5121a232e 1420 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1421 XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1422 "invalid value URI %s\n", url);
pcercuei 0:03b5121a232e 1423 return(-1);
pcercuei 0:03b5121a232e 1424 }
pcercuei 0:03b5121a232e 1425 if (uri->fragment != NULL) {
pcercuei 0:03b5121a232e 1426 fragment = (xmlChar *) uri->fragment;
pcercuei 0:03b5121a232e 1427 uri->fragment = NULL;
pcercuei 0:03b5121a232e 1428 }
pcercuei 0:03b5121a232e 1429 if ((ctxt->incTab != NULL) && (ctxt->incTab[nr] != NULL) &&
pcercuei 0:03b5121a232e 1430 (ctxt->incTab[nr]->fragment != NULL)) {
pcercuei 0:03b5121a232e 1431 if (fragment != NULL) xmlFree(fragment);
pcercuei 0:03b5121a232e 1432 fragment = xmlStrdup(ctxt->incTab[nr]->fragment);
pcercuei 0:03b5121a232e 1433 }
pcercuei 0:03b5121a232e 1434 URL = xmlSaveUri(uri);
pcercuei 0:03b5121a232e 1435 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 1436 if (URL == NULL) {
pcercuei 0:03b5121a232e 1437 if (ctxt->incTab != NULL)
pcercuei 0:03b5121a232e 1438 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1439 XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1440 "invalid value URI %s\n", url);
pcercuei 0:03b5121a232e 1441 else
pcercuei 0:03b5121a232e 1442 xmlXIncludeErr(ctxt, NULL,
pcercuei 0:03b5121a232e 1443 XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1444 "invalid value URI %s\n", url);
pcercuei 0:03b5121a232e 1445 if (fragment != NULL)
pcercuei 0:03b5121a232e 1446 xmlFree(fragment);
pcercuei 0:03b5121a232e 1447 return(-1);
pcercuei 0:03b5121a232e 1448 }
pcercuei 0:03b5121a232e 1449
pcercuei 0:03b5121a232e 1450 /*
pcercuei 0:03b5121a232e 1451 * Handling of references to the local document are done
pcercuei 0:03b5121a232e 1452 * directly through ctxt->doc.
pcercuei 0:03b5121a232e 1453 */
pcercuei 0:03b5121a232e 1454 if ((URL[0] == 0) || (URL[0] == '#') ||
pcercuei 0:03b5121a232e 1455 ((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) {
pcercuei 0:03b5121a232e 1456 doc = NULL;
pcercuei 0:03b5121a232e 1457 goto loaded;
pcercuei 0:03b5121a232e 1458 }
pcercuei 0:03b5121a232e 1459
pcercuei 0:03b5121a232e 1460 /*
pcercuei 0:03b5121a232e 1461 * Prevent reloading twice the document.
pcercuei 0:03b5121a232e 1462 */
pcercuei 0:03b5121a232e 1463 for (i = 0; i < ctxt->incNr; i++) {
pcercuei 0:03b5121a232e 1464 if ((xmlStrEqual(URL, ctxt->incTab[i]->URI)) &&
pcercuei 0:03b5121a232e 1465 (ctxt->incTab[i]->doc != NULL)) {
pcercuei 0:03b5121a232e 1466 doc = ctxt->incTab[i]->doc;
pcercuei 0:03b5121a232e 1467 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 1468 printf("Already loaded %s\n", URL);
pcercuei 0:03b5121a232e 1469 #endif
pcercuei 0:03b5121a232e 1470 goto loaded;
pcercuei 0:03b5121a232e 1471 }
pcercuei 0:03b5121a232e 1472 }
pcercuei 0:03b5121a232e 1473
pcercuei 0:03b5121a232e 1474 /*
pcercuei 0:03b5121a232e 1475 * Load it.
pcercuei 0:03b5121a232e 1476 */
pcercuei 0:03b5121a232e 1477 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 1478 printf("loading %s\n", URL);
pcercuei 0:03b5121a232e 1479 #endif
pcercuei 0:03b5121a232e 1480 #ifdef LIBXML_XPTR_ENABLED
pcercuei 0:03b5121a232e 1481 /*
pcercuei 0:03b5121a232e 1482 * If this is an XPointer evaluation, we want to assure that
pcercuei 0:03b5121a232e 1483 * all entities have been resolved prior to processing the
pcercuei 0:03b5121a232e 1484 * referenced document
pcercuei 0:03b5121a232e 1485 */
pcercuei 0:03b5121a232e 1486 saveFlags = ctxt->parseFlags;
pcercuei 0:03b5121a232e 1487 if (fragment != NULL) { /* if this is an XPointer eval */
pcercuei 0:03b5121a232e 1488 ctxt->parseFlags |= XML_PARSE_NOENT;
pcercuei 0:03b5121a232e 1489 }
pcercuei 0:03b5121a232e 1490 #endif
pcercuei 0:03b5121a232e 1491
pcercuei 0:03b5121a232e 1492 doc = xmlXIncludeParseFile(ctxt, (const char *)URL);
pcercuei 0:03b5121a232e 1493 #ifdef LIBXML_XPTR_ENABLED
pcercuei 0:03b5121a232e 1494 ctxt->parseFlags = saveFlags;
pcercuei 0:03b5121a232e 1495 #endif
pcercuei 0:03b5121a232e 1496 if (doc == NULL) {
pcercuei 0:03b5121a232e 1497 xmlFree(URL);
pcercuei 0:03b5121a232e 1498 if (fragment != NULL)
pcercuei 0:03b5121a232e 1499 xmlFree(fragment);
pcercuei 0:03b5121a232e 1500 return(-1);
pcercuei 0:03b5121a232e 1501 }
pcercuei 0:03b5121a232e 1502 ctxt->incTab[nr]->doc = doc;
pcercuei 0:03b5121a232e 1503 /*
pcercuei 0:03b5121a232e 1504 * It's possible that the requested URL has been mapped to a
pcercuei 0:03b5121a232e 1505 * completely different location (e.g. through a catalog entry).
pcercuei 0:03b5121a232e 1506 * To check for this, we compare the URL with that of the doc
pcercuei 0:03b5121a232e 1507 * and change it if they disagree (bug 146988).
pcercuei 0:03b5121a232e 1508 */
pcercuei 0:03b5121a232e 1509 if (!xmlStrEqual(URL, doc->URL)) {
pcercuei 0:03b5121a232e 1510 xmlFree(URL);
pcercuei 0:03b5121a232e 1511 URL = xmlStrdup(doc->URL);
pcercuei 0:03b5121a232e 1512 }
pcercuei 0:03b5121a232e 1513 for (i = nr + 1; i < ctxt->incNr; i++) {
pcercuei 0:03b5121a232e 1514 if (xmlStrEqual(URL, ctxt->incTab[i]->URI)) {
pcercuei 0:03b5121a232e 1515 ctxt->incTab[nr]->count++;
pcercuei 0:03b5121a232e 1516 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 1517 printf("Increasing %s count since reused\n", URL);
pcercuei 0:03b5121a232e 1518 #endif
pcercuei 0:03b5121a232e 1519 break;
pcercuei 0:03b5121a232e 1520 }
pcercuei 0:03b5121a232e 1521 }
pcercuei 0:03b5121a232e 1522
pcercuei 0:03b5121a232e 1523 /*
pcercuei 0:03b5121a232e 1524 * Make sure we have all entities fixed up
pcercuei 0:03b5121a232e 1525 */
pcercuei 0:03b5121a232e 1526 xmlXIncludeMergeEntities(ctxt, ctxt->doc, doc);
pcercuei 0:03b5121a232e 1527
pcercuei 0:03b5121a232e 1528 /*
pcercuei 0:03b5121a232e 1529 * We don't need the DTD anymore, free up space
pcercuei 0:03b5121a232e 1530 if (doc->intSubset != NULL) {
pcercuei 0:03b5121a232e 1531 xmlUnlinkNode((xmlNodePtr) doc->intSubset);
pcercuei 0:03b5121a232e 1532 xmlFreeNode((xmlNodePtr) doc->intSubset);
pcercuei 0:03b5121a232e 1533 doc->intSubset = NULL;
pcercuei 0:03b5121a232e 1534 }
pcercuei 0:03b5121a232e 1535 if (doc->extSubset != NULL) {
pcercuei 0:03b5121a232e 1536 xmlUnlinkNode((xmlNodePtr) doc->extSubset);
pcercuei 0:03b5121a232e 1537 xmlFreeNode((xmlNodePtr) doc->extSubset);
pcercuei 0:03b5121a232e 1538 doc->extSubset = NULL;
pcercuei 0:03b5121a232e 1539 }
pcercuei 0:03b5121a232e 1540 */
pcercuei 0:03b5121a232e 1541 xmlXIncludeRecurseDoc(ctxt, doc, URL);
pcercuei 0:03b5121a232e 1542
pcercuei 0:03b5121a232e 1543 loaded:
pcercuei 0:03b5121a232e 1544 if (fragment == NULL) {
pcercuei 0:03b5121a232e 1545 /*
pcercuei 0:03b5121a232e 1546 * Add the top children list as the replacement copy.
pcercuei 0:03b5121a232e 1547 */
pcercuei 0:03b5121a232e 1548 if (doc == NULL)
pcercuei 0:03b5121a232e 1549 {
pcercuei 0:03b5121a232e 1550 /* Hopefully a DTD declaration won't be copied from
pcercuei 0:03b5121a232e 1551 * the same document */
pcercuei 0:03b5121a232e 1552 ctxt->incTab[nr]->inc = xmlCopyNodeList(ctxt->doc->children);
pcercuei 0:03b5121a232e 1553 } else {
pcercuei 0:03b5121a232e 1554 ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc,
pcercuei 0:03b5121a232e 1555 doc, doc->children);
pcercuei 0:03b5121a232e 1556 }
pcercuei 0:03b5121a232e 1557 }
pcercuei 0:03b5121a232e 1558 #ifdef LIBXML_XPTR_ENABLED
pcercuei 0:03b5121a232e 1559 else {
pcercuei 0:03b5121a232e 1560 /*
pcercuei 0:03b5121a232e 1561 * Computes the XPointer expression and make a copy used
pcercuei 0:03b5121a232e 1562 * as the replacement copy.
pcercuei 0:03b5121a232e 1563 */
pcercuei 0:03b5121a232e 1564 xmlXPathObjectPtr xptr;
pcercuei 0:03b5121a232e 1565 xmlXPathContextPtr xptrctxt;
pcercuei 0:03b5121a232e 1566 xmlNodeSetPtr set;
pcercuei 0:03b5121a232e 1567
pcercuei 0:03b5121a232e 1568 if (doc == NULL) {
pcercuei 0:03b5121a232e 1569 xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1570 NULL);
pcercuei 0:03b5121a232e 1571 } else {
pcercuei 0:03b5121a232e 1572 xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
pcercuei 0:03b5121a232e 1573 }
pcercuei 0:03b5121a232e 1574 if (xptrctxt == NULL) {
pcercuei 0:03b5121a232e 1575 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1576 XML_XINCLUDE_XPTR_FAILED,
pcercuei 0:03b5121a232e 1577 "could not create XPointer context\n", NULL);
pcercuei 0:03b5121a232e 1578 xmlFree(URL);
pcercuei 0:03b5121a232e 1579 xmlFree(fragment);
pcercuei 0:03b5121a232e 1580 return(-1);
pcercuei 0:03b5121a232e 1581 }
pcercuei 0:03b5121a232e 1582 xptr = xmlXPtrEval(fragment, xptrctxt);
pcercuei 0:03b5121a232e 1583 if (xptr == NULL) {
pcercuei 0:03b5121a232e 1584 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1585 XML_XINCLUDE_XPTR_FAILED,
pcercuei 0:03b5121a232e 1586 "XPointer evaluation failed: #%s\n",
pcercuei 0:03b5121a232e 1587 fragment);
pcercuei 0:03b5121a232e 1588 xmlXPathFreeContext(xptrctxt);
pcercuei 0:03b5121a232e 1589 xmlFree(URL);
pcercuei 0:03b5121a232e 1590 xmlFree(fragment);
pcercuei 0:03b5121a232e 1591 return(-1);
pcercuei 0:03b5121a232e 1592 }
pcercuei 0:03b5121a232e 1593 switch (xptr->type) {
pcercuei 0:03b5121a232e 1594 case XPATH_UNDEFINED:
pcercuei 0:03b5121a232e 1595 case XPATH_BOOLEAN:
pcercuei 0:03b5121a232e 1596 case XPATH_NUMBER:
pcercuei 0:03b5121a232e 1597 case XPATH_STRING:
pcercuei 0:03b5121a232e 1598 case XPATH_POINT:
pcercuei 0:03b5121a232e 1599 case XPATH_USERS:
pcercuei 0:03b5121a232e 1600 case XPATH_XSLT_TREE:
pcercuei 0:03b5121a232e 1601 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1602 XML_XINCLUDE_XPTR_RESULT,
pcercuei 0:03b5121a232e 1603 "XPointer is not a range: #%s\n",
pcercuei 0:03b5121a232e 1604 fragment);
pcercuei 0:03b5121a232e 1605 xmlXPathFreeContext(xptrctxt);
pcercuei 0:03b5121a232e 1606 xmlFree(URL);
pcercuei 0:03b5121a232e 1607 xmlFree(fragment);
pcercuei 0:03b5121a232e 1608 return(-1);
pcercuei 0:03b5121a232e 1609 case XPATH_NODESET:
pcercuei 0:03b5121a232e 1610 if ((xptr->nodesetval == NULL) ||
pcercuei 0:03b5121a232e 1611 (xptr->nodesetval->nodeNr <= 0)) {
pcercuei 0:03b5121a232e 1612 xmlXPathFreeContext(xptrctxt);
pcercuei 0:03b5121a232e 1613 xmlFree(URL);
pcercuei 0:03b5121a232e 1614 xmlFree(fragment);
pcercuei 0:03b5121a232e 1615 return(-1);
pcercuei 0:03b5121a232e 1616 }
pcercuei 0:03b5121a232e 1617
pcercuei 0:03b5121a232e 1618 case XPATH_RANGE:
pcercuei 0:03b5121a232e 1619 case XPATH_LOCATIONSET:
pcercuei 0:03b5121a232e 1620 break;
pcercuei 0:03b5121a232e 1621 }
pcercuei 0:03b5121a232e 1622 set = xptr->nodesetval;
pcercuei 0:03b5121a232e 1623 if (set != NULL) {
pcercuei 0:03b5121a232e 1624 for (i = 0;i < set->nodeNr;i++) {
pcercuei 0:03b5121a232e 1625 if (set->nodeTab[i] == NULL)
pcercuei 0:03b5121a232e 1626 continue;
pcercuei 0:03b5121a232e 1627 switch (set->nodeTab[i]->type) {
pcercuei 0:03b5121a232e 1628 case XML_ELEMENT_NODE:
pcercuei 0:03b5121a232e 1629 case XML_TEXT_NODE:
pcercuei 0:03b5121a232e 1630 case XML_CDATA_SECTION_NODE:
pcercuei 0:03b5121a232e 1631 case XML_ENTITY_REF_NODE:
pcercuei 0:03b5121a232e 1632 case XML_ENTITY_NODE:
pcercuei 0:03b5121a232e 1633 case XML_PI_NODE:
pcercuei 0:03b5121a232e 1634 case XML_COMMENT_NODE:
pcercuei 0:03b5121a232e 1635 case XML_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 1636 case XML_HTML_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 1637 #ifdef LIBXML_DOCB_ENABLED
pcercuei 0:03b5121a232e 1638 case XML_DOCB_DOCUMENT_NODE:
pcercuei 0:03b5121a232e 1639 #endif
pcercuei 0:03b5121a232e 1640 continue;
pcercuei 0:03b5121a232e 1641
pcercuei 0:03b5121a232e 1642 case XML_ATTRIBUTE_NODE:
pcercuei 0:03b5121a232e 1643 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1644 XML_XINCLUDE_XPTR_RESULT,
pcercuei 0:03b5121a232e 1645 "XPointer selects an attribute: #%s\n",
pcercuei 0:03b5121a232e 1646 fragment);
pcercuei 0:03b5121a232e 1647 set->nodeTab[i] = NULL;
pcercuei 0:03b5121a232e 1648 continue;
pcercuei 0:03b5121a232e 1649 case XML_NAMESPACE_DECL:
pcercuei 0:03b5121a232e 1650 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1651 XML_XINCLUDE_XPTR_RESULT,
pcercuei 0:03b5121a232e 1652 "XPointer selects a namespace: #%s\n",
pcercuei 0:03b5121a232e 1653 fragment);
pcercuei 0:03b5121a232e 1654 set->nodeTab[i] = NULL;
pcercuei 0:03b5121a232e 1655 continue;
pcercuei 0:03b5121a232e 1656 case XML_DOCUMENT_TYPE_NODE:
pcercuei 0:03b5121a232e 1657 case XML_DOCUMENT_FRAG_NODE:
pcercuei 0:03b5121a232e 1658 case XML_NOTATION_NODE:
pcercuei 0:03b5121a232e 1659 case XML_DTD_NODE:
pcercuei 0:03b5121a232e 1660 case XML_ELEMENT_DECL:
pcercuei 0:03b5121a232e 1661 case XML_ATTRIBUTE_DECL:
pcercuei 0:03b5121a232e 1662 case XML_ENTITY_DECL:
pcercuei 0:03b5121a232e 1663 case XML_XINCLUDE_START:
pcercuei 0:03b5121a232e 1664 case XML_XINCLUDE_END:
pcercuei 0:03b5121a232e 1665 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1666 XML_XINCLUDE_XPTR_RESULT,
pcercuei 0:03b5121a232e 1667 "XPointer selects unexpected nodes: #%s\n",
pcercuei 0:03b5121a232e 1668 fragment);
pcercuei 0:03b5121a232e 1669 set->nodeTab[i] = NULL;
pcercuei 0:03b5121a232e 1670 set->nodeTab[i] = NULL;
pcercuei 0:03b5121a232e 1671 continue; /* for */
pcercuei 0:03b5121a232e 1672 }
pcercuei 0:03b5121a232e 1673 }
pcercuei 0:03b5121a232e 1674 }
pcercuei 0:03b5121a232e 1675 if (doc == NULL) {
pcercuei 0:03b5121a232e 1676 ctxt->incTab[nr]->xptr = xptr;
pcercuei 0:03b5121a232e 1677 ctxt->incTab[nr]->inc = NULL;
pcercuei 0:03b5121a232e 1678 } else {
pcercuei 0:03b5121a232e 1679 ctxt->incTab[nr]->inc =
pcercuei 0:03b5121a232e 1680 xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
pcercuei 0:03b5121a232e 1681 xmlXPathFreeObject(xptr);
pcercuei 0:03b5121a232e 1682 }
pcercuei 0:03b5121a232e 1683 xmlXPathFreeContext(xptrctxt);
pcercuei 0:03b5121a232e 1684 xmlFree(fragment);
pcercuei 0:03b5121a232e 1685 }
pcercuei 0:03b5121a232e 1686 #endif
pcercuei 0:03b5121a232e 1687
pcercuei 0:03b5121a232e 1688 /*
pcercuei 0:03b5121a232e 1689 * Do the xml:base fixup if needed
pcercuei 0:03b5121a232e 1690 */
pcercuei 0:03b5121a232e 1691 if ((doc != NULL) && (URL != NULL) &&
pcercuei 0:03b5121a232e 1692 (!(ctxt->parseFlags & XML_PARSE_NOBASEFIX)) &&
pcercuei 0:03b5121a232e 1693 (!(doc->parseFlags & XML_PARSE_NOBASEFIX))) {
pcercuei 0:03b5121a232e 1694 xmlNodePtr node;
pcercuei 0:03b5121a232e 1695 xmlChar *base;
pcercuei 0:03b5121a232e 1696 xmlChar *curBase;
pcercuei 0:03b5121a232e 1697
pcercuei 0:03b5121a232e 1698 /*
pcercuei 0:03b5121a232e 1699 * The base is only adjusted if "necessary", i.e. if the xinclude node
pcercuei 0:03b5121a232e 1700 * has a base specified, or the URL is relative
pcercuei 0:03b5121a232e 1701 */
pcercuei 0:03b5121a232e 1702 base = xmlGetNsProp(ctxt->incTab[nr]->ref, BAD_CAST "base",
pcercuei 0:03b5121a232e 1703 XML_XML_NAMESPACE);
pcercuei 0:03b5121a232e 1704 if (base == NULL) {
pcercuei 0:03b5121a232e 1705 /*
pcercuei 0:03b5121a232e 1706 * No xml:base on the xinclude node, so we check whether the
pcercuei 0:03b5121a232e 1707 * URI base is different than (relative to) the context base
pcercuei 0:03b5121a232e 1708 */
pcercuei 0:03b5121a232e 1709 curBase = xmlBuildRelativeURI(URL, ctxt->base);
pcercuei 0:03b5121a232e 1710 if (curBase == NULL) { /* Error return */
pcercuei 0:03b5121a232e 1711 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1712 XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1713 "trying to build relative URI from %s\n", URL);
pcercuei 0:03b5121a232e 1714 } else {
pcercuei 0:03b5121a232e 1715 /* If the URI doesn't contain a slash, it's not relative */
pcercuei 0:03b5121a232e 1716 if (!xmlStrchr(curBase, (xmlChar) '/'))
pcercuei 0:03b5121a232e 1717 xmlFree(curBase);
pcercuei 0:03b5121a232e 1718 else
pcercuei 0:03b5121a232e 1719 base = curBase;
pcercuei 0:03b5121a232e 1720 }
pcercuei 0:03b5121a232e 1721 }
pcercuei 0:03b5121a232e 1722 if (base != NULL) { /* Adjustment may be needed */
pcercuei 0:03b5121a232e 1723 node = ctxt->incTab[nr]->inc;
pcercuei 0:03b5121a232e 1724 while (node != NULL) {
pcercuei 0:03b5121a232e 1725 /* Only work on element nodes */
pcercuei 0:03b5121a232e 1726 if (node->type == XML_ELEMENT_NODE) {
pcercuei 0:03b5121a232e 1727 curBase = xmlNodeGetBase(node->doc, node);
pcercuei 0:03b5121a232e 1728 /* If no current base, set it */
pcercuei 0:03b5121a232e 1729 if (curBase == NULL) {
pcercuei 0:03b5121a232e 1730 xmlNodeSetBase(node, base);
pcercuei 0:03b5121a232e 1731 } else {
pcercuei 0:03b5121a232e 1732 /*
pcercuei 0:03b5121a232e 1733 * If the current base is the same as the
pcercuei 0:03b5121a232e 1734 * URL of the document, then reset it to be
pcercuei 0:03b5121a232e 1735 * the specified xml:base or the relative URI
pcercuei 0:03b5121a232e 1736 */
pcercuei 0:03b5121a232e 1737 if (xmlStrEqual(curBase, node->doc->URL)) {
pcercuei 0:03b5121a232e 1738 xmlNodeSetBase(node, base);
pcercuei 0:03b5121a232e 1739 } else {
pcercuei 0:03b5121a232e 1740 /*
pcercuei 0:03b5121a232e 1741 * If the element already has an xml:base
pcercuei 0:03b5121a232e 1742 * set, then relativise it if necessary
pcercuei 0:03b5121a232e 1743 */
pcercuei 0:03b5121a232e 1744 xmlChar *xmlBase;
pcercuei 0:03b5121a232e 1745 xmlBase = xmlGetNsProp(node,
pcercuei 0:03b5121a232e 1746 BAD_CAST "base",
pcercuei 0:03b5121a232e 1747 XML_XML_NAMESPACE);
pcercuei 0:03b5121a232e 1748 if (xmlBase != NULL) {
pcercuei 0:03b5121a232e 1749 xmlChar *relBase;
pcercuei 0:03b5121a232e 1750 relBase = xmlBuildURI(xmlBase, base);
pcercuei 0:03b5121a232e 1751 if (relBase == NULL) { /* error */
pcercuei 0:03b5121a232e 1752 xmlXIncludeErr(ctxt,
pcercuei 0:03b5121a232e 1753 ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1754 XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1755 "trying to rebuild base from %s\n",
pcercuei 0:03b5121a232e 1756 xmlBase);
pcercuei 0:03b5121a232e 1757 } else {
pcercuei 0:03b5121a232e 1758 xmlNodeSetBase(node, relBase);
pcercuei 0:03b5121a232e 1759 xmlFree(relBase);
pcercuei 0:03b5121a232e 1760 }
pcercuei 0:03b5121a232e 1761 xmlFree(xmlBase);
pcercuei 0:03b5121a232e 1762 }
pcercuei 0:03b5121a232e 1763 }
pcercuei 0:03b5121a232e 1764 xmlFree(curBase);
pcercuei 0:03b5121a232e 1765 }
pcercuei 0:03b5121a232e 1766 }
pcercuei 0:03b5121a232e 1767 node = node->next;
pcercuei 0:03b5121a232e 1768 }
pcercuei 0:03b5121a232e 1769 xmlFree(base);
pcercuei 0:03b5121a232e 1770 }
pcercuei 0:03b5121a232e 1771 }
pcercuei 0:03b5121a232e 1772 if ((nr < ctxt->incNr) && (ctxt->incTab[nr]->doc != NULL) &&
pcercuei 0:03b5121a232e 1773 (ctxt->incTab[nr]->count <= 1)) {
pcercuei 0:03b5121a232e 1774 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 1775 printf("freeing %s\n", ctxt->incTab[nr]->doc->URL);
pcercuei 0:03b5121a232e 1776 #endif
pcercuei 0:03b5121a232e 1777 xmlFreeDoc(ctxt->incTab[nr]->doc);
pcercuei 0:03b5121a232e 1778 ctxt->incTab[nr]->doc = NULL;
pcercuei 0:03b5121a232e 1779 }
pcercuei 0:03b5121a232e 1780 xmlFree(URL);
pcercuei 0:03b5121a232e 1781 return(0);
pcercuei 0:03b5121a232e 1782 }
pcercuei 0:03b5121a232e 1783
pcercuei 0:03b5121a232e 1784 /**
pcercuei 0:03b5121a232e 1785 * xmlXIncludeLoadTxt:
pcercuei 0:03b5121a232e 1786 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 1787 * @url: the associated URL
pcercuei 0:03b5121a232e 1788 * @nr: the xinclude node number
pcercuei 0:03b5121a232e 1789 *
pcercuei 0:03b5121a232e 1790 * Load the content, and store the result in the XInclude context
pcercuei 0:03b5121a232e 1791 *
pcercuei 0:03b5121a232e 1792 * Returns 0 in case of success, -1 in case of failure
pcercuei 0:03b5121a232e 1793 */
pcercuei 0:03b5121a232e 1794 static int
pcercuei 0:03b5121a232e 1795 xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
pcercuei 0:03b5121a232e 1796 xmlParserInputBufferPtr buf;
pcercuei 0:03b5121a232e 1797 xmlNodePtr node;
pcercuei 0:03b5121a232e 1798 xmlURIPtr uri;
pcercuei 0:03b5121a232e 1799 xmlChar *URL;
pcercuei 0:03b5121a232e 1800 int i;
pcercuei 0:03b5121a232e 1801 xmlChar *encoding = NULL;
pcercuei 0:03b5121a232e 1802 xmlCharEncoding enc = (xmlCharEncoding) 0;
pcercuei 0:03b5121a232e 1803 xmlParserCtxtPtr pctxt;
pcercuei 0:03b5121a232e 1804 xmlParserInputPtr inputStream;
pcercuei 0:03b5121a232e 1805 int xinclude_multibyte_fallback_used = 0;
pcercuei 0:03b5121a232e 1806
pcercuei 0:03b5121a232e 1807 /*
pcercuei 0:03b5121a232e 1808 * Check the URL and remove any fragment identifier
pcercuei 0:03b5121a232e 1809 */
pcercuei 0:03b5121a232e 1810 uri = xmlParseURI((const char *)url);
pcercuei 0:03b5121a232e 1811 if (uri == NULL) {
pcercuei 0:03b5121a232e 1812 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1813 "invalid value URI %s\n", url);
pcercuei 0:03b5121a232e 1814 return(-1);
pcercuei 0:03b5121a232e 1815 }
pcercuei 0:03b5121a232e 1816 if (uri->fragment != NULL) {
pcercuei 0:03b5121a232e 1817 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_TEXT_FRAGMENT,
pcercuei 0:03b5121a232e 1818 "fragment identifier forbidden for text: %s\n",
pcercuei 0:03b5121a232e 1819 (const xmlChar *) uri->fragment);
pcercuei 0:03b5121a232e 1820 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 1821 return(-1);
pcercuei 0:03b5121a232e 1822 }
pcercuei 0:03b5121a232e 1823 URL = xmlSaveUri(uri);
pcercuei 0:03b5121a232e 1824 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 1825 if (URL == NULL) {
pcercuei 0:03b5121a232e 1826 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_HREF_URI,
pcercuei 0:03b5121a232e 1827 "invalid value URI %s\n", url);
pcercuei 0:03b5121a232e 1828 return(-1);
pcercuei 0:03b5121a232e 1829 }
pcercuei 0:03b5121a232e 1830
pcercuei 0:03b5121a232e 1831 /*
pcercuei 0:03b5121a232e 1832 * Handling of references to the local document are done
pcercuei 0:03b5121a232e 1833 * directly through ctxt->doc.
pcercuei 0:03b5121a232e 1834 */
pcercuei 0:03b5121a232e 1835 if (URL[0] == 0) {
pcercuei 0:03b5121a232e 1836 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1837 XML_XINCLUDE_TEXT_DOCUMENT,
pcercuei 0:03b5121a232e 1838 "text serialization of document not available\n", NULL);
pcercuei 0:03b5121a232e 1839 xmlFree(URL);
pcercuei 0:03b5121a232e 1840 return(-1);
pcercuei 0:03b5121a232e 1841 }
pcercuei 0:03b5121a232e 1842
pcercuei 0:03b5121a232e 1843 /*
pcercuei 0:03b5121a232e 1844 * Prevent reloading twice the document.
pcercuei 0:03b5121a232e 1845 */
pcercuei 0:03b5121a232e 1846 for (i = 0; i < ctxt->txtNr; i++) {
pcercuei 0:03b5121a232e 1847 if (xmlStrEqual(URL, ctxt->txturlTab[i])) {
pcercuei 0:03b5121a232e 1848 node = xmlCopyNode(ctxt->txtTab[i], 1);
pcercuei 0:03b5121a232e 1849 goto loaded;
pcercuei 0:03b5121a232e 1850 }
pcercuei 0:03b5121a232e 1851 }
pcercuei 0:03b5121a232e 1852 /*
pcercuei 0:03b5121a232e 1853 * Try to get the encoding if available
pcercuei 0:03b5121a232e 1854 */
pcercuei 0:03b5121a232e 1855 if ((ctxt->incTab[nr] != NULL) && (ctxt->incTab[nr]->ref != NULL)) {
pcercuei 0:03b5121a232e 1856 encoding = xmlGetProp(ctxt->incTab[nr]->ref, XINCLUDE_PARSE_ENCODING);
pcercuei 0:03b5121a232e 1857 }
pcercuei 0:03b5121a232e 1858 if (encoding != NULL) {
pcercuei 0:03b5121a232e 1859 /*
pcercuei 0:03b5121a232e 1860 * TODO: we should not have to remap to the xmlCharEncoding
pcercuei 0:03b5121a232e 1861 * predefined set, a better interface than
pcercuei 0:03b5121a232e 1862 * xmlParserInputBufferCreateFilename should allow any
pcercuei 0:03b5121a232e 1863 * encoding supported by iconv
pcercuei 0:03b5121a232e 1864 */
pcercuei 0:03b5121a232e 1865 enc = xmlParseCharEncoding((const char *) encoding);
pcercuei 0:03b5121a232e 1866 if (enc == XML_CHAR_ENCODING_ERROR) {
pcercuei 0:03b5121a232e 1867 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1868 XML_XINCLUDE_UNKNOWN_ENCODING,
pcercuei 0:03b5121a232e 1869 "encoding %s not supported\n", encoding);
pcercuei 0:03b5121a232e 1870 xmlFree(encoding);
pcercuei 0:03b5121a232e 1871 xmlFree(URL);
pcercuei 0:03b5121a232e 1872 return(-1);
pcercuei 0:03b5121a232e 1873 }
pcercuei 0:03b5121a232e 1874 xmlFree(encoding);
pcercuei 0:03b5121a232e 1875 }
pcercuei 0:03b5121a232e 1876
pcercuei 0:03b5121a232e 1877 /*
pcercuei 0:03b5121a232e 1878 * Load it.
pcercuei 0:03b5121a232e 1879 */
pcercuei 0:03b5121a232e 1880 pctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 1881 inputStream = xmlLoadExternalEntity((const char*)URL, NULL, pctxt);
pcercuei 0:03b5121a232e 1882 if(inputStream == NULL) {
pcercuei 0:03b5121a232e 1883 xmlFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 1884 xmlFree(URL);
pcercuei 0:03b5121a232e 1885 return(-1);
pcercuei 0:03b5121a232e 1886 }
pcercuei 0:03b5121a232e 1887 buf = inputStream->buf;
pcercuei 0:03b5121a232e 1888 if (buf == NULL) {
pcercuei 0:03b5121a232e 1889 xmlFreeInputStream (inputStream);
pcercuei 0:03b5121a232e 1890 xmlFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 1891 xmlFree(URL);
pcercuei 0:03b5121a232e 1892 return(-1);
pcercuei 0:03b5121a232e 1893 }
pcercuei 0:03b5121a232e 1894 if (buf->encoder)
pcercuei 0:03b5121a232e 1895 xmlCharEncCloseFunc(buf->encoder);
pcercuei 0:03b5121a232e 1896 buf->encoder = xmlGetCharEncodingHandler(enc);
pcercuei 0:03b5121a232e 1897 node = xmlNewText(NULL);
pcercuei 0:03b5121a232e 1898
pcercuei 0:03b5121a232e 1899 /*
pcercuei 0:03b5121a232e 1900 * Scan all chars from the resource and add the to the node
pcercuei 0:03b5121a232e 1901 */
pcercuei 0:03b5121a232e 1902 xinclude_multibyte_fallback:
pcercuei 0:03b5121a232e 1903 while (xmlParserInputBufferRead(buf, 128) > 0) {
pcercuei 0:03b5121a232e 1904 int len;
pcercuei 0:03b5121a232e 1905 const xmlChar *content;
pcercuei 0:03b5121a232e 1906
pcercuei 0:03b5121a232e 1907 content = xmlBufContent(buf->buffer);
pcercuei 0:03b5121a232e 1908 len = xmlBufLength(buf->buffer);
pcercuei 0:03b5121a232e 1909 for (i = 0;i < len;) {
pcercuei 0:03b5121a232e 1910 int cur;
pcercuei 0:03b5121a232e 1911 int l;
pcercuei 0:03b5121a232e 1912
pcercuei 0:03b5121a232e 1913 cur = xmlStringCurrentChar(NULL, &content[i], &l);
pcercuei 0:03b5121a232e 1914 if (!IS_CHAR(cur)) {
pcercuei 0:03b5121a232e 1915 /* Handle splitted multibyte char at buffer boundary */
pcercuei 0:03b5121a232e 1916 if (((len - i) < 4) && (!xinclude_multibyte_fallback_used)) {
pcercuei 0:03b5121a232e 1917 xinclude_multibyte_fallback_used = 1;
pcercuei 0:03b5121a232e 1918 xmlBufShrink(buf->buffer, i);
pcercuei 0:03b5121a232e 1919 goto xinclude_multibyte_fallback;
pcercuei 0:03b5121a232e 1920 } else {
pcercuei 0:03b5121a232e 1921 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 1922 XML_XINCLUDE_INVALID_CHAR,
pcercuei 0:03b5121a232e 1923 "%s contains invalid char\n", URL);
pcercuei 0:03b5121a232e 1924 xmlFreeParserInputBuffer(buf);
pcercuei 0:03b5121a232e 1925 xmlFree(URL);
pcercuei 0:03b5121a232e 1926 return(-1);
pcercuei 0:03b5121a232e 1927 }
pcercuei 0:03b5121a232e 1928 } else {
pcercuei 0:03b5121a232e 1929 xinclude_multibyte_fallback_used = 0;
pcercuei 0:03b5121a232e 1930 xmlNodeAddContentLen(node, &content[i], l);
pcercuei 0:03b5121a232e 1931 }
pcercuei 0:03b5121a232e 1932 i += l;
pcercuei 0:03b5121a232e 1933 }
pcercuei 0:03b5121a232e 1934 xmlBufShrink(buf->buffer, len);
pcercuei 0:03b5121a232e 1935 }
pcercuei 0:03b5121a232e 1936 xmlFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 1937 xmlXIncludeAddTxt(ctxt, node, URL);
pcercuei 0:03b5121a232e 1938 xmlFreeInputStream(inputStream);
pcercuei 0:03b5121a232e 1939
pcercuei 0:03b5121a232e 1940 loaded:
pcercuei 0:03b5121a232e 1941 /*
pcercuei 0:03b5121a232e 1942 * Add the element as the replacement copy.
pcercuei 0:03b5121a232e 1943 */
pcercuei 0:03b5121a232e 1944 ctxt->incTab[nr]->inc = node;
pcercuei 0:03b5121a232e 1945 xmlFree(URL);
pcercuei 0:03b5121a232e 1946 return(0);
pcercuei 0:03b5121a232e 1947 }
pcercuei 0:03b5121a232e 1948
pcercuei 0:03b5121a232e 1949 /**
pcercuei 0:03b5121a232e 1950 * xmlXIncludeLoadFallback:
pcercuei 0:03b5121a232e 1951 * @ctxt: the XInclude context
pcercuei 0:03b5121a232e 1952 * @fallback: the fallback node
pcercuei 0:03b5121a232e 1953 * @nr: the xinclude node number
pcercuei 0:03b5121a232e 1954 *
pcercuei 0:03b5121a232e 1955 * Load the content of the fallback node, and store the result
pcercuei 0:03b5121a232e 1956 * in the XInclude context
pcercuei 0:03b5121a232e 1957 *
pcercuei 0:03b5121a232e 1958 * Returns 0 in case of success, -1 in case of failure
pcercuei 0:03b5121a232e 1959 */
pcercuei 0:03b5121a232e 1960 static int
pcercuei 0:03b5121a232e 1961 xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) {
pcercuei 0:03b5121a232e 1962 xmlXIncludeCtxtPtr newctxt;
pcercuei 0:03b5121a232e 1963 int ret = 0;
pcercuei 0:03b5121a232e 1964
pcercuei 0:03b5121a232e 1965 if ((fallback == NULL) || (fallback->type == XML_NAMESPACE_DECL) ||
pcercuei 0:03b5121a232e 1966 (ctxt == NULL))
pcercuei 0:03b5121a232e 1967 return(-1);
pcercuei 0:03b5121a232e 1968 if (fallback->children != NULL) {
pcercuei 0:03b5121a232e 1969 /*
pcercuei 0:03b5121a232e 1970 * It's possible that the fallback also has 'includes'
pcercuei 0:03b5121a232e 1971 * (Bug 129969), so we re-process the fallback just in case
pcercuei 0:03b5121a232e 1972 */
pcercuei 0:03b5121a232e 1973 newctxt = xmlXIncludeNewContext(ctxt->doc);
pcercuei 0:03b5121a232e 1974 if (newctxt == NULL)
pcercuei 0:03b5121a232e 1975 return (-1);
pcercuei 0:03b5121a232e 1976 newctxt->_private = ctxt->_private;
pcercuei 0:03b5121a232e 1977 newctxt->base = xmlStrdup(ctxt->base); /* Inherit the base from the existing context */
pcercuei 0:03b5121a232e 1978 xmlXIncludeSetFlags(newctxt, ctxt->parseFlags);
pcercuei 0:03b5121a232e 1979 ret = xmlXIncludeDoProcess(newctxt, ctxt->doc, fallback->children);
pcercuei 0:03b5121a232e 1980 if (ctxt->nbErrors > 0)
pcercuei 0:03b5121a232e 1981 ret = -1;
pcercuei 0:03b5121a232e 1982 else if (ret > 0)
pcercuei 0:03b5121a232e 1983 ret = 0; /* xmlXIncludeDoProcess can return +ve number */
pcercuei 0:03b5121a232e 1984 xmlXIncludeFreeContext(newctxt);
pcercuei 0:03b5121a232e 1985
pcercuei 0:03b5121a232e 1986 ctxt->incTab[nr]->inc = xmlDocCopyNodeList(ctxt->doc,
pcercuei 0:03b5121a232e 1987 fallback->children);
pcercuei 0:03b5121a232e 1988 } else {
pcercuei 0:03b5121a232e 1989 ctxt->incTab[nr]->inc = NULL;
pcercuei 0:03b5121a232e 1990 ctxt->incTab[nr]->emptyFb = 1; /* flag empty callback */
pcercuei 0:03b5121a232e 1991 }
pcercuei 0:03b5121a232e 1992 return(ret);
pcercuei 0:03b5121a232e 1993 }
pcercuei 0:03b5121a232e 1994
pcercuei 0:03b5121a232e 1995 /************************************************************************
pcercuei 0:03b5121a232e 1996 * *
pcercuei 0:03b5121a232e 1997 * XInclude Processing *
pcercuei 0:03b5121a232e 1998 * *
pcercuei 0:03b5121a232e 1999 ************************************************************************/
pcercuei 0:03b5121a232e 2000
pcercuei 0:03b5121a232e 2001 /**
pcercuei 0:03b5121a232e 2002 * xmlXIncludePreProcessNode:
pcercuei 0:03b5121a232e 2003 * @ctxt: an XInclude context
pcercuei 0:03b5121a232e 2004 * @node: an XInclude node
pcercuei 0:03b5121a232e 2005 *
pcercuei 0:03b5121a232e 2006 * Implement the XInclude preprocessing, currently just adding the element
pcercuei 0:03b5121a232e 2007 * for further processing.
pcercuei 0:03b5121a232e 2008 *
pcercuei 0:03b5121a232e 2009 * Returns the result list or NULL in case of error
pcercuei 0:03b5121a232e 2010 */
pcercuei 0:03b5121a232e 2011 static xmlNodePtr
pcercuei 0:03b5121a232e 2012 xmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
pcercuei 0:03b5121a232e 2013 xmlXIncludeAddNode(ctxt, node);
pcercuei 0:03b5121a232e 2014 return(NULL);
pcercuei 0:03b5121a232e 2015 }
pcercuei 0:03b5121a232e 2016
pcercuei 0:03b5121a232e 2017 /**
pcercuei 0:03b5121a232e 2018 * xmlXIncludeLoadNode:
pcercuei 0:03b5121a232e 2019 * @ctxt: an XInclude context
pcercuei 0:03b5121a232e 2020 * @nr: the node number
pcercuei 0:03b5121a232e 2021 *
pcercuei 0:03b5121a232e 2022 * Find and load the infoset replacement for the given node.
pcercuei 0:03b5121a232e 2023 *
pcercuei 0:03b5121a232e 2024 * Returns 0 if substitution succeeded, -1 if some processing failed
pcercuei 0:03b5121a232e 2025 */
pcercuei 0:03b5121a232e 2026 static int
pcercuei 0:03b5121a232e 2027 xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
pcercuei 0:03b5121a232e 2028 xmlNodePtr cur;
pcercuei 0:03b5121a232e 2029 xmlChar *href;
pcercuei 0:03b5121a232e 2030 xmlChar *parse;
pcercuei 0:03b5121a232e 2031 xmlChar *base;
pcercuei 0:03b5121a232e 2032 xmlChar *oldBase;
pcercuei 0:03b5121a232e 2033 xmlChar *URI;
pcercuei 0:03b5121a232e 2034 int xml = 1; /* default Issue 64 */
pcercuei 0:03b5121a232e 2035 int ret;
pcercuei 0:03b5121a232e 2036
pcercuei 0:03b5121a232e 2037 if (ctxt == NULL)
pcercuei 0:03b5121a232e 2038 return(-1);
pcercuei 0:03b5121a232e 2039 if ((nr < 0) || (nr >= ctxt->incNr))
pcercuei 0:03b5121a232e 2040 return(-1);
pcercuei 0:03b5121a232e 2041 cur = ctxt->incTab[nr]->ref;
pcercuei 0:03b5121a232e 2042 if (cur == NULL)
pcercuei 0:03b5121a232e 2043 return(-1);
pcercuei 0:03b5121a232e 2044
pcercuei 0:03b5121a232e 2045 /*
pcercuei 0:03b5121a232e 2046 * read the attributes
pcercuei 0:03b5121a232e 2047 */
pcercuei 0:03b5121a232e 2048 href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
pcercuei 0:03b5121a232e 2049 if (href == NULL) {
pcercuei 0:03b5121a232e 2050 href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
pcercuei 0:03b5121a232e 2051 if (href == NULL)
pcercuei 0:03b5121a232e 2052 return(-1);
pcercuei 0:03b5121a232e 2053 }
pcercuei 0:03b5121a232e 2054 parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
pcercuei 0:03b5121a232e 2055 if (parse != NULL) {
pcercuei 0:03b5121a232e 2056 if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
pcercuei 0:03b5121a232e 2057 xml = 1;
pcercuei 0:03b5121a232e 2058 else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
pcercuei 0:03b5121a232e 2059 xml = 0;
pcercuei 0:03b5121a232e 2060 else {
pcercuei 0:03b5121a232e 2061 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 2062 XML_XINCLUDE_PARSE_VALUE,
pcercuei 0:03b5121a232e 2063 "invalid value %s for 'parse'\n", parse);
pcercuei 0:03b5121a232e 2064 if (href != NULL)
pcercuei 0:03b5121a232e 2065 xmlFree(href);
pcercuei 0:03b5121a232e 2066 if (parse != NULL)
pcercuei 0:03b5121a232e 2067 xmlFree(parse);
pcercuei 0:03b5121a232e 2068 return(-1);
pcercuei 0:03b5121a232e 2069 }
pcercuei 0:03b5121a232e 2070 }
pcercuei 0:03b5121a232e 2071
pcercuei 0:03b5121a232e 2072 /*
pcercuei 0:03b5121a232e 2073 * compute the URI
pcercuei 0:03b5121a232e 2074 */
pcercuei 0:03b5121a232e 2075 base = xmlNodeGetBase(ctxt->doc, cur);
pcercuei 0:03b5121a232e 2076 if (base == NULL) {
pcercuei 0:03b5121a232e 2077 URI = xmlBuildURI(href, ctxt->doc->URL);
pcercuei 0:03b5121a232e 2078 } else {
pcercuei 0:03b5121a232e 2079 URI = xmlBuildURI(href, base);
pcercuei 0:03b5121a232e 2080 }
pcercuei 0:03b5121a232e 2081 if (URI == NULL) {
pcercuei 0:03b5121a232e 2082 xmlChar *escbase;
pcercuei 0:03b5121a232e 2083 xmlChar *eschref;
pcercuei 0:03b5121a232e 2084 /*
pcercuei 0:03b5121a232e 2085 * Some escaping may be needed
pcercuei 0:03b5121a232e 2086 */
pcercuei 0:03b5121a232e 2087 escbase = xmlURIEscape(base);
pcercuei 0:03b5121a232e 2088 eschref = xmlURIEscape(href);
pcercuei 0:03b5121a232e 2089 URI = xmlBuildURI(eschref, escbase);
pcercuei 0:03b5121a232e 2090 if (escbase != NULL)
pcercuei 0:03b5121a232e 2091 xmlFree(escbase);
pcercuei 0:03b5121a232e 2092 if (eschref != NULL)
pcercuei 0:03b5121a232e 2093 xmlFree(eschref);
pcercuei 0:03b5121a232e 2094 }
pcercuei 0:03b5121a232e 2095 if (URI == NULL) {
pcercuei 0:03b5121a232e 2096 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 2097 XML_XINCLUDE_HREF_URI, "failed build URL\n", NULL);
pcercuei 0:03b5121a232e 2098 if (parse != NULL)
pcercuei 0:03b5121a232e 2099 xmlFree(parse);
pcercuei 0:03b5121a232e 2100 if (href != NULL)
pcercuei 0:03b5121a232e 2101 xmlFree(href);
pcercuei 0:03b5121a232e 2102 if (base != NULL)
pcercuei 0:03b5121a232e 2103 xmlFree(base);
pcercuei 0:03b5121a232e 2104 return(-1);
pcercuei 0:03b5121a232e 2105 }
pcercuei 0:03b5121a232e 2106 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 2107 xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
pcercuei 0:03b5121a232e 2108 xml ? "xml": "text");
pcercuei 0:03b5121a232e 2109 xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
pcercuei 0:03b5121a232e 2110 #endif
pcercuei 0:03b5121a232e 2111
pcercuei 0:03b5121a232e 2112 /*
pcercuei 0:03b5121a232e 2113 * Save the base for this include (saving the current one)
pcercuei 0:03b5121a232e 2114 */
pcercuei 0:03b5121a232e 2115 oldBase = ctxt->base;
pcercuei 0:03b5121a232e 2116 ctxt->base = base;
pcercuei 0:03b5121a232e 2117
pcercuei 0:03b5121a232e 2118 if (xml) {
pcercuei 0:03b5121a232e 2119 ret = xmlXIncludeLoadDoc(ctxt, URI, nr);
pcercuei 0:03b5121a232e 2120 /* xmlXIncludeGetFragment(ctxt, cur, URI); */
pcercuei 0:03b5121a232e 2121 } else {
pcercuei 0:03b5121a232e 2122 ret = xmlXIncludeLoadTxt(ctxt, URI, nr);
pcercuei 0:03b5121a232e 2123 }
pcercuei 0:03b5121a232e 2124
pcercuei 0:03b5121a232e 2125 /*
pcercuei 0:03b5121a232e 2126 * Restore the original base before checking for fallback
pcercuei 0:03b5121a232e 2127 */
pcercuei 0:03b5121a232e 2128 ctxt->base = oldBase;
pcercuei 0:03b5121a232e 2129
pcercuei 0:03b5121a232e 2130 if (ret < 0) {
pcercuei 0:03b5121a232e 2131 xmlNodePtr children;
pcercuei 0:03b5121a232e 2132
pcercuei 0:03b5121a232e 2133 /*
pcercuei 0:03b5121a232e 2134 * Time to try a fallback if availble
pcercuei 0:03b5121a232e 2135 */
pcercuei 0:03b5121a232e 2136 #ifdef DEBUG_XINCLUDE
pcercuei 0:03b5121a232e 2137 xmlGenericError(xmlGenericErrorContext, "error looking for fallback\n");
pcercuei 0:03b5121a232e 2138 #endif
pcercuei 0:03b5121a232e 2139 children = cur->children;
pcercuei 0:03b5121a232e 2140 while (children != NULL) {
pcercuei 0:03b5121a232e 2141 if ((children->type == XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 2142 (children->ns != NULL) &&
pcercuei 0:03b5121a232e 2143 (xmlStrEqual(children->name, XINCLUDE_FALLBACK)) &&
pcercuei 0:03b5121a232e 2144 ((xmlStrEqual(children->ns->href, XINCLUDE_NS)) ||
pcercuei 0:03b5121a232e 2145 (xmlStrEqual(children->ns->href, XINCLUDE_OLD_NS)))) {
pcercuei 0:03b5121a232e 2146 ret = xmlXIncludeLoadFallback(ctxt, children, nr);
pcercuei 0:03b5121a232e 2147 if (ret == 0)
pcercuei 0:03b5121a232e 2148 break;
pcercuei 0:03b5121a232e 2149 }
pcercuei 0:03b5121a232e 2150 children = children->next;
pcercuei 0:03b5121a232e 2151 }
pcercuei 0:03b5121a232e 2152 }
pcercuei 0:03b5121a232e 2153 if (ret < 0) {
pcercuei 0:03b5121a232e 2154 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 2155 XML_XINCLUDE_NO_FALLBACK,
pcercuei 0:03b5121a232e 2156 "could not load %s, and no fallback was found\n",
pcercuei 0:03b5121a232e 2157 URI);
pcercuei 0:03b5121a232e 2158 }
pcercuei 0:03b5121a232e 2159
pcercuei 0:03b5121a232e 2160 /*
pcercuei 0:03b5121a232e 2161 * Cleanup
pcercuei 0:03b5121a232e 2162 */
pcercuei 0:03b5121a232e 2163 if (URI != NULL)
pcercuei 0:03b5121a232e 2164 xmlFree(URI);
pcercuei 0:03b5121a232e 2165 if (parse != NULL)
pcercuei 0:03b5121a232e 2166 xmlFree(parse);
pcercuei 0:03b5121a232e 2167 if (href != NULL)
pcercuei 0:03b5121a232e 2168 xmlFree(href);
pcercuei 0:03b5121a232e 2169 if (base != NULL)
pcercuei 0:03b5121a232e 2170 xmlFree(base);
pcercuei 0:03b5121a232e 2171 return(0);
pcercuei 0:03b5121a232e 2172 }
pcercuei 0:03b5121a232e 2173
pcercuei 0:03b5121a232e 2174 /**
pcercuei 0:03b5121a232e 2175 * xmlXIncludeIncludeNode:
pcercuei 0:03b5121a232e 2176 * @ctxt: an XInclude context
pcercuei 0:03b5121a232e 2177 * @nr: the node number
pcercuei 0:03b5121a232e 2178 *
pcercuei 0:03b5121a232e 2179 * Inplement the infoset replacement for the given node
pcercuei 0:03b5121a232e 2180 *
pcercuei 0:03b5121a232e 2181 * Returns 0 if substitution succeeded, -1 if some processing failed
pcercuei 0:03b5121a232e 2182 */
pcercuei 0:03b5121a232e 2183 static int
pcercuei 0:03b5121a232e 2184 xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
pcercuei 0:03b5121a232e 2185 xmlNodePtr cur, end, list, tmp;
pcercuei 0:03b5121a232e 2186
pcercuei 0:03b5121a232e 2187 if (ctxt == NULL)
pcercuei 0:03b5121a232e 2188 return(-1);
pcercuei 0:03b5121a232e 2189 if ((nr < 0) || (nr >= ctxt->incNr))
pcercuei 0:03b5121a232e 2190 return(-1);
pcercuei 0:03b5121a232e 2191 cur = ctxt->incTab[nr]->ref;
pcercuei 0:03b5121a232e 2192 if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
pcercuei 0:03b5121a232e 2193 return(-1);
pcercuei 0:03b5121a232e 2194
pcercuei 0:03b5121a232e 2195 /*
pcercuei 0:03b5121a232e 2196 * If we stored an XPointer a late computation may be needed
pcercuei 0:03b5121a232e 2197 */
pcercuei 0:03b5121a232e 2198 if ((ctxt->incTab[nr]->inc == NULL) &&
pcercuei 0:03b5121a232e 2199 (ctxt->incTab[nr]->xptr != NULL)) {
pcercuei 0:03b5121a232e 2200 ctxt->incTab[nr]->inc =
pcercuei 0:03b5121a232e 2201 xmlXIncludeCopyXPointer(ctxt, ctxt->doc, ctxt->doc,
pcercuei 0:03b5121a232e 2202 ctxt->incTab[nr]->xptr);
pcercuei 0:03b5121a232e 2203 xmlXPathFreeObject(ctxt->incTab[nr]->xptr);
pcercuei 0:03b5121a232e 2204 ctxt->incTab[nr]->xptr = NULL;
pcercuei 0:03b5121a232e 2205 }
pcercuei 0:03b5121a232e 2206 list = ctxt->incTab[nr]->inc;
pcercuei 0:03b5121a232e 2207 ctxt->incTab[nr]->inc = NULL;
pcercuei 0:03b5121a232e 2208
pcercuei 0:03b5121a232e 2209 /*
pcercuei 0:03b5121a232e 2210 * Check against the risk of generating a multi-rooted document
pcercuei 0:03b5121a232e 2211 */
pcercuei 0:03b5121a232e 2212 if ((cur->parent != NULL) &&
pcercuei 0:03b5121a232e 2213 (cur->parent->type != XML_ELEMENT_NODE)) {
pcercuei 0:03b5121a232e 2214 int nb_elem = 0;
pcercuei 0:03b5121a232e 2215
pcercuei 0:03b5121a232e 2216 tmp = list;
pcercuei 0:03b5121a232e 2217 while (tmp != NULL) {
pcercuei 0:03b5121a232e 2218 if (tmp->type == XML_ELEMENT_NODE)
pcercuei 0:03b5121a232e 2219 nb_elem++;
pcercuei 0:03b5121a232e 2220 tmp = tmp->next;
pcercuei 0:03b5121a232e 2221 }
pcercuei 0:03b5121a232e 2222 if (nb_elem > 1) {
pcercuei 0:03b5121a232e 2223 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 2224 XML_XINCLUDE_MULTIPLE_ROOT,
pcercuei 0:03b5121a232e 2225 "XInclude error: would result in multiple root nodes\n",
pcercuei 0:03b5121a232e 2226 NULL);
pcercuei 0:03b5121a232e 2227 return(-1);
pcercuei 0:03b5121a232e 2228 }
pcercuei 0:03b5121a232e 2229 }
pcercuei 0:03b5121a232e 2230
pcercuei 0:03b5121a232e 2231 if (ctxt->parseFlags & XML_PARSE_NOXINCNODE) {
pcercuei 0:03b5121a232e 2232 /*
pcercuei 0:03b5121a232e 2233 * Add the list of nodes
pcercuei 0:03b5121a232e 2234 */
pcercuei 0:03b5121a232e 2235 while (list != NULL) {
pcercuei 0:03b5121a232e 2236 end = list;
pcercuei 0:03b5121a232e 2237 list = list->next;
pcercuei 0:03b5121a232e 2238
pcercuei 0:03b5121a232e 2239 xmlAddPrevSibling(cur, end);
pcercuei 0:03b5121a232e 2240 }
pcercuei 0:03b5121a232e 2241 xmlUnlinkNode(cur);
pcercuei 0:03b5121a232e 2242 xmlFreeNode(cur);
pcercuei 0:03b5121a232e 2243 } else {
pcercuei 0:03b5121a232e 2244 /*
pcercuei 0:03b5121a232e 2245 * Change the current node as an XInclude start one, and add an
pcercuei 0:03b5121a232e 2246 * XInclude end one
pcercuei 0:03b5121a232e 2247 */
pcercuei 0:03b5121a232e 2248 cur->type = XML_XINCLUDE_START;
pcercuei 0:03b5121a232e 2249 end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
pcercuei 0:03b5121a232e 2250 if (end == NULL) {
pcercuei 0:03b5121a232e 2251 xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref,
pcercuei 0:03b5121a232e 2252 XML_XINCLUDE_BUILD_FAILED,
pcercuei 0:03b5121a232e 2253 "failed to build node\n", NULL);
pcercuei 0:03b5121a232e 2254 return(-1);
pcercuei 0:03b5121a232e 2255 }
pcercuei 0:03b5121a232e 2256 end->type = XML_XINCLUDE_END;
pcercuei 0:03b5121a232e 2257 xmlAddNextSibling(cur, end);
pcercuei 0:03b5121a232e 2258
pcercuei 0:03b5121a232e 2259 /*
pcercuei 0:03b5121a232e 2260 * Add the list of nodes
pcercuei 0:03b5121a232e 2261 */
pcercuei 0:03b5121a232e 2262 while (list != NULL) {
pcercuei 0:03b5121a232e 2263 cur = list;
pcercuei 0:03b5121a232e 2264 list = list->next;
pcercuei 0:03b5121a232e 2265
pcercuei 0:03b5121a232e 2266 xmlAddPrevSibling(end, cur);
pcercuei 0:03b5121a232e 2267 }
pcercuei 0:03b5121a232e 2268 }
pcercuei 0:03b5121a232e 2269
pcercuei 0:03b5121a232e 2270
pcercuei 0:03b5121a232e 2271 return(0);
pcercuei 0:03b5121a232e 2272 }
pcercuei 0:03b5121a232e 2273
pcercuei 0:03b5121a232e 2274 /**
pcercuei 0:03b5121a232e 2275 * xmlXIncludeTestNode:
pcercuei 0:03b5121a232e 2276 * @ctxt: the XInclude processing context
pcercuei 0:03b5121a232e 2277 * @node: an XInclude node
pcercuei 0:03b5121a232e 2278 *
pcercuei 0:03b5121a232e 2279 * test if the node is an XInclude node
pcercuei 0:03b5121a232e 2280 *
pcercuei 0:03b5121a232e 2281 * Returns 1 true, 0 otherwise
pcercuei 0:03b5121a232e 2282 */
pcercuei 0:03b5121a232e 2283 static int
pcercuei 0:03b5121a232e 2284 xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
pcercuei 0:03b5121a232e 2285 if (node == NULL)
pcercuei 0:03b5121a232e 2286 return(0);
pcercuei 0:03b5121a232e 2287 if (node->type != XML_ELEMENT_NODE)
pcercuei 0:03b5121a232e 2288 return(0);
pcercuei 0:03b5121a232e 2289 if (node->ns == NULL)
pcercuei 0:03b5121a232e 2290 return(0);
pcercuei 0:03b5121a232e 2291 if ((xmlStrEqual(node->ns->href, XINCLUDE_NS)) ||
pcercuei 0:03b5121a232e 2292 (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS))) {
pcercuei 0:03b5121a232e 2293 if (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS)) {
pcercuei 0:03b5121a232e 2294 if (ctxt->legacy == 0) {
pcercuei 0:03b5121a232e 2295 #if 0 /* wait for the XML Core Working Group to get something stable ! */
pcercuei 0:03b5121a232e 2296 xmlXIncludeWarn(ctxt, node, XML_XINCLUDE_DEPRECATED_NS,
pcercuei 0:03b5121a232e 2297 "Deprecated XInclude namespace found, use %s",
pcercuei 0:03b5121a232e 2298 XINCLUDE_NS);
pcercuei 0:03b5121a232e 2299 #endif
pcercuei 0:03b5121a232e 2300 ctxt->legacy = 1;
pcercuei 0:03b5121a232e 2301 }
pcercuei 0:03b5121a232e 2302 }
pcercuei 0:03b5121a232e 2303 if (xmlStrEqual(node->name, XINCLUDE_NODE)) {
pcercuei 0:03b5121a232e 2304 xmlNodePtr child = node->children;
pcercuei 0:03b5121a232e 2305 int nb_fallback = 0;
pcercuei 0:03b5121a232e 2306
pcercuei 0:03b5121a232e 2307 while (child != NULL) {
pcercuei 0:03b5121a232e 2308 if ((child->type == XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 2309 (child->ns != NULL) &&
pcercuei 0:03b5121a232e 2310 ((xmlStrEqual(child->ns->href, XINCLUDE_NS)) ||
pcercuei 0:03b5121a232e 2311 (xmlStrEqual(child->ns->href, XINCLUDE_OLD_NS)))) {
pcercuei 0:03b5121a232e 2312 if (xmlStrEqual(child->name, XINCLUDE_NODE)) {
pcercuei 0:03b5121a232e 2313 xmlXIncludeErr(ctxt, node,
pcercuei 0:03b5121a232e 2314 XML_XINCLUDE_INCLUDE_IN_INCLUDE,
pcercuei 0:03b5121a232e 2315 "%s has an 'include' child\n",
pcercuei 0:03b5121a232e 2316 XINCLUDE_NODE);
pcercuei 0:03b5121a232e 2317 return(0);
pcercuei 0:03b5121a232e 2318 }
pcercuei 0:03b5121a232e 2319 if (xmlStrEqual(child->name, XINCLUDE_FALLBACK)) {
pcercuei 0:03b5121a232e 2320 nb_fallback++;
pcercuei 0:03b5121a232e 2321 }
pcercuei 0:03b5121a232e 2322 }
pcercuei 0:03b5121a232e 2323 child = child->next;
pcercuei 0:03b5121a232e 2324 }
pcercuei 0:03b5121a232e 2325 if (nb_fallback > 1) {
pcercuei 0:03b5121a232e 2326 xmlXIncludeErr(ctxt, node, XML_XINCLUDE_FALLBACKS_IN_INCLUDE,
pcercuei 0:03b5121a232e 2327 "%s has multiple fallback children\n",
pcercuei 0:03b5121a232e 2328 XINCLUDE_NODE);
pcercuei 0:03b5121a232e 2329 return(0);
pcercuei 0:03b5121a232e 2330 }
pcercuei 0:03b5121a232e 2331 return(1);
pcercuei 0:03b5121a232e 2332 }
pcercuei 0:03b5121a232e 2333 if (xmlStrEqual(node->name, XINCLUDE_FALLBACK)) {
pcercuei 0:03b5121a232e 2334 if ((node->parent == NULL) ||
pcercuei 0:03b5121a232e 2335 (node->parent->type != XML_ELEMENT_NODE) ||
pcercuei 0:03b5121a232e 2336 (node->parent->ns == NULL) ||
pcercuei 0:03b5121a232e 2337 ((!xmlStrEqual(node->parent->ns->href, XINCLUDE_NS)) &&
pcercuei 0:03b5121a232e 2338 (!xmlStrEqual(node->parent->ns->href, XINCLUDE_OLD_NS))) ||
pcercuei 0:03b5121a232e 2339 (!xmlStrEqual(node->parent->name, XINCLUDE_NODE))) {
pcercuei 0:03b5121a232e 2340 xmlXIncludeErr(ctxt, node,
pcercuei 0:03b5121a232e 2341 XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE,
pcercuei 0:03b5121a232e 2342 "%s is not the child of an 'include'\n",
pcercuei 0:03b5121a232e 2343 XINCLUDE_FALLBACK);
pcercuei 0:03b5121a232e 2344 }
pcercuei 0:03b5121a232e 2345 }
pcercuei 0:03b5121a232e 2346 }
pcercuei 0:03b5121a232e 2347 return(0);
pcercuei 0:03b5121a232e 2348 }
pcercuei 0:03b5121a232e 2349
pcercuei 0:03b5121a232e 2350 /**
pcercuei 0:03b5121a232e 2351 * xmlXIncludeDoProcess:
pcercuei 0:03b5121a232e 2352 * @ctxt: the XInclude processing context
pcercuei 0:03b5121a232e 2353 * @doc: an XML document
pcercuei 0:03b5121a232e 2354 * @tree: the top of the tree to process
pcercuei 0:03b5121a232e 2355 *
pcercuei 0:03b5121a232e 2356 * Implement the XInclude substitution on the XML document @doc
pcercuei 0:03b5121a232e 2357 *
pcercuei 0:03b5121a232e 2358 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2359 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2360 */
pcercuei 0:03b5121a232e 2361 static int
pcercuei 0:03b5121a232e 2362 xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) {
pcercuei 0:03b5121a232e 2363 xmlNodePtr cur;
pcercuei 0:03b5121a232e 2364 int ret = 0;
pcercuei 0:03b5121a232e 2365 int i, start;
pcercuei 0:03b5121a232e 2366
pcercuei 0:03b5121a232e 2367 if ((doc == NULL) || (tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
pcercuei 0:03b5121a232e 2368 return(-1);
pcercuei 0:03b5121a232e 2369 if (ctxt == NULL)
pcercuei 0:03b5121a232e 2370 return(-1);
pcercuei 0:03b5121a232e 2371
pcercuei 0:03b5121a232e 2372 if (doc->URL != NULL) {
pcercuei 0:03b5121a232e 2373 ret = xmlXIncludeURLPush(ctxt, doc->URL);
pcercuei 0:03b5121a232e 2374 if (ret < 0)
pcercuei 0:03b5121a232e 2375 return(-1);
pcercuei 0:03b5121a232e 2376 }
pcercuei 0:03b5121a232e 2377 start = ctxt->incNr;
pcercuei 0:03b5121a232e 2378
pcercuei 0:03b5121a232e 2379 /*
pcercuei 0:03b5121a232e 2380 * First phase: lookup the elements in the document
pcercuei 0:03b5121a232e 2381 */
pcercuei 0:03b5121a232e 2382 cur = tree;
pcercuei 0:03b5121a232e 2383 if (xmlXIncludeTestNode(ctxt, cur) == 1)
pcercuei 0:03b5121a232e 2384 xmlXIncludePreProcessNode(ctxt, cur);
pcercuei 0:03b5121a232e 2385 while ((cur != NULL) && (cur != tree->parent)) {
pcercuei 0:03b5121a232e 2386 /* TODO: need to work on entities -> stack */
pcercuei 0:03b5121a232e 2387 if ((cur->children != NULL) &&
pcercuei 0:03b5121a232e 2388 (cur->children->type != XML_ENTITY_DECL) &&
pcercuei 0:03b5121a232e 2389 (cur->children->type != XML_XINCLUDE_START) &&
pcercuei 0:03b5121a232e 2390 (cur->children->type != XML_XINCLUDE_END)) {
pcercuei 0:03b5121a232e 2391 cur = cur->children;
pcercuei 0:03b5121a232e 2392 if (xmlXIncludeTestNode(ctxt, cur))
pcercuei 0:03b5121a232e 2393 xmlXIncludePreProcessNode(ctxt, cur);
pcercuei 0:03b5121a232e 2394 } else if (cur->next != NULL) {
pcercuei 0:03b5121a232e 2395 cur = cur->next;
pcercuei 0:03b5121a232e 2396 if (xmlXIncludeTestNode(ctxt, cur))
pcercuei 0:03b5121a232e 2397 xmlXIncludePreProcessNode(ctxt, cur);
pcercuei 0:03b5121a232e 2398 } else {
pcercuei 0:03b5121a232e 2399 if (cur == tree)
pcercuei 0:03b5121a232e 2400 break;
pcercuei 0:03b5121a232e 2401 do {
pcercuei 0:03b5121a232e 2402 cur = cur->parent;
pcercuei 0:03b5121a232e 2403 if ((cur == NULL) || (cur == tree->parent))
pcercuei 0:03b5121a232e 2404 break; /* do */
pcercuei 0:03b5121a232e 2405 if (cur->next != NULL) {
pcercuei 0:03b5121a232e 2406 cur = cur->next;
pcercuei 0:03b5121a232e 2407 if (xmlXIncludeTestNode(ctxt, cur))
pcercuei 0:03b5121a232e 2408 xmlXIncludePreProcessNode(ctxt, cur);
pcercuei 0:03b5121a232e 2409 break; /* do */
pcercuei 0:03b5121a232e 2410 }
pcercuei 0:03b5121a232e 2411 } while (cur != NULL);
pcercuei 0:03b5121a232e 2412 }
pcercuei 0:03b5121a232e 2413 }
pcercuei 0:03b5121a232e 2414
pcercuei 0:03b5121a232e 2415 /*
pcercuei 0:03b5121a232e 2416 * Second Phase : collect the infosets fragments
pcercuei 0:03b5121a232e 2417 */
pcercuei 0:03b5121a232e 2418 for (i = start;i < ctxt->incNr; i++) {
pcercuei 0:03b5121a232e 2419 xmlXIncludeLoadNode(ctxt, i);
pcercuei 0:03b5121a232e 2420 ret++;
pcercuei 0:03b5121a232e 2421 }
pcercuei 0:03b5121a232e 2422
pcercuei 0:03b5121a232e 2423 /*
pcercuei 0:03b5121a232e 2424 * Third phase: extend the original document infoset.
pcercuei 0:03b5121a232e 2425 *
pcercuei 0:03b5121a232e 2426 * Originally we bypassed the inclusion if there were any errors
pcercuei 0:03b5121a232e 2427 * encountered on any of the XIncludes. A bug was raised (bug
pcercuei 0:03b5121a232e 2428 * 132588) requesting that we output the XIncludes without error,
pcercuei 0:03b5121a232e 2429 * so the check for inc!=NULL || xptr!=NULL was put in. This may
pcercuei 0:03b5121a232e 2430 * give some other problems in the future, but for now it seems to
pcercuei 0:03b5121a232e 2431 * work ok.
pcercuei 0:03b5121a232e 2432 *
pcercuei 0:03b5121a232e 2433 */
pcercuei 0:03b5121a232e 2434 for (i = ctxt->incBase;i < ctxt->incNr; i++) {
pcercuei 0:03b5121a232e 2435 if ((ctxt->incTab[i]->inc != NULL) ||
pcercuei 0:03b5121a232e 2436 (ctxt->incTab[i]->xptr != NULL) ||
pcercuei 0:03b5121a232e 2437 (ctxt->incTab[i]->emptyFb != 0)) /* (empty fallback) */
pcercuei 0:03b5121a232e 2438 xmlXIncludeIncludeNode(ctxt, i);
pcercuei 0:03b5121a232e 2439 }
pcercuei 0:03b5121a232e 2440
pcercuei 0:03b5121a232e 2441 if (doc->URL != NULL)
pcercuei 0:03b5121a232e 2442 xmlXIncludeURLPop(ctxt);
pcercuei 0:03b5121a232e 2443 return(ret);
pcercuei 0:03b5121a232e 2444 }
pcercuei 0:03b5121a232e 2445
pcercuei 0:03b5121a232e 2446 /**
pcercuei 0:03b5121a232e 2447 * xmlXIncludeSetFlags:
pcercuei 0:03b5121a232e 2448 * @ctxt: an XInclude processing context
pcercuei 0:03b5121a232e 2449 * @flags: a set of xmlParserOption used for parsing XML includes
pcercuei 0:03b5121a232e 2450 *
pcercuei 0:03b5121a232e 2451 * Set the flags used for further processing of XML resources.
pcercuei 0:03b5121a232e 2452 *
pcercuei 0:03b5121a232e 2453 * Returns 0 in case of success and -1 in case of error.
pcercuei 0:03b5121a232e 2454 */
pcercuei 0:03b5121a232e 2455 int
pcercuei 0:03b5121a232e 2456 xmlXIncludeSetFlags(xmlXIncludeCtxtPtr ctxt, int flags) {
pcercuei 0:03b5121a232e 2457 if (ctxt == NULL)
pcercuei 0:03b5121a232e 2458 return(-1);
pcercuei 0:03b5121a232e 2459 ctxt->parseFlags = flags;
pcercuei 0:03b5121a232e 2460 return(0);
pcercuei 0:03b5121a232e 2461 }
pcercuei 0:03b5121a232e 2462
pcercuei 0:03b5121a232e 2463 /**
pcercuei 0:03b5121a232e 2464 * xmlXIncludeProcessTreeFlagsData:
pcercuei 0:03b5121a232e 2465 * @tree: an XML node
pcercuei 0:03b5121a232e 2466 * @flags: a set of xmlParserOption used for parsing XML includes
pcercuei 0:03b5121a232e 2467 * @data: application data that will be passed to the parser context
pcercuei 0:03b5121a232e 2468 * in the _private field of the parser context(s)
pcercuei 0:03b5121a232e 2469 *
pcercuei 0:03b5121a232e 2470 * Implement the XInclude substitution on the XML node @tree
pcercuei 0:03b5121a232e 2471 *
pcercuei 0:03b5121a232e 2472 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2473 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2474 */
pcercuei 0:03b5121a232e 2475
pcercuei 0:03b5121a232e 2476 int
pcercuei 0:03b5121a232e 2477 xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) {
pcercuei 0:03b5121a232e 2478 xmlXIncludeCtxtPtr ctxt;
pcercuei 0:03b5121a232e 2479 int ret = 0;
pcercuei 0:03b5121a232e 2480
pcercuei 0:03b5121a232e 2481 if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL) ||
pcercuei 0:03b5121a232e 2482 (tree->doc == NULL))
pcercuei 0:03b5121a232e 2483 return(-1);
pcercuei 0:03b5121a232e 2484
pcercuei 0:03b5121a232e 2485 ctxt = xmlXIncludeNewContext(tree->doc);
pcercuei 0:03b5121a232e 2486 if (ctxt == NULL)
pcercuei 0:03b5121a232e 2487 return(-1);
pcercuei 0:03b5121a232e 2488 ctxt->_private = data;
pcercuei 0:03b5121a232e 2489 ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL);
pcercuei 0:03b5121a232e 2490 xmlXIncludeSetFlags(ctxt, flags);
pcercuei 0:03b5121a232e 2491 ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree);
pcercuei 0:03b5121a232e 2492 if ((ret >= 0) && (ctxt->nbErrors > 0))
pcercuei 0:03b5121a232e 2493 ret = -1;
pcercuei 0:03b5121a232e 2494
pcercuei 0:03b5121a232e 2495 xmlXIncludeFreeContext(ctxt);
pcercuei 0:03b5121a232e 2496 return(ret);
pcercuei 0:03b5121a232e 2497 }
pcercuei 0:03b5121a232e 2498
pcercuei 0:03b5121a232e 2499 /**
pcercuei 0:03b5121a232e 2500 * xmlXIncludeProcessFlagsData:
pcercuei 0:03b5121a232e 2501 * @doc: an XML document
pcercuei 0:03b5121a232e 2502 * @flags: a set of xmlParserOption used for parsing XML includes
pcercuei 0:03b5121a232e 2503 * @data: application data that will be passed to the parser context
pcercuei 0:03b5121a232e 2504 * in the _private field of the parser context(s)
pcercuei 0:03b5121a232e 2505 *
pcercuei 0:03b5121a232e 2506 * Implement the XInclude substitution on the XML document @doc
pcercuei 0:03b5121a232e 2507 *
pcercuei 0:03b5121a232e 2508 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2509 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2510 */
pcercuei 0:03b5121a232e 2511 int
pcercuei 0:03b5121a232e 2512 xmlXIncludeProcessFlagsData(xmlDocPtr doc, int flags, void *data) {
pcercuei 0:03b5121a232e 2513 xmlNodePtr tree;
pcercuei 0:03b5121a232e 2514
pcercuei 0:03b5121a232e 2515 if (doc == NULL)
pcercuei 0:03b5121a232e 2516 return(-1);
pcercuei 0:03b5121a232e 2517 tree = xmlDocGetRootElement(doc);
pcercuei 0:03b5121a232e 2518 if (tree == NULL)
pcercuei 0:03b5121a232e 2519 return(-1);
pcercuei 0:03b5121a232e 2520 return(xmlXIncludeProcessTreeFlagsData(tree, flags, data));
pcercuei 0:03b5121a232e 2521 }
pcercuei 0:03b5121a232e 2522
pcercuei 0:03b5121a232e 2523 /**
pcercuei 0:03b5121a232e 2524 * xmlXIncludeProcessFlags:
pcercuei 0:03b5121a232e 2525 * @doc: an XML document
pcercuei 0:03b5121a232e 2526 * @flags: a set of xmlParserOption used for parsing XML includes
pcercuei 0:03b5121a232e 2527 *
pcercuei 0:03b5121a232e 2528 * Implement the XInclude substitution on the XML document @doc
pcercuei 0:03b5121a232e 2529 *
pcercuei 0:03b5121a232e 2530 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2531 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2532 */
pcercuei 0:03b5121a232e 2533 int
pcercuei 0:03b5121a232e 2534 xmlXIncludeProcessFlags(xmlDocPtr doc, int flags) {
pcercuei 0:03b5121a232e 2535 return xmlXIncludeProcessFlagsData(doc, flags, NULL);
pcercuei 0:03b5121a232e 2536 }
pcercuei 0:03b5121a232e 2537
pcercuei 0:03b5121a232e 2538 /**
pcercuei 0:03b5121a232e 2539 * xmlXIncludeProcess:
pcercuei 0:03b5121a232e 2540 * @doc: an XML document
pcercuei 0:03b5121a232e 2541 *
pcercuei 0:03b5121a232e 2542 * Implement the XInclude substitution on the XML document @doc
pcercuei 0:03b5121a232e 2543 *
pcercuei 0:03b5121a232e 2544 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2545 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2546 */
pcercuei 0:03b5121a232e 2547 int
pcercuei 0:03b5121a232e 2548 xmlXIncludeProcess(xmlDocPtr doc) {
pcercuei 0:03b5121a232e 2549 return(xmlXIncludeProcessFlags(doc, 0));
pcercuei 0:03b5121a232e 2550 }
pcercuei 0:03b5121a232e 2551
pcercuei 0:03b5121a232e 2552 /**
pcercuei 0:03b5121a232e 2553 * xmlXIncludeProcessTreeFlags:
pcercuei 0:03b5121a232e 2554 * @tree: a node in an XML document
pcercuei 0:03b5121a232e 2555 * @flags: a set of xmlParserOption used for parsing XML includes
pcercuei 0:03b5121a232e 2556 *
pcercuei 0:03b5121a232e 2557 * Implement the XInclude substitution for the given subtree
pcercuei 0:03b5121a232e 2558 *
pcercuei 0:03b5121a232e 2559 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2560 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2561 */
pcercuei 0:03b5121a232e 2562 int
pcercuei 0:03b5121a232e 2563 xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
pcercuei 0:03b5121a232e 2564 xmlXIncludeCtxtPtr ctxt;
pcercuei 0:03b5121a232e 2565 int ret = 0;
pcercuei 0:03b5121a232e 2566
pcercuei 0:03b5121a232e 2567 if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL) ||
pcercuei 0:03b5121a232e 2568 (tree->doc == NULL))
pcercuei 0:03b5121a232e 2569 return(-1);
pcercuei 0:03b5121a232e 2570 ctxt = xmlXIncludeNewContext(tree->doc);
pcercuei 0:03b5121a232e 2571 if (ctxt == NULL)
pcercuei 0:03b5121a232e 2572 return(-1);
pcercuei 0:03b5121a232e 2573 ctxt->base = xmlNodeGetBase(tree->doc, tree);
pcercuei 0:03b5121a232e 2574 xmlXIncludeSetFlags(ctxt, flags);
pcercuei 0:03b5121a232e 2575 ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree);
pcercuei 0:03b5121a232e 2576 if ((ret >= 0) && (ctxt->nbErrors > 0))
pcercuei 0:03b5121a232e 2577 ret = -1;
pcercuei 0:03b5121a232e 2578
pcercuei 0:03b5121a232e 2579 xmlXIncludeFreeContext(ctxt);
pcercuei 0:03b5121a232e 2580 return(ret);
pcercuei 0:03b5121a232e 2581 }
pcercuei 0:03b5121a232e 2582
pcercuei 0:03b5121a232e 2583 /**
pcercuei 0:03b5121a232e 2584 * xmlXIncludeProcessTree:
pcercuei 0:03b5121a232e 2585 * @tree: a node in an XML document
pcercuei 0:03b5121a232e 2586 *
pcercuei 0:03b5121a232e 2587 * Implement the XInclude substitution for the given subtree
pcercuei 0:03b5121a232e 2588 *
pcercuei 0:03b5121a232e 2589 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2590 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2591 */
pcercuei 0:03b5121a232e 2592 int
pcercuei 0:03b5121a232e 2593 xmlXIncludeProcessTree(xmlNodePtr tree) {
pcercuei 0:03b5121a232e 2594 return(xmlXIncludeProcessTreeFlags(tree, 0));
pcercuei 0:03b5121a232e 2595 }
pcercuei 0:03b5121a232e 2596
pcercuei 0:03b5121a232e 2597 /**
pcercuei 0:03b5121a232e 2598 * xmlXIncludeProcessNode:
pcercuei 0:03b5121a232e 2599 * @ctxt: an existing XInclude context
pcercuei 0:03b5121a232e 2600 * @node: a node in an XML document
pcercuei 0:03b5121a232e 2601 *
pcercuei 0:03b5121a232e 2602 * Implement the XInclude substitution for the given subtree reusing
pcercuei 0:03b5121a232e 2603 * the informations and data coming from the given context.
pcercuei 0:03b5121a232e 2604 *
pcercuei 0:03b5121a232e 2605 * Returns 0 if no substitution were done, -1 if some processing failed
pcercuei 0:03b5121a232e 2606 * or the number of substitutions done.
pcercuei 0:03b5121a232e 2607 */
pcercuei 0:03b5121a232e 2608 int
pcercuei 0:03b5121a232e 2609 xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
pcercuei 0:03b5121a232e 2610 int ret = 0;
pcercuei 0:03b5121a232e 2611
pcercuei 0:03b5121a232e 2612 if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
pcercuei 0:03b5121a232e 2613 (node->doc == NULL) || (ctxt == NULL))
pcercuei 0:03b5121a232e 2614 return(-1);
pcercuei 0:03b5121a232e 2615 ret = xmlXIncludeDoProcess(ctxt, node->doc, node);
pcercuei 0:03b5121a232e 2616 if ((ret >= 0) && (ctxt->nbErrors > 0))
pcercuei 0:03b5121a232e 2617 ret = -1;
pcercuei 0:03b5121a232e 2618 return(ret);
pcercuei 0:03b5121a232e 2619 }
pcercuei 0:03b5121a232e 2620
pcercuei 0:03b5121a232e 2621 #else /* !LIBXML_XINCLUDE_ENABLED */
pcercuei 0:03b5121a232e 2622 #endif
pcercuei 0:03b5121a232e 2623 #define bottom_xinclude
pcercuei 0:03b5121a232e 2624 #include "elfgcchack.h"
pcercuei 0:03b5121a232e 2625