2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 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 +----------------------------------------------------------------------+
23 #include "ext/libxml/php_libxml.h"
24 #include "libxml/parser.h"
25 #include "libxml/parserInternals.h"
27 /* Channel libxml file io layer through the PHP streams subsystem.
28 * This allows use of ftps:// and https:// urls */
30 static int is_blank(const xmlChar
* str
)
32 while (*str
!= '\0') {
33 if (*str
!= ' ' && *str
!= 0x9 && *str
!= 0xa && *str
!= 0xd) {
41 /* removes all empty text, comments and other insignoficant nodes */
42 static void cleanup_xml_node(xmlNodePtr node
)
45 xmlNodePtr del
= NULL
;
47 trav
= node
->children
;
48 while (trav
!= NULL
) {
54 if (trav
->type
== XML_TEXT_NODE
) {
55 if (is_blank(trav
->content
)) {
58 } else if ((trav
->type
!= XML_ELEMENT_NODE
) &&
59 (trav
->type
!= XML_CDATA_SECTION_NODE
)) {
61 } else if (trav
->children
!= NULL
) {
62 cleanup_xml_node(trav
);
72 static void soap_ignorableWhitespace(void *ctx
, const xmlChar
*ch
, int len
)
76 static void soap_Comment(void *ctx
, const xmlChar
*value
)
80 xmlDocPtr
soap_xmlParseFile(const char *filename TSRMLS_DC
)
82 xmlParserCtxtPtr ctxt
= NULL
;
84 zend_bool old_allow_url_fopen
;
90 old_allow_url_fopen
= PG(allow_url_fopen
);
91 PG(allow_url_fopen
) = 1;
92 ctxt
= xmlCreateFileParserCtxt(filename
);
93 PG(allow_url_fopen
) = old_allow_url_fopen
;
98 ctxt
->sax
->ignorableWhitespace
= soap_ignorableWhitespace
;
99 ctxt
->sax
->comment
= soap_Comment
;
100 ctxt
->sax
->warning
= NULL
;
101 ctxt
->sax
->error
= NULL
;
102 /*ctxt->sax->fatalError = NULL;*/
103 old
= php_libxml_disable_entity_loader(1 TSRMLS_CC
);
104 xmlParseDocument(ctxt
);
105 php_libxml_disable_entity_loader(old TSRMLS_CC
);
106 if (ctxt
->wellFormed
) {
108 if (ret
->URL
== NULL
&& ctxt
->directory
!= NULL
) {
109 ret
->URL
= xmlCharStrdup(ctxt
->directory
);
113 xmlFreeDoc(ctxt
->myDoc
);
116 xmlFreeParserCtxt(ctxt
);
126 cleanup_xml_node((xmlNodePtr
)ret
);
131 xmlDocPtr
soap_xmlParseMemory(const void *buf
, size_t buf_size
)
133 xmlParserCtxtPtr ctxt
= NULL
;
141 ctxt
= xmlCreateMemoryParserCtxt(buf
, buf_size
);
145 ctxt
->sax
->ignorableWhitespace
= soap_ignorableWhitespace
;
146 ctxt
->sax
->comment
= soap_Comment
;
147 ctxt
->sax
->warning
= NULL
;
148 ctxt
->sax
->error
= NULL
;
149 /*ctxt->sax->fatalError = NULL;*/
150 #if LIBXML_VERSION >= 20703
151 ctxt
->options
|= XML_PARSE_HUGE
;
153 old
= php_libxml_disable_entity_loader(1 TSRMLS_CC
);
154 xmlParseDocument(ctxt
);
155 php_libxml_disable_entity_loader(old TSRMLS_CC
);
156 if (ctxt
->wellFormed
) {
158 if (ret
->URL
== NULL
&& ctxt
->directory
!= NULL
) {
159 ret
->URL
= xmlCharStrdup(ctxt
->directory
);
163 xmlFreeDoc(ctxt
->myDoc
);
166 xmlFreeParserCtxt(ctxt
);
177 cleanup_xml_node((xmlNodePtr)ret);
183 xmlNsPtr
attr_find_ns(xmlAttrPtr node
)
187 } else if (node
->parent
->ns
) {
188 return node
->parent
->ns
;
190 return xmlSearchNs(node
->doc
, node
->parent
, NULL
);
194 xmlNsPtr
node_find_ns(xmlNodePtr node
)
199 return xmlSearchNs(node
->doc
, node
, NULL
);
203 int attr_is_equal_ex(xmlAttrPtr node
, char *name
, char *ns
)
205 if (name
== NULL
|| strcmp((char*)node
->name
, name
) == 0) {
207 xmlNsPtr nsPtr
= attr_find_ns(node
);
209 return (strcmp((char*)nsPtr
->href
, ns
) == 0);
219 int node_is_equal_ex(xmlNodePtr node
, char *name
, char *ns
)
221 if (name
== NULL
|| strcmp((char*)node
->name
, name
) == 0) {
223 xmlNsPtr nsPtr
= node_find_ns(node
);
225 return (strcmp((char*)nsPtr
->href
, ns
) == 0);
236 xmlAttrPtr
get_attribute_ex(xmlAttrPtr node
, char *name
, char *ns
)
239 if (attr_is_equal_ex(node
, name
, ns
)) {
247 xmlNodePtr
get_node_ex(xmlNodePtr node
, char *name
, char *ns
)
250 if (node_is_equal_ex(node
, name
, ns
)) {
258 xmlNodePtr
get_node_recurisve_ex(xmlNodePtr node
, char *name
, char *ns
)
260 while (node
!= NULL
) {
261 if (node_is_equal_ex(node
, name
, ns
)) {
263 } else if (node
->children
!= NULL
) {
264 xmlNodePtr tmp
= get_node_recurisve_ex(node
->children
, name
, ns
);
274 xmlNodePtr
get_node_with_attribute_ex(xmlNodePtr node
, char *name
, char *name_ns
, char *attribute
, char *value
, char *attr_ns
)
278 while (node
!= NULL
) {
280 node
= get_node_ex(node
, name
, name_ns
);
286 attr
= get_attribute_ex(node
->properties
, attribute
, attr_ns
);
287 if (attr
!= NULL
&& strcmp((char*)attr
->children
->content
, value
) == 0) {
295 xmlNodePtr
get_node_with_attribute_recursive_ex(xmlNodePtr node
, char *name
, char *name_ns
, char *attribute
, char *value
, char *attr_ns
)
297 while (node
!= NULL
) {
298 if (node_is_equal_ex(node
, name
, name_ns
)) {
299 xmlAttrPtr attr
= get_attribute_ex(node
->properties
, attribute
, attr_ns
);
300 if (attr
!= NULL
&& strcmp((char*)attr
->children
->content
, value
) == 0) {
304 if (node
->children
!= NULL
) {
305 xmlNodePtr tmp
= get_node_with_attribute_recursive_ex(node
->children
, name
, name_ns
, attribute
, value
, attr_ns
);
315 int parse_namespace(const xmlChar
*inval
, char **value
, char **namespace)
317 char *found
= strrchr((char*)inval
, ':');
319 if (found
!= NULL
&& found
!= (char*)inval
) {
320 (*namespace) = estrndup((char*)inval
, found
- (char*)inval
);
321 (*value
) = estrdup(++found
);
323 (*value
) = estrdup((char*)inval
);