php-src/ext/soap/php_xml.c

341 lines
7.9 KiB
C
Raw Normal View History

2004-01-29 09:27:06 +00:00
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
2006-01-01 12:51:34 +00:00
| Copyright (c) 1997-2006 The PHP Group |
2004-01-29 09:27:06 +00:00
+----------------------------------------------------------------------+
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 of the PHP license, |
2004-01-29 09:27:06 +00:00
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
2006-01-01 12:51:34 +00:00
| http://www.php.net/license/3_01.txt |
2004-01-29 09:27:06 +00:00
| 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. |
+----------------------------------------------------------------------+
2004-01-29 11:51:11 +00:00
| Authors: Brad Lafountain <rodif_bl@yahoo.com> |
| Shane Caraveo <shane@caraveo.com> |
| Dmitry Stogov <dmitry@zend.com> |
2004-01-29 09:27:06 +00:00
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include "php_soap.h"
2004-02-05 09:28:09 +00:00
#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 */
2006-07-11 14:24:18 +00:00
static int is_blank(const xmlChar* str)
2004-02-05 09:28:09 +00:00
{
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)
{
}
2005-08-02 11:15:42 +00:00
xmlDocPtr soap_xmlParseFile(const char *filename TSRMLS_DC)
2004-02-05 09:28:09 +00:00
{
2004-02-13 15:19:09 +00:00
xmlParserCtxtPtr ctxt = NULL;
2004-02-05 09:28:09 +00:00
xmlDocPtr ret;
zend_bool old_allow_url_fopen;
2004-02-05 09:28:09 +00:00
/*
xmlInitParser();
*/
old_allow_url_fopen = PG(allow_url_fopen);
PG(allow_url_fopen) = 1;
2004-02-05 09:28:09 +00:00
ctxt = xmlCreateFileParserCtxt(filename);
PG(allow_url_fopen) = old_allow_url_fopen;
2004-02-05 09:28:09 +00:00
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) {
2006-07-11 14:24:18 +00:00
ret->URL = xmlCharStrdup(ctxt->directory);
2004-02-05 09:28:09 +00:00
}
} else {
ret = NULL;
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
} else {
2004-02-13 15:19:09 +00:00
ret = NULL;
2004-02-05 09:28:09 +00:00
}
/*
xmlCleanupParser();
*/
if (ret) {
cleanup_xml_node((xmlNodePtr)ret);
}
return ret;
}
xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size)
{
2004-02-13 15:19:09 +00:00
xmlParserCtxtPtr ctxt = NULL;
2004-02-05 09:28:09 +00:00
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) {
2006-07-11 14:24:18 +00:00
ret->URL = xmlCharStrdup(ctxt->directory);
2004-02-05 09:28:09 +00:00
}
} else {
ret = NULL;
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
xmlFreeParserCtxt(ctxt);
} else {
2004-02-13 15:19:09 +00:00
ret = NULL;
2004-02-05 09:28:09 +00:00
}
/*
xmlCleanupParser();
*/
/*
if (ret) {
cleanup_xml_node((xmlNodePtr)ret);
}
*/
return ret;
}
2004-02-06 08:01:35 +00:00
#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);
}
2004-02-06 08:01:35 +00:00
#endif
xmlNsPtr attr_find_ns(xmlAttrPtr node)
{
2004-01-09 18:22:03 +00:00
if (node->ns) {
return node->ns;
2004-01-09 18:22:03 +00:00
} else if (node->parent->ns) {
return node->parent->ns;
2004-01-09 18:22:03 +00:00
} else {
return xmlSearchNs(node->doc, node->parent, NULL);
2004-01-09 18:22:03 +00:00
}
}
xmlNsPtr node_find_ns(xmlNodePtr node)
{
2004-01-09 18:22:03 +00:00
if (node->ns) {
return node->ns;
2004-01-09 18:22:03 +00:00
} else {
return xmlSearchNs(node->doc, node, NULL);
2004-01-09 18:22:03 +00:00
}
}
int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
{
2006-07-11 14:24:18 +00:00
if (name == NULL || strcmp((char*)node->name, name) == 0) {
2004-01-09 18:22:03 +00:00
if (ns) {
2004-01-13 17:20:10 +00:00
xmlNsPtr nsPtr = attr_find_ns(node);
2004-01-29 06:37:51 +00:00
if (nsPtr) {
2006-07-11 14:24:18 +00:00
return (strcmp((char*)nsPtr->href, ns) == 0);
2004-01-29 06:37:51 +00:00
} else {
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
{
2006-07-11 14:24:18 +00:00
if (name == NULL || strcmp((char*)node->name, name) == 0) {
2004-01-09 18:22:03 +00:00
if (ns) {
2004-01-13 17:20:10 +00:00
xmlNsPtr nsPtr = node_find_ns(node);
2004-01-29 06:37:51 +00:00
if (nsPtr) {
2006-07-11 14:24:18 +00:00
return (strcmp((char*)nsPtr->href, ns) == 0);
2004-01-29 06:37:51 +00:00
} else {
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
2004-01-13 17:20:10 +00:00
xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns)
{
2004-01-13 17:20:10 +00:00
while (node!=NULL) {
if (attr_is_equal_ex(node, name, ns)) {
return node;
2004-01-09 18:22:03 +00:00
}
2004-01-13 17:20:10 +00:00
node = node->next;
}
return NULL;
}
xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns)
{
2004-01-13 17:20:10 +00:00
while (node!=NULL) {
if (node_is_equal_ex(node, name, ns)) {
return node;
2004-01-09 18:22:03 +00:00
}
2004-01-13 17:20:10 +00:00
node = node->next;
}
return NULL;
}
xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns)
{
2004-01-13 17:20:10 +00:00
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;
}
}
2004-01-13 17:20:10 +00:00
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;
2004-01-13 17:20:10 +00:00
while (node != NULL) {
2004-01-09 18:22:03 +00:00
if (name != NULL) {
2004-01-13 17:20:10 +00:00
node = get_node_ex(node, name, name_ns);
if (node==NULL) {
return NULL;
2004-01-09 18:22:03 +00:00
}
}
2004-01-13 17:20:10 +00:00
attr = get_attribute_ex(node->properties, attribute, attr_ns);
2006-07-11 14:24:18 +00:00
if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
2004-01-13 17:20:10 +00:00
return node;
}
2004-01-13 17:20:10 +00:00
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)
{
2004-01-13 17:20:10 +00:00
while (node != NULL) {
if (node_is_equal_ex(node, name, name_ns)) {
xmlAttrPtr attr = get_attribute_ex(node->properties, attribute, attr_ns);
2006-07-11 14:24:18 +00:00
if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
2004-01-13 17:20:10 +00:00
return node;
2004-01-09 18:22:03 +00:00
}
}
2004-01-13 17:20:10 +00:00
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;
}
}
2004-01-13 17:20:10 +00:00
node = node->next;
}
return NULL;
}
2006-07-11 14:24:18 +00:00
int parse_namespace(const xmlChar *inval, char **value, char **namespace)
{
2006-07-11 14:24:18 +00:00
char *found = strrchr((char*)inval, ':');
2006-07-11 14:24:18 +00:00
if (found != NULL && found != (char*)inval) {
(*namespace) = estrndup((char*)inval, found - (char*)inval);
(*value) = estrdup(++found);
2004-01-09 18:22:03 +00:00
} else {
2006-07-11 14:24:18 +00:00
(*value) = estrdup((char*)inval);
(*namespace) = NULL;
}
return FALSE;
}