@@ -1416,18 +1416,23 @@ PHP_METHOD(SimpleXMLElement, asXML)
1416
1416
1417
1417
#define SXE_NS_PREFIX (ns ) (ns->prefix ? (char*)ns->prefix : "")
1418
1418
1419
- static inline void sxe_add_namespace_name (zval * return_value , xmlNsPtr ns ) /* {{{ */
1419
+ static inline void sxe_add_namespace_name_raw (zval * return_value , const char * prefix , const char * href )
1420
1420
{
1421
- char * prefix = SXE_NS_PREFIX (ns );
1422
1421
zend_string * key = zend_string_init (prefix , strlen (prefix ), 0 );
1423
1422
zval zv ;
1424
1423
1425
1424
if (!zend_hash_exists (Z_ARRVAL_P (return_value ), key )) {
1426
- ZVAL_STRING (& zv , ( char * ) ns -> href );
1425
+ ZVAL_STRING (& zv , href );
1427
1426
zend_hash_add_new (Z_ARRVAL_P (return_value ), key , & zv );
1428
1427
}
1429
1428
zend_string_release_ex (key , 0 );
1430
1429
}
1430
+
1431
+ static inline void sxe_add_namespace_name (zval * return_value , xmlNsPtr ns ) /* {{{ */
1432
+ {
1433
+ char * prefix = SXE_NS_PREFIX (ns );
1434
+ sxe_add_namespace_name_raw (return_value , prefix , (const char * ) ns -> href );
1435
+ }
1431
1436
/* }}} */
1432
1437
1433
1438
static void sxe_add_namespaces (php_sxe_object * sxe , xmlNodePtr node , bool recursive , zval * return_value ) /* {{{ */
@@ -1484,7 +1489,7 @@ PHP_METHOD(SimpleXMLElement, getNamespaces)
1484
1489
}
1485
1490
/* }}} */
1486
1491
1487
- static void sxe_add_registered_namespaces (php_sxe_object * sxe , xmlNodePtr node , bool recursive , zval * return_value ) /* {{{ */
1492
+ static void sxe_add_registered_namespaces (php_sxe_object * sxe , xmlNodePtr node , bool recursive , bool include_xmlns_attributes , zval * return_value ) /* {{{ */
1488
1493
{
1489
1494
xmlNsPtr ns ;
1490
1495
@@ -1494,10 +1499,24 @@ static void sxe_add_registered_namespaces(php_sxe_object *sxe, xmlNodePtr node,
1494
1499
sxe_add_namespace_name (return_value , ns );
1495
1500
ns = ns -> next ;
1496
1501
}
1502
+ if (include_xmlns_attributes ) {
1503
+ for (const xmlAttr * attr = node -> properties ; attr ; attr = attr -> next ) {
1504
+ /* Attributes in the xmlns namespace should be treated as namespace declarations too. */
1505
+ if (attr -> ns && xmlStrEqual (attr -> ns -> href , (const xmlChar * ) "http://www.w3.org/2000/xmlns/" )) {
1506
+ const char * prefix = attr -> ns -> prefix ? (const char * ) attr -> name : "" ;
1507
+ bool free ;
1508
+ xmlChar * href = php_libxml_attr_value (attr , & free );
1509
+ sxe_add_namespace_name_raw (return_value , prefix , (const char * ) href );
1510
+ if (free ) {
1511
+ xmlFree (href );
1512
+ }
1513
+ }
1514
+ }
1515
+ }
1497
1516
if (recursive ) {
1498
1517
node = node -> children ;
1499
1518
while (node ) {
1500
- sxe_add_registered_namespaces (sxe , node , recursive , return_value );
1519
+ sxe_add_registered_namespaces (sxe , node , recursive , include_xmlns_attributes , return_value );
1501
1520
node = node -> next ;
1502
1521
}
1503
1522
}
@@ -1532,8 +1551,11 @@ PHP_METHOD(SimpleXMLElement, getDocNamespaces)
1532
1551
RETURN_FALSE ;
1533
1552
}
1534
1553
1554
+ /* Only do this for modern documents to keep BC. */
1555
+ bool include_xmlns_attributes = sxe -> document -> class_type == PHP_LIBXML_CLASS_MODERN ;
1556
+
1535
1557
array_init (return_value );
1536
- sxe_add_registered_namespaces (sxe , node , recursive , return_value );
1558
+ sxe_add_registered_namespaces (sxe , node , recursive , include_xmlns_attributes , return_value );
1537
1559
}
1538
1560
/* }}} */
1539
1561
0 commit comments