diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 36602eb2f40..483585990a0 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -833,6 +833,53 @@ HRESULT node_get_xml(xmlnode *This, BOOL ensure_eol, BSTR *ret)
return *ret ? S_OK : E_OUTOFMEMORY;
}
+static void htmldtd_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc)
+{
+ xmlDtdPtr cur = doc->intSubset;
+
+ xmlOutputBufferWriteString(buf, "name);
+ if (cur->ExternalID)
+ {
+ xmlOutputBufferWriteString(buf, " PUBLIC ");
+ xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID);
+ if (cur->SystemID)
+ {
+ xmlOutputBufferWriteString(buf, " ");
+ xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
+ }
+ }
+ else if (cur->SystemID)
+ {
+ xmlOutputBufferWriteString(buf, " SYSTEM ");
+ xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
+ }
+ xmlOutputBufferWriteString(buf, ">\n");
+}
+
+static void htmldoc_dumpcontent(xmlOutputBufferPtr buf, xmlDocPtr doc)
+{
+ xmlElementType type;
+
+ /* force HTML output */
+ type = doc->type;
+ doc->type = XML_HTML_DOCUMENT_NODE;
+ if (doc->intSubset)
+ htmldtd_dumpcontent(buf, doc);
+ if (doc->children)
+ {
+ xmlNodePtr cur = doc->children;
+
+ while (cur)
+ {
+ htmlNodeDumpFormatOutput(buf, doc, cur, NULL, 1);
+ cur = cur->next;
+ }
+
+ }
+ doc->type = type;
+}
+
HRESULT node_transform_node(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *p)
{
#ifdef SONAME_LIBXSLT
@@ -860,7 +907,7 @@ HRESULT node_transform_node(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *
xmlOutputBufferPtr output = xmlAllocOutputBuffer(NULL);
if (output)
{
- htmlDocContentDumpOutput(output, result->doc, NULL);
+ htmldoc_dumpcontent(output, result->doc);
content = xmlBufferContent(output->buffer);
*p = bstr_from_xmlChar(content);
xmlOutputBufferClose(output);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index f59a001867b..85d2bc4c54d 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -9732,8 +9732,7 @@ todo_wine {
hr = IXSLProcessor_get_output(processor, &v);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(V_VT(&v) == VT_BSTR, "got type %d\n", V_VT(&v));
- /* we currently output one '\n' instead of empty string */
- todo_wine ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
+ ok(lstrcmpW(V_BSTR(&v), _bstr_("")) == 0, "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
IXMLDOMDocument_Release(doc2);
VariantClear(&v);
@@ -12469,6 +12468,47 @@ static void test_namedmap_newenum(void)
IXMLDOMDocument_Release(doc);
}
+static const char xsltext_xsl[] =
+""
+""
+""
+""
+" "
+" "
+" testdata"
+" "
+" "
+""
+"";
+
+static void test_xsltext(void)
+{
+ IXMLDOMDocument *doc, *doc2;
+ VARIANT_BOOL b;
+ HRESULT hr;
+ BSTR ret;
+
+ doc = create_document(&IID_IXMLDOMDocument);
+ if (!doc) return;
+
+ doc2 = create_document(&IID_IXMLDOMDocument);
+
+ hr = IXMLDOMDocument_loadXML(doc, _bstr_(xsltext_xsl), &b);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IXMLDOMDocument_loadXML(doc2, _bstr_(""), &b);
+ EXPECT_HR(hr, S_OK);
+
+ hr = IXMLDOMDocument_transformNode(doc2, (IXMLDOMNode*)doc, &ret);
+ EXPECT_HR(hr, S_OK);
+ ok(!lstrcmpW(ret, _bstr_("testdata")), "transform result %s\n", wine_dbgstr_w(ret));
+ SysFreeString(ret);
+
+ IXMLDOMDocument_Release(doc2);
+ IXMLDOMDocument_Release(doc);
+ free_bstrs();
+}
+
START_TEST(domdoc)
{
IXMLDOMDocument *doc;
@@ -12552,6 +12592,7 @@ START_TEST(domdoc)
test_namedmap_newenum();
test_xsltemplate();
+ test_xsltext();
hr = CoCreateInstance(&CLSID_MXNamespaceManager40, NULL, CLSCTX_INPROC_SERVER,
&IID_IMXNamespaceManager, (void**)&unk);