Return to php_xml.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / soap |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Authors: Brad Lafountain <rodif_bl@yahoo.com> | ! 16: | Shane Caraveo <shane@caraveo.com> | ! 17: | Dmitry Stogov <dmitry@zend.com> | ! 18: +----------------------------------------------------------------------+ ! 19: */ ! 20: /* $Id: php_xml.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 21: ! 22: #include "php_soap.h" ! 23: #include "libxml/parser.h" ! 24: #include "libxml/parserInternals.h" ! 25: ! 26: /* Channel libxml file io layer through the PHP streams subsystem. ! 27: * This allows use of ftps:// and https:// urls */ ! 28: ! 29: static int is_blank(const xmlChar* str) ! 30: { ! 31: while (*str != '\0') { ! 32: if (*str != ' ' && *str != 0x9 && *str != 0xa && *str != 0xd) { ! 33: return 0; ! 34: } ! 35: str++; ! 36: } ! 37: return 1; ! 38: } ! 39: ! 40: /* removes all empty text, comments and other insignoficant nodes */ ! 41: static void cleanup_xml_node(xmlNodePtr node) ! 42: { ! 43: xmlNodePtr trav; ! 44: xmlNodePtr del = NULL; ! 45: ! 46: trav = node->children; ! 47: while (trav != NULL) { ! 48: if (del != NULL) { ! 49: xmlUnlinkNode(del); ! 50: xmlFreeNode(del); ! 51: del = NULL; ! 52: } ! 53: if (trav->type == XML_TEXT_NODE) { ! 54: if (is_blank(trav->content)) { ! 55: del = trav; ! 56: } ! 57: } else if ((trav->type != XML_ELEMENT_NODE) && ! 58: (trav->type != XML_CDATA_SECTION_NODE)) { ! 59: del = trav; ! 60: } else if (trav->children != NULL) { ! 61: cleanup_xml_node(trav); ! 62: } ! 63: trav = trav->next; ! 64: } ! 65: if (del != NULL) { ! 66: xmlUnlinkNode(del); ! 67: xmlFreeNode(del); ! 68: } ! 69: } ! 70: ! 71: static void soap_ignorableWhitespace(void *ctx, const xmlChar *ch, int len) ! 72: { ! 73: } ! 74: ! 75: static void soap_Comment(void *ctx, const xmlChar *value) ! 76: { ! 77: } ! 78: ! 79: xmlDocPtr soap_xmlParseFile(const char *filename TSRMLS_DC) ! 80: { ! 81: xmlParserCtxtPtr ctxt = NULL; ! 82: xmlDocPtr ret; ! 83: zend_bool old_allow_url_fopen; ! 84: ! 85: /* ! 86: xmlInitParser(); ! 87: */ ! 88: ! 89: old_allow_url_fopen = PG(allow_url_fopen); ! 90: PG(allow_url_fopen) = 1; ! 91: ctxt = xmlCreateFileParserCtxt(filename); ! 92: PG(allow_url_fopen) = old_allow_url_fopen; ! 93: if (ctxt) { ! 94: ctxt->keepBlanks = 0; ! 95: ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; ! 96: ctxt->sax->comment = soap_Comment; ! 97: ctxt->sax->warning = NULL; ! 98: ctxt->sax->error = NULL; ! 99: /*ctxt->sax->fatalError = NULL;*/ ! 100: xmlParseDocument(ctxt); ! 101: if (ctxt->wellFormed) { ! 102: ret = ctxt->myDoc; ! 103: if (ret->URL == NULL && ctxt->directory != NULL) { ! 104: ret->URL = xmlCharStrdup(ctxt->directory); ! 105: } ! 106: } else { ! 107: ret = NULL; ! 108: xmlFreeDoc(ctxt->myDoc); ! 109: ctxt->myDoc = NULL; ! 110: } ! 111: xmlFreeParserCtxt(ctxt); ! 112: } else { ! 113: ret = NULL; ! 114: } ! 115: ! 116: /* ! 117: xmlCleanupParser(); ! 118: */ ! 119: ! 120: if (ret) { ! 121: cleanup_xml_node((xmlNodePtr)ret); ! 122: } ! 123: return ret; ! 124: } ! 125: ! 126: xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size) ! 127: { ! 128: xmlParserCtxtPtr ctxt = NULL; ! 129: xmlDocPtr ret; ! 130: ! 131: /* ! 132: xmlInitParser(); ! 133: */ ! 134: ctxt = xmlCreateMemoryParserCtxt(buf, buf_size); ! 135: if (ctxt) { ! 136: ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; ! 137: ctxt->sax->comment = soap_Comment; ! 138: ctxt->sax->warning = NULL; ! 139: ctxt->sax->error = NULL; ! 140: /*ctxt->sax->fatalError = NULL;*/ ! 141: #if LIBXML_VERSION >= 20703 ! 142: ctxt->options |= XML_PARSE_HUGE; ! 143: #endif ! 144: xmlParseDocument(ctxt); ! 145: if (ctxt->wellFormed) { ! 146: ret = ctxt->myDoc; ! 147: if (ret->URL == NULL && ctxt->directory != NULL) { ! 148: ret->URL = xmlCharStrdup(ctxt->directory); ! 149: } ! 150: } else { ! 151: ret = NULL; ! 152: xmlFreeDoc(ctxt->myDoc); ! 153: ctxt->myDoc = NULL; ! 154: } ! 155: xmlFreeParserCtxt(ctxt); ! 156: } else { ! 157: ret = NULL; ! 158: } ! 159: ! 160: /* ! 161: xmlCleanupParser(); ! 162: */ ! 163: ! 164: /* ! 165: if (ret) { ! 166: cleanup_xml_node((xmlNodePtr)ret); ! 167: } ! 168: */ ! 169: return ret; ! 170: } ! 171: ! 172: #ifndef ZEND_ENGINE_2 ! 173: int php_stream_xmlIO_match_wrapper(const char *filename) ! 174: { ! 175: TSRMLS_FETCH(); ! 176: return php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ? 1 : 0; ! 177: } ! 178: ! 179: void *php_stream_xmlIO_open_wrapper(const char *filename) ! 180: { ! 181: TSRMLS_FETCH(); ! 182: return php_stream_open_wrapper((char*)filename, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); ! 183: } ! 184: ! 185: int php_stream_xmlIO_read(void *context, char *buffer, int len) ! 186: { ! 187: TSRMLS_FETCH(); ! 188: return php_stream_read((php_stream*)context, buffer, len); ! 189: } ! 190: ! 191: int php_stream_xmlIO_close(void *context) ! 192: { ! 193: TSRMLS_FETCH(); ! 194: return php_stream_close((php_stream*)context); ! 195: } ! 196: #endif ! 197: ! 198: xmlNsPtr attr_find_ns(xmlAttrPtr node) ! 199: { ! 200: if (node->ns) { ! 201: return node->ns; ! 202: } else if (node->parent->ns) { ! 203: return node->parent->ns; ! 204: } else { ! 205: return xmlSearchNs(node->doc, node->parent, NULL); ! 206: } ! 207: } ! 208: ! 209: xmlNsPtr node_find_ns(xmlNodePtr node) ! 210: { ! 211: if (node->ns) { ! 212: return node->ns; ! 213: } else { ! 214: return xmlSearchNs(node->doc, node, NULL); ! 215: } ! 216: } ! 217: ! 218: int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns) ! 219: { ! 220: if (name == NULL || strcmp((char*)node->name, name) == 0) { ! 221: if (ns) { ! 222: xmlNsPtr nsPtr = attr_find_ns(node); ! 223: if (nsPtr) { ! 224: return (strcmp((char*)nsPtr->href, ns) == 0); ! 225: } else { ! 226: return FALSE; ! 227: } ! 228: } ! 229: return TRUE; ! 230: } ! 231: return FALSE; ! 232: } ! 233: ! 234: int node_is_equal_ex(xmlNodePtr node, char *name, char *ns) ! 235: { ! 236: if (name == NULL || strcmp((char*)node->name, name) == 0) { ! 237: if (ns) { ! 238: xmlNsPtr nsPtr = node_find_ns(node); ! 239: if (nsPtr) { ! 240: return (strcmp((char*)nsPtr->href, ns) == 0); ! 241: } else { ! 242: return FALSE; ! 243: } ! 244: } ! 245: return TRUE; ! 246: } ! 247: return FALSE; ! 248: } ! 249: ! 250: ! 251: xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns) ! 252: { ! 253: while (node!=NULL) { ! 254: if (attr_is_equal_ex(node, name, ns)) { ! 255: return node; ! 256: } ! 257: node = node->next; ! 258: } ! 259: return NULL; ! 260: } ! 261: ! 262: xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns) ! 263: { ! 264: while (node!=NULL) { ! 265: if (node_is_equal_ex(node, name, ns)) { ! 266: return node; ! 267: } ! 268: node = node->next; ! 269: } ! 270: return NULL; ! 271: } ! 272: ! 273: xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns) ! 274: { ! 275: while (node != NULL) { ! 276: if (node_is_equal_ex(node, name, ns)) { ! 277: return node; ! 278: } else if (node->children != NULL) { ! 279: xmlNodePtr tmp = get_node_recurisve_ex(node->children, name, ns); ! 280: if (tmp) { ! 281: return tmp; ! 282: } ! 283: } ! 284: node = node->next; ! 285: } ! 286: return NULL; ! 287: } ! 288: ! 289: xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns) ! 290: { ! 291: xmlAttrPtr attr; ! 292: ! 293: while (node != NULL) { ! 294: if (name != NULL) { ! 295: node = get_node_ex(node, name, name_ns); ! 296: if (node==NULL) { ! 297: return NULL; ! 298: } ! 299: } ! 300: ! 301: attr = get_attribute_ex(node->properties, attribute, attr_ns); ! 302: if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) { ! 303: return node; ! 304: } ! 305: node = node->next; ! 306: } ! 307: return NULL; ! 308: } ! 309: ! 310: xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns) ! 311: { ! 312: while (node != NULL) { ! 313: if (node_is_equal_ex(node, name, name_ns)) { ! 314: xmlAttrPtr attr = get_attribute_ex(node->properties, attribute, attr_ns); ! 315: if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) { ! 316: return node; ! 317: } ! 318: } ! 319: if (node->children != NULL) { ! 320: xmlNodePtr tmp = get_node_with_attribute_recursive_ex(node->children, name, name_ns, attribute, value, attr_ns); ! 321: if (tmp) { ! 322: return tmp; ! 323: } ! 324: } ! 325: node = node->next; ! 326: } ! 327: return NULL; ! 328: } ! 329: ! 330: int parse_namespace(const xmlChar *inval, char **value, char **namespace) ! 331: { ! 332: char *found = strrchr((char*)inval, ':'); ! 333: ! 334: if (found != NULL && found != (char*)inval) { ! 335: (*namespace) = estrndup((char*)inval, found - (char*)inval); ! 336: (*value) = estrdup(++found); ! 337: } else { ! 338: (*value) = estrdup((char*)inval); ! 339: (*namespace) = NULL; ! 340: } ! 341: ! 342: return FALSE; ! 343: }