@@ -1478,17 +1478,28 @@ static void dom_libxml_reconcile_ensure_namespaces_are_declared(xmlNodePtr nodep
1478
1478
xmlDOMWrapReconcileNamespaces (& dummy_ctxt , nodep , /* options */ 0 );
1479
1479
}
1480
1480
1481
- static void dom_check_default_namespace (xmlDocPtr doc , xmlNodePtr nodep )
1481
+ static bool dom_must_replace_namespace_by_empty_default (xmlDocPtr doc , xmlNodePtr nodep )
1482
+ {
1483
+ xmlNsPtr default_ns = xmlSearchNs (doc , nodep -> parent , NULL );
1484
+ return default_ns != NULL && default_ns -> href != NULL && default_ns -> href [0 ] != '\0' ;
1485
+ }
1486
+
1487
+ static void dom_replace_namespace_by_empty_default (xmlDocPtr doc , xmlNodePtr nodep )
1482
1488
{
1483
1489
if (nodep -> ns == NULL ) {
1484
- xmlNsPtr default_ns = xmlSearchNs (doc , nodep -> parent , NULL );
1485
- if (default_ns != NULL && default_ns -> href != NULL && default_ns -> href [0 ] != '\0' ) {
1486
- /* The node uses the default empty namespace, but the current default namespace is non-empty.
1487
- * We can't unconditionally do this because otherwise libxml2 creates an xmlns="" declaration.
1488
- * Note: there's no point searching the oldNs list, because we haven't found it in the tree anyway.
1489
- * Ideally this would be pre-allocated but unfortunately libxml2 doesn't offer such a functionality. */
1490
- xmlSetNs (nodep , xmlNewNs (nodep , (const xmlChar * ) "" , NULL ));
1491
- }
1490
+ /* The node uses the default empty namespace, but the current default namespace is non-empty.
1491
+ * We can't unconditionally do this because otherwise libxml2 creates an xmlns="" declaration.
1492
+ * Note: there's no point searching the oldNs list, because we haven't found it in the tree anyway.
1493
+ * Ideally this would be pre-allocated but unfortunately libxml2 doesn't offer such a functionality. */
1494
+ xmlSetNs (nodep , xmlNewNs (nodep , (const xmlChar * ) "" , NULL ));
1495
+ }
1496
+ }
1497
+
1498
+ static void dom_check_default_namespace (xmlDocPtr doc , xmlNodePtr nodep )
1499
+ {
1500
+ /* Check nodep->ns first to avoid an expensive lookup. */
1501
+ if (nodep -> ns == NULL && dom_must_replace_namespace_by_empty_default (doc , nodep )) {
1502
+ dom_replace_namespace_by_empty_default (doc , nodep );
1492
1503
}
1493
1504
}
1494
1505
@@ -1498,8 +1509,8 @@ void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
1498
1509
* we still want to do the internal reconciliation conditionally. */
1499
1510
if (nodep -> type == XML_ELEMENT_NODE ) {
1500
1511
dom_reconcile_ns_internal (doc , nodep , nodep -> parent );
1501
- dom_check_default_namespace (doc , nodep );
1502
1512
dom_libxml_reconcile_ensure_namespaces_are_declared (nodep );
1513
+ dom_check_default_namespace (doc , nodep );
1503
1514
}
1504
1515
}
1505
1516
/* }}} */
@@ -1523,13 +1534,18 @@ static void dom_reconcile_ns_list_internal(xmlDocPtr doc, xmlNodePtr nodep, xmlN
1523
1534
1524
1535
void dom_reconcile_ns_list (xmlDocPtr doc , xmlNodePtr nodep , xmlNodePtr last )
1525
1536
{
1537
+ bool must_replace_namespace_by_empty_default = dom_must_replace_namespace_by_empty_default (doc , nodep );
1526
1538
dom_reconcile_ns_list_internal (doc , nodep , last , nodep -> parent );
1527
- dom_check_default_namespace (doc , nodep );
1528
1539
/* The loop is outside of the recursion in the above call because
1529
1540
* dom_libxml_reconcile_ensure_namespaces_are_declared() performs its own recursion. */
1530
1541
while (true) {
1531
1542
/* The internal libxml2 call will already check the node type, no need for us to do it here. */
1532
1543
dom_libxml_reconcile_ensure_namespaces_are_declared (nodep );
1544
+ /* We don't have to handle the children, because if their ns's are NULL they'll just take on the default
1545
+ * which should've been reconciled before. */
1546
+ if (must_replace_namespace_by_empty_default ) {
1547
+ dom_replace_namespace_by_empty_default (doc , nodep );
1548
+ }
1533
1549
if (nodep == last ) {
1534
1550
break ;
1535
1551
}
0 commit comments