diff options
author | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:34:21 -0400 |
---|---|---|
committer | Mark A. Hershberger <mah@debian.(none)> | 2009-03-25 00:34:21 -0400 |
commit | 0e920280a2e04b110827bb766b9f29e3d581c4ee (patch) | |
tree | 8f2125f3d00fe3089e3b94adb06f04479ee15f2a /ext/soap/php_xml.c | |
download | php-0e920280a2e04b110827bb766b9f29e3d581c4ee.tar.gz |
Imported Upstream version 5.0.4upstream/5.0.4
Diffstat (limited to 'ext/soap/php_xml.c')
-rw-r--r-- | ext/soap/php_xml.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c new file mode 100644 index 000000000..35dc825cb --- /dev/null +++ b/ext/soap/php_xml.c @@ -0,0 +1,335 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2004 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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.22 2004/02/13 15:19:09 dmitry 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 char* 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) +{ + xmlParserCtxtPtr ctxt = NULL; + xmlDocPtr ret; + +/* + xmlInitParser(); +*/ + ctxt = xmlCreateFileParserCtxt(filename); + 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 = xmlStrdup(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 = xmlStrdup(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(node->name, name) == 0) { + if (ns) { + xmlNsPtr nsPtr = attr_find_ns(node); + if (nsPtr) { + return (strcmp(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(node->name, name) == 0) { + if (ns) { + xmlNsPtr nsPtr = node_find_ns(node); + if (nsPtr) { + return (strcmp(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(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(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 char *inval, char **value, char **namespace) +{ + char *found = strrchr(inval, ':'); + + if (found != NULL && found != inval) { + (*namespace) = estrndup(inval, found - inval); + (*value) = estrdup(++found); + } else { + (*value) = estrdup(inval); + (*namespace) = NULL; + } + + return FALSE; +} |