From dfde0d4cef6e7b02648b124db81733ccd8414f11 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 11 May 2024 01:40:55 +0200 Subject: [PATCH] Handle dumping node to file --- .../common/namespace_sxe_interaction.phpt | 20 ++++++++++++++--- ext/dom/xml_document.c | 10 +++++++-- ext/libxml/libxml.c | 13 +++++++++++ ext/libxml/php_libxml.h | 1 + ext/simplexml/simplexml.c | 22 ++++++------------- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt b/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt index dfe01ba279b92..c25518616fca9 100644 --- a/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt +++ b/ext/dom/tests/modern/common/namespace_sxe_interaction.phpt @@ -24,6 +24,11 @@ var_dump($dom->documentElement->firstElementChild->firstElementChild->lookupName echo "=== serialize SimpleXML ===\n"; echo $sxe->saveXML(), "\n"; +echo $sxe->foo->saveXML(), "\n"; +$sxe->asXML(__DIR__ . "/namespace_sxe_interaction1.xml"); +$sxe->foo->asXML(__DIR__ . "/namespace_sxe_interaction2.xml"); +echo file_get_contents(__DIR__ . "/namespace_sxe_interaction1.xml"), "\n"; +echo file_get_contents(__DIR__ . "/namespace_sxe_interaction2.xml"), "\n"; echo "=== serialize DOM ===\n"; @@ -36,6 +41,11 @@ $new_dom = Dom\XMLDocument::createEmpty(); $new_dom->append($new_dom->importNode($dom->documentElement, true)); echo $new_dom->saveXML(), "\n"; +?> +--CLEAN-- + --EXPECT-- namespace c: string(5) "urn:c" @@ -43,11 +53,15 @@ namespace b: string(5) "urn:b" namespace a: NULL === serialize SimpleXML === -value +valuevalue2 +value2 + +valuevalue2 +value2 === serialize DOM === -value +valuevalue2 === serialize imported DOM === -value +valuevalue2 diff --git a/ext/dom/xml_document.c b/ext/dom/xml_document.c index 87b80b7365550..32eaa4b4cf92d 100644 --- a/ext/dom/xml_document.c +++ b/ext/dom/xml_document.c @@ -293,7 +293,7 @@ static zend_string *php_new_dom_dump_doc_to_str(xmlDocPtr doc, int options, cons return php_new_dom_dump_node_to_str(doc, (xmlNodePtr) doc, options & XML_SAVE_FORMAT, encoding); } -static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding) +zend_long php_new_dom_dump_node_to_file(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding) { xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler(encoding); xmlOutputBufferPtr out = xmlOutputBufferCreateFilename(filename, handler, 0); @@ -307,7 +307,7 @@ static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr do int status = -1; xmlSaveCtxtPtr ctxt = xmlSaveToIO(out->writecallback, NULL, stream, encoding, XML_SAVE_AS_XML); if (EXPECTED(ctxt != NULL)) { - status = dom_xml_serialize(ctxt, out, (xmlNodePtr) doc, format); + status = dom_xml_serialize(ctxt, out, node, format); status |= xmlOutputBufferFlush(out); (void) xmlSaveClose(ctxt); } @@ -319,9 +319,15 @@ static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr do return status < 0 ? status : (zend_long) offset; } +static zend_long php_new_dom_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding) +{ + return php_new_dom_dump_node_to_file(filename, doc, (xmlNodePtr) doc, format, encoding); +} + static const php_libxml_document_handlers php_new_dom_default_document_handlers = { .dump_node_to_str = php_new_dom_dump_node_to_str, .dump_doc_to_str = php_new_dom_dump_doc_to_str, + .dump_node_to_file = php_new_dom_dump_node_to_file, .dump_doc_to_file = php_new_dom_dump_doc_to_file, }; diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 6d052ff66ac07..858da6922c078 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -83,6 +83,7 @@ static zend_result php_libxml_post_deactivate(void); static zend_string *php_libxml_default_dump_node_to_str(xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding); static zend_string *php_libxml_default_dump_doc_to_str(xmlDocPtr doc, int options, const char *encoding); +static zend_long php_libxml_dump_node_to_file(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding); static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDocPtr doc, bool format, const char *encoding); /* }}} */ @@ -109,6 +110,7 @@ zend_module_entry libxml_module_entry = { static const php_libxml_document_handlers php_libxml_default_document_handlers = { .dump_node_to_str = php_libxml_default_dump_node_to_str, .dump_doc_to_str = php_libxml_default_dump_doc_to_str, + .dump_node_to_file = php_libxml_dump_node_to_file, .dump_doc_to_file = php_libxml_default_dump_doc_to_file, }; @@ -1540,6 +1542,17 @@ static zend_long php_libxml_default_dump_doc_to_file(const char *filename, xmlDo return xmlSaveFormatFileEnc(filename, doc, encoding, format); } +static zend_long php_libxml_dump_node_to_file(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding) +{ + xmlOutputBufferPtr outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0); + if (!outbuf) { + return -1; + } + + xmlNodeDumpOutput(outbuf, doc, node, 0, format, encoding); + return xmlOutputBufferClose(outbuf); +} + #if defined(PHP_WIN32) && defined(COMPILE_DL_LIBXML) PHP_LIBXML_API BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index e6b0a3a887882..4d799c39b165f 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -75,6 +75,7 @@ typedef struct _php_libxml_private_data_header { typedef struct php_libxml_document_handlers { zend_string *(*dump_node_to_str)(xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding); zend_string *(*dump_doc_to_str)(xmlDocPtr doc, int options, const char *encoding); + zend_long (*dump_node_to_file)(const char *filename, xmlDocPtr doc, xmlNodePtr node, bool format, const char *encoding); zend_long (*dump_doc_to_file)(const char *filename, xmlDocPtr doc, bool format, const char *encoding); } php_libxml_document_handlers; diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index b104784f5369c..3bc7964541e9f 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1342,7 +1342,6 @@ PHP_METHOD(SimpleXMLElement, asXML) { php_sxe_object *sxe; xmlNodePtr node; - xmlOutputBufferPtr outbuf; char *filename = NULL; size_t filename_len; @@ -1361,22 +1360,15 @@ PHP_METHOD(SimpleXMLElement, asXML) xmlDocPtr doc = sxe->document->ptr; if (filename) { + zend_long bytes; if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) { - zend_long bytes = sxe->document->handlers->dump_doc_to_file(filename, doc, false, (const char *) doc->encoding); - if (bytes == -1) { - RETURN_FALSE; - } else { - RETURN_TRUE; - } + bytes = sxe->document->handlers->dump_doc_to_file(filename, doc, false, (const char *) doc->encoding); + } else { + bytes = sxe->document->handlers->dump_node_to_file(filename, doc, node, false, NULL); + } + if (bytes == -1) { + RETURN_FALSE; } else { - outbuf = xmlOutputBufferCreateFilename(filename, NULL, 0); - - if (outbuf == NULL) { - RETURN_FALSE; - } - - xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, NULL); - xmlOutputBufferClose(outbuf); RETURN_TRUE; } }