Synch with HEAD

add readInnerXML, readOuterXML, readString, and setSchema functionality
  allow parser options to be passed when loading reader
  optimization: use xmlTextReader const functions for string properties
  add test
This commit is contained in:
Rob Richards 2006-05-10 12:04:46 +00:00
parent ac97b77ed9
commit aa38b5572e
4 changed files with 182 additions and 74 deletions

View file

@ -40,21 +40,23 @@ static HashTable xmlreader_prop_handlers;
typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader); typedef int (*xmlreader_read_int_t)(xmlTextReaderPtr reader);
typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader); typedef unsigned char *(*xmlreader_read_char_t)(xmlTextReaderPtr reader);
typedef const unsigned char *(*xmlreader_read_const_char_t)(xmlTextReaderPtr reader);
typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval TSRMLS_DC); typedef int (*xmlreader_write_t)(xmlreader_object *obj, zval *newval TSRMLS_DC);
typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, const unsigned char *); typedef unsigned char *(*xmlreader_read_one_char_t)(xmlTextReaderPtr reader, const unsigned char *);
typedef struct _xmlreader_prop_handler { typedef struct _xmlreader_prop_handler {
xmlreader_read_int_t read_int_func; xmlreader_read_int_t read_int_func;
xmlreader_read_char_t read_char_func; xmlreader_read_const_char_t read_char_func;
xmlreader_write_t write_func; xmlreader_write_t write_func;
int type; int type;
} xmlreader_prop_handler; } xmlreader_prop_handler;
#define XMLREADER_LOAD_STRING 0 #define XMLREADER_LOAD_STRING 0
#define XMLREADER_LOAD_FILE 1 #define XMLREADER_LOAD_FILE 1
/* {{{ xmlreader_register_prop_handler */ /* {{{ xmlreader_register_prop_handler */
static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name, xmlreader_read_int_t read_int_func, xmlreader_read_char_t read_char_func, int rettype TSRMLS_DC) static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name, xmlreader_read_int_t read_int_func, xmlreader_read_const_char_t read_char_func, int rettype TSRMLS_DC)
{ {
xmlreader_prop_handler hnd; xmlreader_prop_handler hnd;
@ -68,7 +70,7 @@ static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name,
/* {{{ xmlreader_property_reader */ /* {{{ xmlreader_property_reader */
static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC) static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handler *hnd, zval **retval TSRMLS_DC)
{ {
char *retchar = NULL; const xmlChar *retchar = NULL;
int retint = 0; int retint = 0;
if (obj->ptr != NULL) { if (obj->ptr != NULL) {
@ -90,8 +92,7 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl
switch (hnd->type) { switch (hnd->type) {
case IS_STRING: case IS_STRING:
if (retchar) { if (retchar) {
ZVAL_STRING(*retval, retchar, 1); ZVAL_STRING(*retval, (xmlChar *) retchar, 1);
xmlFree(retchar);
} else { } else {
ZVAL_EMPTY_STRING(*retval); ZVAL_EMPTY_STRING(*retval);
} }
@ -377,20 +378,8 @@ void xmlreader_objects_free_storage(void *object TSRMLS_DC)
{ {
xmlreader_object *intern = (xmlreader_object *)object; xmlreader_object *intern = (xmlreader_object *)object;
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
zend_object_std_dtor(&intern->std TSRMLS_CC); zend_object_std_dtor(&intern->std TSRMLS_CC);
#else
if (intern->std.guards) {
zend_hash_destroy(intern->std.guards);
FREE_HASHTABLE(intern->std.guards);
}
if (intern->std.properties) {
zend_hash_destroy(intern->std.properties);
FREE_HASHTABLE(intern->std.properties);
}
#endif
xmlreader_free_resources(intern); xmlreader_free_resources(intern);
efree(object); efree(object);
@ -405,21 +394,13 @@ zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC)
zval *tmp; zval *tmp;
intern = emalloc(sizeof(xmlreader_object)); intern = emalloc(sizeof(xmlreader_object));
memset(&intern->std, 0, sizeof(zend_object));
intern->ptr = NULL; intern->ptr = NULL;
intern->input = NULL; intern->input = NULL;
intern->schema = NULL; intern->schema = NULL;
intern->prop_handler = &xmlreader_prop_handlers; intern->prop_handler = &xmlreader_prop_handlers;
#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 1 && PHP_RELEASE_VERSION > 2) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5)
zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_object_std_init(&intern->std, class_type TSRMLS_CC);
#else
ALLOC_HASHTABLE(intern->std.properties);
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
intern->std.ce = class_type;
intern->std.guards = NULL;
#endif
zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) xmlreader_objects_free_storage, xmlreader_objects_clone TSRMLS_CC); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) xmlreader_objects_free_storage, xmlreader_objects_clone TSRMLS_CC);
intern->handle = retval.handle; intern->handle = retval.handle;
@ -481,7 +462,7 @@ static void php_xmlreader_no_arg(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_in
} }
/* }}} */ /* }}} */
/* This function not yet needed until some additional functions are implemented in libxml /* {{{ php_xmlreader_no_arg_string */
static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_char_t internal_function) { static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_read_char_t internal_function) {
zval *id; zval *id;
char *retchar = NULL; char *retchar = NULL;
@ -491,7 +472,7 @@ static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_
intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC); intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
if (intern && intern->ptr) { if (intern && intern->ptr) {
retchar = xmlTextReaderReadString(intern->ptr); retchar = internal_function(intern->ptr);
} }
if (retchar) { if (retchar) {
RETVAL_STRING(retchar, 1); RETVAL_STRING(retchar, 1);
@ -501,7 +482,7 @@ static void php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAMETERS, xmlreader_
RETVAL_EMPTY_STRING(); RETVAL_EMPTY_STRING();
} }
} }
*/ /* }}} */
/* {{{ php_xmlreader_set_relaxng_schema */ /* {{{ php_xmlreader_set_relaxng_schema */
static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int type) { static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int type) {
@ -876,18 +857,20 @@ PHP_METHOD(xmlreader, next)
} }
/* }}} */ /* }}} */
/* {{{ proto boolean XMLReader::open(string URI) /* {{{ proto boolean XMLReader::open(string URI [, string encoding [, int options]])
Sets the URI that the the XMLReader will parse. */ Sets the URI that the the XMLReader will parse. */
PHP_METHOD(xmlreader, open) PHP_METHOD(xmlreader, open)
{ {
zval *id; zval *id;
int source_len = 0; int source_len = 0, encoding_len = 0;
long options = 0;
xmlreader_object *intern = NULL; xmlreader_object *intern = NULL;
char *source, *valid_file = NULL; char *source, *valid_file = NULL;
char *encoding = NULL;
char resolved_path[MAXPATHLEN + 1]; char resolved_path[MAXPATHLEN + 1];
xmlTextReaderPtr reader = NULL; xmlTextReaderPtr reader = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
return; return;
} }
@ -909,7 +892,7 @@ PHP_METHOD(xmlreader, open)
valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC); valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
if (valid_file) { if (valid_file) {
reader = xmlNewTextReaderFilename(valid_file); reader = xmlReaderForFile(valid_file, encoding, options);
} }
if (reader == NULL) { if (reader == NULL) {
@ -932,34 +915,87 @@ PHP_METHOD(xmlreader, open)
/* }}} */ /* }}} */
/* Not Yet Implemented in libxml - functions exist just not coded /* Not Yet Implemented in libxml - functions exist just not coded
PHP_METHOD(xmlreader, readInnerXml)
{
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
}
PHP_METHOD(xmlreader, readOuterXml)
{
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
}
PHP_METHOD(xmlreader, readString)
{
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
}
PHP_METHOD(xmlreader, resetState) PHP_METHOD(xmlreader, resetState)
{ {
} }
*/ */
#if LIBXML_VERSION >= 20620
/* {{{ proto boolean XMLReader::readInnerXml()
Reads the contents of the current node, including child nodes and markup. */
PHP_METHOD(xmlreader, readInnerXml)
{
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadInnerXml);
}
/* }}} */
/* {{{ proto boolean XMLReader::readOuterXml()
Reads the contents of the current node, including child nodes and markup. */
PHP_METHOD(xmlreader, readOuterXml)
{
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadOuterXml);
}
/* }}} */
/* {{{ proto boolean XMLReader::readString()
Reads the contents of an element or a text node as a string. */
PHP_METHOD(xmlreader, readString)
{
php_xmlreader_no_arg_string(INTERNAL_FUNCTION_PARAM_PASSTHRU, xmlTextReaderReadString);
}
/* }}} */
/* {{{ proto boolean XMLReader::setSchema(string filename)
Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
PHP_METHOD(xmlreader, setSchema)
{
#ifdef LIBXML_SCHEMAS_ENABLED
zval *id;
int source_len = 0, retval = -1;
xmlreader_object *intern;
char *source;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!", &source, &source_len) == FAILURE) {
return;
}
if (source != NULL && !source_len) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Schema data source is required");
RETURN_FALSE;
}
id = getThis();
intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
if (intern && intern->ptr) {
retval = xmlTextReaderSchemaValidate(intern->ptr, source);
if (retval == 0) {
RETURN_TRUE;
}
}
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
RETURN_FALSE;
#else
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No Schema support built into libxml.");
RETURN_FALSE;
#endif
}
/* }}} */
#endif
/* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value) /* {{{ proto boolean XMLReader::setParserProperty(int property, boolean value)
Sets parser property (one of the parser option constants). Sets parser property (one of the parser option constants).
Properties must be set after open() or XML() and before the first read() is called */ Properties must be set after open() or XML() and before the first read() is called */
PHP_METHOD(xmlreader, setParserProperty) PHP_METHOD(xmlreader, setParserProperty)
{ {
zval *id; zval *id;
int property, retval = -1; long property;
int retval = -1;
zend_bool value; zend_bool value;
xmlreader_object *intern; xmlreader_object *intern;
@ -982,7 +1018,7 @@ PHP_METHOD(xmlreader, setParserProperty)
} }
/* }}} */ /* }}} */
/* {{{ proto boolean XMLReader::setRelaxNGSchemaSource(string filename) /* {{{ proto boolean XMLReader::setRelaxNGSchema(string filename)
Sets the string that the the XMLReader will parse. */ Sets the string that the the XMLReader will parse. */
PHP_METHOD(xmlreader, setRelaxNGSchema) PHP_METHOD(xmlreader, setRelaxNGSchema)
{ {
@ -998,20 +1034,27 @@ PHP_METHOD(xmlreader, setRelaxNGSchemaSource)
} }
/* }}} */ /* }}} */
/* {{{ proto boolean XMLReader::XML(string source) /* TODO
XMLPUBFUN int XMLCALL
xmlTextReaderSetSchema (xmlTextReaderPtr reader,
xmlSchemaPtr schema);
*/
/* {{{ proto boolean XMLReader::XML(string source [, string encoding [, int options]])
Sets the string that the the XMLReader will parse. */ Sets the string that the the XMLReader will parse. */
PHP_METHOD(xmlreader, XML) PHP_METHOD(xmlreader, XML)
{ {
zval *id; zval *id;
int source_len = 0; int source_len = 0, encoding_len = 0;
long options = 0;
xmlreader_object *intern = NULL; xmlreader_object *intern = NULL;
char *source, *uri = NULL; char *source, *uri = NULL, *encoding = NULL;
int resolved_path_len; int resolved_path_len;
char *directory=NULL, resolved_path[MAXPATHLEN]; char *directory=NULL, resolved_path[MAXPATHLEN];
xmlParserInputBufferPtr inputbfr; xmlParserInputBufferPtr inputbfr;
xmlTextReaderPtr reader; xmlTextReaderPtr reader;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!l", &source, &source_len, &encoding, &encoding_len, &options) == FAILURE) {
return; return;
} }
@ -1054,15 +1097,12 @@ PHP_METHOD(xmlreader, XML)
if (id == NULL) { if (id == NULL) {
object_init_ex(return_value, xmlreader_class_entry); object_init_ex(return_value, xmlreader_class_entry);
intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC); intern = (xmlreader_object *)zend_objects_get_address(return_value TSRMLS_CC);
intern->input = inputbfr;
intern->ptr = reader;
return;
} else { } else {
intern->input = inputbfr; RETVAL_TRUE;
intern->ptr = reader;
RETURN_TRUE;
} }
intern->input = inputbfr;
intern->ptr = reader;
return;
} }
} }
@ -1095,7 +1135,12 @@ PHP_METHOD(xmlreader, expand)
RETURN_FALSE; RETURN_FALSE;
} else { } else {
nodec = xmlCopyNode(node, 1); nodec = xmlCopyNode(node, 1);
DOM_RET_OBJ(rv, nodec, &ret, NULL); if (nodec == NULL) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot expand this node type");
RETURN_FALSE;
} else {
DOM_RET_OBJ(rv, nodec, &ret, NULL);
}
} }
} else { } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to expand"); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to expand");
@ -1125,10 +1170,13 @@ static zend_function_entry xmlreader_functions[] = {
PHP_ME(xmlreader, open, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) PHP_ME(xmlreader, open, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
PHP_ME(xmlreader, read, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, read, NULL, ZEND_ACC_PUBLIC)
PHP_ME(xmlreader, next, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, next, NULL, ZEND_ACC_PUBLIC)
/* Not Yet Implemented though defined in libxml as of 2.6.9dev #if LIBXML_VERSION >= 20620
PHP_ME(xmlreader, readInnerXml, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, readInnerXml, NULL, ZEND_ACC_PUBLIC)
PHP_ME(xmlreader, readOuterXml, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, readOuterXml, NULL, ZEND_ACC_PUBLIC)
PHP_ME(xmlreader, readString, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, readString, NULL, ZEND_ACC_PUBLIC)
PHP_ME(xmlreader, setSchema, NULL, ZEND_ACC_PUBLIC)
#endif
/* Not Yet Implemented though defined in libxml as of 2.6.9dev
PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, resetState, NULL, ZEND_ACC_PUBLIC)
*/ */
PHP_ME(xmlreader, setParserProperty, NULL, ZEND_ACC_PUBLIC) PHP_ME(xmlreader, setParserProperty, NULL, ZEND_ACC_PUBLIC)
@ -1157,19 +1205,19 @@ PHP_MINIT_FUNCTION(xmlreader)
zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1); zend_hash_init(&xmlreader_prop_handlers, 0, NULL, NULL, 1);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "attributeCount", xmlTextReaderAttributeCount, NULL, IS_LONG TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderBaseUri, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "baseURI", NULL, xmlTextReaderConstBaseUri, IS_STRING TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "depth", xmlTextReaderDepth, NULL, IS_LONG TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasAttributes", xmlTextReaderHasAttributes, NULL, IS_BOOL TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "hasValue", xmlTextReaderHasValue, NULL, IS_BOOL TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isDefault", xmlTextReaderIsDefault, NULL, IS_BOOL TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "isEmptyElement", xmlTextReaderIsEmptyElement, NULL, IS_BOOL TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderLocalName, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "localName", NULL, xmlTextReaderConstLocalName, IS_STRING TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderName, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "name", NULL, xmlTextReaderConstName, IS_STRING TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderNamespaceUri, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "namespaceURI", NULL, xmlTextReaderConstNamespaceUri, IS_STRING TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "nodeType", xmlTextReaderNodeType, NULL, IS_LONG TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderPrefix, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "prefix", NULL, xmlTextReaderConstPrefix, IS_STRING TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderValue, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "value", NULL, xmlTextReaderConstValue, IS_STRING TSRMLS_CC);
xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderXmlLang, IS_STRING TSRMLS_CC); xmlreader_register_prop_handler(&xmlreader_prop_handlers, "xmlLang", NULL, xmlTextReaderConstXmlLang, IS_STRING TSRMLS_CC);
/* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */ /* Constants for NodeType - cannot define common types to share with dom as there are differences in these types */

View file

@ -40,9 +40,7 @@ extern zend_module_entry xmlreader_module_entry;
typedef struct _xmlreader_object { typedef struct _xmlreader_object {
zend_object std; zend_object std;
xmlTextReaderPtr ptr; xmlTextReaderPtr ptr;
/* input is used to allow strings to be loaded under libxml 2.5.x /* strings must be set in input buffer as copy is required */
must manually allocate and de-allocate these - can be refactored when
libxml 2.6.x becomes minimum version */
xmlParserInputBufferPtr input; xmlParserInputBufferPtr input;
void *schema; void *schema;
HashTable *prop_handler; HashTable *prop_handler;

52
ext/xmlreader/tests/013.phpt Executable file
View file

@ -0,0 +1,52 @@
--TEST--
XMLReader: Schema validation
--SKIPIF--
<?php if (!extension_loaded('xmlreader')) die('skip');?>
<?php if (!method_exists('XMLReader','setSchema')) die('skip XMLReader::setSchema() not supported');?>
--FILE--
<?php
/* $Id$ */
$xml =<<<EOF
<?xml version="1.0" encoding="UTF-8" ?>
<items>
<item>123</item>
<item>456</item>
</items>
EOF;
$reader = new XMLReader();
$reader->XML($xml);
$reader->setSchema(dirname(__FILE__) . '/013.xsd');
while($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'item') {
$reader->read();
var_dump($reader->value);
}
}
$reader->close();
?>
===FAIL===
<?php
$xml =<<<EOF
<?xml version="1.0" encoding="UTF-8" ?>
<foo/>
EOF;
$reader = new XMLReader();
$reader->XML($xml);
$reader->setSchema(dirname(__FILE__) . '/013.xsd');
while($reader->read() && $reader->nodeType != XMLReader::ELEMENT);
$reader->close();
?>
===DONE===
--EXPECTF--
string(3) "123"
string(3) "456"
===FAIL===
Warning: XMLReader::read(): Element 'foo': %s
===DONE===

10
ext/xmlreader/tests/013.xsd Executable file
View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="items">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="item" type="xsd:integer" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>