Skip to content

Commit

Permalink
Handle dumping node to file
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsdos committed May 11, 2024
1 parent 0c490ad commit dfde0d4
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 20 deletions.
20 changes: 17 additions & 3 deletions ext/dom/tests/modern/common/namespace_sxe_interaction.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -36,18 +41,27 @@ $new_dom = Dom\XMLDocument::createEmpty();
$new_dom->append($new_dom->importNode($dom->documentElement, true));
echo $new_dom->saveXML(), "\n";

?>
--CLEAN--
<?php
@unlink(__DIR__ . "/namespace_sxe_interaction1.xml");
@unlink(__DIR__ . "/namespace_sxe_interaction2.xml");
?>
--EXPECT--
namespace c: string(5) "urn:c"
namespace b: string(5) "urn:b"
namespace a: NULL
=== serialize SimpleXML ===
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child></root>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child><foo>value2</foo></root>
<foo>value2</foo>
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child><foo>value2</foo></root>
<foo>value2</foo>
=== serialize DOM ===
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child></root>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child><foo>value2</foo></root>

=== serialize imported DOM ===
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child></root>
<root xmlns:a="urn:a" a:attr="value"><b:child xmlns:b="urn:b">value<c:child xmlns:c="urn:c"/></b:child><foo>value2</foo></root>
10 changes: 8 additions & 2 deletions ext/dom/xml_document.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand All @@ -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,
};

Expand Down
13 changes: 13 additions & 0 deletions ext/libxml/libxml.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/* }}} */
Expand All @@ -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,
};

Expand Down Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions ext/libxml/php_libxml.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
22 changes: 7 additions & 15 deletions ext/simplexml/simplexml.c
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,6 @@ PHP_METHOD(SimpleXMLElement, asXML)
{
php_sxe_object *sxe;
xmlNodePtr node;
xmlOutputBufferPtr outbuf;
char *filename = NULL;
size_t filename_len;

Expand All @@ -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;
}
}
Expand Down

0 comments on commit dfde0d4

Please sign in to comment.