diff --git a/dlls/msxml3/stylesheet.c b/dlls/msxml3/stylesheet.c index b1f79721f7a..df29fc2b4ea 100644 --- a/dlls/msxml3/stylesheet.c +++ b/dlls/msxml3/stylesheet.c @@ -50,11 +50,12 @@ typedef struct _xslprocessor IXSLProcessor IXSLProcessor_iface; LONG ref; + xsltemplate *stylesheet; IXMLDOMNode *input; IStream *output; } xslprocessor; -static HRESULT XSLProcessor_create(IXSLProcessor**); +static HRESULT XSLProcessor_create(xsltemplate*, IXSLProcessor**); static inline xsltemplate *impl_from_IXSLTemplate( IXSLTemplate *iface ) { @@ -226,7 +227,7 @@ static HRESULT WINAPI xsltemplate_createProcessor( IXSLTemplate *iface, if (!processor) return E_INVALIDARG; - return XSLProcessor_create(processor); + return XSLProcessor_create(This, processor); } static const struct IXSLTemplateVtbl xsltemplate_vtbl = @@ -308,6 +309,7 @@ static ULONG WINAPI xslprocessor_Release( IXSLProcessor *iface ) { if (This->input) IXMLDOMNode_Release(This->input); if (This->output) IStream_Release(This->output); + IXSLTemplate_Release(&This->stylesheet->IXSLTemplate_iface); heap_free( This ); } @@ -516,12 +518,30 @@ static HRESULT WINAPI xslprocessor_get_output( static HRESULT WINAPI xslprocessor_transform( IXSLProcessor *iface, - VARIANT_BOOL *pbool) + VARIANT_BOOL *ret) { xslprocessor *This = impl_from_IXSLProcessor( iface ); + HRESULT hr; + BSTR p; - FIXME("(%p)->(%p): stub\n", This, pbool); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, ret); + + if (!ret) return E_INVALIDARG; + + hr = IXMLDOMNode_transformNode(This->input, This->stylesheet->node, &p); + if (hr == S_OK) + { + ULONG len = 0; + + /* output to stream */ + hr = IStream_Write(This->output, p, SysStringByteLen(p), &len); + *ret = len == SysStringByteLen(p) ? VARIANT_TRUE : VARIANT_FALSE; + SysFreeString(p); + } + else + *ret = VARIANT_FALSE; + + return hr; } static HRESULT WINAPI xslprocessor_reset( IXSLProcessor *iface ) @@ -601,7 +621,7 @@ static const struct IXSLProcessorVtbl xslprocessor_vtbl = xslprocessor_get_stylesheet }; -HRESULT XSLProcessor_create(IXSLProcessor **ppObj) +HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ppObj) { xslprocessor *This; @@ -615,6 +635,8 @@ HRESULT XSLProcessor_create(IXSLProcessor **ppObj) This->ref = 1; This->input = NULL; This->output = NULL; + This->stylesheet = template; + IXSLTemplate_AddRef(&template->IXSLTemplate_iface); *ppObj = &This->IXSLProcessor_iface; diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index d85c6784029..d34168e7640 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -7724,9 +7724,17 @@ static void test_xsltemplate(void) hr = IXSLTemplate_createProcessor(template, NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ref = IXSLTemplate_AddRef(template); + IXSLTemplate_Release(template); + ok(ref == 2, "got %d\n", ref); + hr = IXSLTemplate_createProcessor(template, &processor); ok(hr == S_OK, "got 0x%08x\n", hr); + ref = IXSLTemplate_AddRef(template); + IXSLTemplate_Release(template); + ok(ref == 3, "got %d\n", ref); + /* input no set yet */ V_VT(&v) = VT_BSTR; V_BSTR(&v) = NULL; @@ -7756,6 +7764,9 @@ todo_wine { IStream_Release(stream); todo_wine ok(ref == 4, "got %d\n", ref); + hr = IXSLProcessor_transform(processor, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + /* reset and check stream refcount */ V_VT(&v) = VT_EMPTY; hr = IXSLProcessor_put_output(processor, v);