/php5/ext/soap/php_xml.c
C | 340 lines | 263 code | 35 blank | 42 comment | 100 complexity | 5256db2b76f73e4dd8cf6aff8123a3b5 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
- /*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Brad Lafountain <rodif_bl@yahoo.com> |
- | Shane Caraveo <shane@caraveo.com> |
- | Dmitry Stogov <dmitry@zend.com> |
- +----------------------------------------------------------------------+
- */
- /* $Id: php_xml.c,v 1.25.2.1.2.2.2.2 2008/12/31 11:15:43 sebastian Exp $ */
- #include "php_soap.h"
- #include "libxml/parser.h"
- #include "libxml/parserInternals.h"
- /* Channel libxml file io layer through the PHP streams subsystem.
- * This allows use of ftps:// and https:// urls */
- static int is_blank(const xmlChar* str)
- {
- while (*str != '\0') {
- if (*str != ' ' && *str != 0x9 && *str != 0xa && *str != 0xd) {
- return 0;
- }
- str++;
- }
- return 1;
- }
- /* removes all empty text, comments and other insignoficant nodes */
- static void cleanup_xml_node(xmlNodePtr node)
- {
- xmlNodePtr trav;
- xmlNodePtr del = NULL;
- trav = node->children;
- while (trav != NULL) {
- if (del != NULL) {
- xmlUnlinkNode(del);
- xmlFreeNode(del);
- del = NULL;
- }
- if (trav->type == XML_TEXT_NODE) {
- if (is_blank(trav->content)) {
- del = trav;
- }
- } else if ((trav->type != XML_ELEMENT_NODE) &&
- (trav->type != XML_CDATA_SECTION_NODE)) {
- del = trav;
- } else if (trav->children != NULL) {
- cleanup_xml_node(trav);
- }
- trav = trav->next;
- }
- if (del != NULL) {
- xmlUnlinkNode(del);
- xmlFreeNode(del);
- }
- }
- static void soap_ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
- {
- }
- static void soap_Comment(void *ctx, const xmlChar *value)
- {
- }
- xmlDocPtr soap_xmlParseFile(const char *filename TSRMLS_DC)
- {
- xmlParserCtxtPtr ctxt = NULL;
- xmlDocPtr ret;
- zend_bool old_allow_url_fopen;
- /*
- xmlInitParser();
- */
- old_allow_url_fopen = PG(allow_url_fopen);
- PG(allow_url_fopen) = 1;
- ctxt = xmlCreateFileParserCtxt(filename);
- PG(allow_url_fopen) = old_allow_url_fopen;
- if (ctxt) {
- ctxt->keepBlanks = 0;
- ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
- ctxt->sax->comment = soap_Comment;
- ctxt->sax->warning = NULL;
- ctxt->sax->error = NULL;
- /*ctxt->sax->fatalError = NULL;*/
- xmlParseDocument(ctxt);
- if (ctxt->wellFormed) {
- ret = ctxt->myDoc;
- if (ret->URL == NULL && ctxt->directory != NULL) {
- ret->URL = xmlCharStrdup(ctxt->directory);
- }
- } else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- xmlFreeParserCtxt(ctxt);
- } else {
- ret = NULL;
- }
- /*
- xmlCleanupParser();
- */
- if (ret) {
- cleanup_xml_node((xmlNodePtr)ret);
- }
- return ret;
- }
- xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size)
- {
- xmlParserCtxtPtr ctxt = NULL;
- xmlDocPtr ret;
- /*
- xmlInitParser();
- */
- ctxt = xmlCreateMemoryParserCtxt(buf, buf_size);
- if (ctxt) {
- ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
- ctxt->sax->comment = soap_Comment;
- ctxt->sax->warning = NULL;
- ctxt->sax->error = NULL;
- /*ctxt->sax->fatalError = NULL;*/
- xmlParseDocument(ctxt);
- if (ctxt->wellFormed) {
- ret = ctxt->myDoc;
- if (ret->URL == NULL && ctxt->directory != NULL) {
- ret->URL = xmlCharStrdup(ctxt->directory);
- }
- } else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- xmlFreeParserCtxt(ctxt);
- } else {
- ret = NULL;
- }
- /*
- xmlCleanupParser();
- */
- /*
- if (ret) {
- cleanup_xml_node((xmlNodePtr)ret);
- }
- */
- return ret;
- }
- #ifndef ZEND_ENGINE_2
- int php_stream_xmlIO_match_wrapper(const char *filename)
- {
- TSRMLS_FETCH();
- return php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ? 1 : 0;
- }
- void *php_stream_xmlIO_open_wrapper(const char *filename)
- {
- TSRMLS_FETCH();
- return php_stream_open_wrapper((char*)filename, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
- }
- int php_stream_xmlIO_read(void *context, char *buffer, int len)
- {
- TSRMLS_FETCH();
- return php_stream_read((php_stream*)context, buffer, len);
- }
- int php_stream_xmlIO_close(void *context)
- {
- TSRMLS_FETCH();
- return php_stream_close((php_stream*)context);
- }
- #endif
- xmlNsPtr attr_find_ns(xmlAttrPtr node)
- {
- if (node->ns) {
- return node->ns;
- } else if (node->parent->ns) {
- return node->parent->ns;
- } else {
- return xmlSearchNs(node->doc, node->parent, NULL);
- }
- }
- xmlNsPtr node_find_ns(xmlNodePtr node)
- {
- if (node->ns) {
- return node->ns;
- } else {
- return xmlSearchNs(node->doc, node, NULL);
- }
- }
- int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
- {
- if (name == NULL || strcmp((char*)node->name, name) == 0) {
- if (ns) {
- xmlNsPtr nsPtr = attr_find_ns(node);
- if (nsPtr) {
- return (strcmp((char*)nsPtr->href, ns) == 0);
- } else {
- return FALSE;
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
- {
- if (name == NULL || strcmp((char*)node->name, name) == 0) {
- if (ns) {
- xmlNsPtr nsPtr = node_find_ns(node);
- if (nsPtr) {
- return (strcmp((char*)nsPtr->href, ns) == 0);
- } else {
- return FALSE;
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns)
- {
- while (node!=NULL) {
- if (attr_is_equal_ex(node, name, ns)) {
- return node;
- }
- node = node->next;
- }
- return NULL;
- }
- xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns)
- {
- while (node!=NULL) {
- if (node_is_equal_ex(node, name, ns)) {
- return node;
- }
- node = node->next;
- }
- return NULL;
- }
- xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns)
- {
- while (node != NULL) {
- if (node_is_equal_ex(node, name, ns)) {
- return node;
- } else if (node->children != NULL) {
- xmlNodePtr tmp = get_node_recurisve_ex(node->children, name, ns);
- if (tmp) {
- return tmp;
- }
- }
- node = node->next;
- }
- return NULL;
- }
- xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
- {
- xmlAttrPtr attr;
- while (node != NULL) {
- if (name != NULL) {
- node = get_node_ex(node, name, name_ns);
- if (node==NULL) {
- return NULL;
- }
- }
- attr = get_attribute_ex(node->properties, attribute, attr_ns);
- if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
- return node;
- }
- node = node->next;
- }
- return NULL;
- }
- xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
- {
- while (node != NULL) {
- if (node_is_equal_ex(node, name, name_ns)) {
- xmlAttrPtr attr = get_attribute_ex(node->properties, attribute, attr_ns);
- if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
- return node;
- }
- }
- if (node->children != NULL) {
- xmlNodePtr tmp = get_node_with_attribute_recursive_ex(node->children, name, name_ns, attribute, value, attr_ns);
- if (tmp) {
- return tmp;
- }
- }
- node = node->next;
- }
- return NULL;
- }
- int parse_namespace(const xmlChar *inval, char **value, char **namespace)
- {
- char *found = strrchr((char*)inval, ':');
- if (found != NULL && found != (char*)inval) {
- (*namespace) = estrndup((char*)inval, found - (char*)inval);
- (*value) = estrdup(++found);
- } else {
- (*value) = estrdup((char*)inval);
- (*namespace) = NULL;
- }
- return FALSE;
- }