Module: wine Branch: master Commit: 880bacb5f10dcbb55cc1bd94b7bf5705510ea5f0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=880bacb5f10dcbb55cc1bd94b7...
Author: Alistair Leslie-Hughes leslie_alistair@hotmail.com Date: Wed Mar 26 19:52:36 2008 +1100
msxml3: Implement transformNode.
---
dlls/msxml3/main.c | 10 ++++++ dlls/msxml3/node.c | 66 ++++++++++++++++++++++++++++++++++++++- dlls/msxml3/tests/domdoc.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletions(-)
diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c index 7f03948..7296690 100644 --- a/dlls/msxml3/main.c +++ b/dlls/msxml3/main.c @@ -35,6 +35,10 @@
#include "msxml_private.h"
+#ifdef HAVE_LIBXSLT +#include <libxslt/xslt.h> +#endif + WINE_DEFAULT_DEBUG_CHANNEL(msxml);
static HINSTANCE hInstance; @@ -171,10 +175,16 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) #ifdef HAVE_LIBXML2 xmlInitParser(); #endif +#ifdef HAVE_LIBXSLT + xsltInit(); +#endif hInstance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); break; case DLL_PROCESS_DETACH: +#ifdef HAVE_LIBXSLT + xsltCleanupGlobals(); +#endif #ifdef HAVE_LIBXML2 xmlCleanupParser(); process_detach(); diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index ee4e1b2..7506460 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -33,6 +33,17 @@
#include "msxml_private.h"
+#ifdef HAVE_LIBXSLT +# ifdef HAVE_LIBXSLT_PATTERN_H +# include <libxslt/pattern.h> +# endif +# ifdef HAVE_LIBXSLT_TRANSFORM_H +# include <libxslt/transform.h> +# endif +# include <libxslt/xsltutils.h> +# include <libxslt/xsltInternals.h> +#endif + #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msxml); @@ -1030,8 +1041,61 @@ static HRESULT WINAPI xmlnode_transformNode( IXMLDOMNode* styleSheet, BSTR* xmlString) { - FIXME("\n"); +#ifdef HAVE_LIBXSLT + xmlnode *This = impl_from_IXMLDOMNode( iface ); + xmlnode *pStyleSheet = NULL; + xsltStylesheetPtr xsltSS = NULL; + xmlDocPtr result = NULL; + IXMLDOMNode *ssNew; + + TRACE("%p %p %p\n", This, styleSheet, xmlString); + + if(!styleSheet || !xmlString) + return E_INVALIDARG; + + *xmlString = NULL; + + if(IXMLDOMNode_QueryInterface(styleSheet, &IID_IXMLDOMNode, (LPVOID)&ssNew) == S_OK) + { + pStyleSheet = impl_from_IXMLDOMNode( ssNew ); + + xsltSS = xsltParseStylesheetDoc( pStyleSheet->node->doc); + if(xsltSS) + { + result = xsltApplyStylesheet(xsltSS, This->node->doc, NULL); + if(result) + { + xmlBufferPtr pXmlBuf; + int nSize; + + pXmlBuf = xmlBufferCreate(); + if(pXmlBuf) + { + nSize = xmlNodeDump(pXmlBuf, NULL, (xmlNodePtr)result, 0, 0); + if(nSize > 0) + { + const xmlChar *pContent; + + pContent = xmlBufferContent(pXmlBuf); + *xmlString = bstr_from_xmlChar(pContent); + + xmlBufferFree(pXmlBuf); + } + } + } + } + + IXMLDOMNode_Release(ssNew); + } + + if(*xmlString == NULL) + *xmlString = SysAllocStringLen(NULL, 0); + + return S_OK; +#else + FIXME("libxslt headers were not found at compile time\n"); return E_NOTIMPL; +#endif }
static HRESULT WINAPI xmlnode_selectNodes( diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 9c6eb66..32d3b93 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -119,6 +119,35 @@ static const CHAR szExampleXML[] = " </elem>\n" "</root>\n";
+static const CHAR szTransformXML[] = +"<?xml version=\"1.0\"?>\n" +"<greeting>\n" +"Hello World\n" +"</greeting>"; + +static const CHAR szTransformSSXML[] = +"<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform%5C" version="1.0">\n" +" <xsl:output method="html"/>\n" +" <xsl:template match="/">\n" +" <xsl:apply-templates select="greeting"/>\n" +" </xsl:template>\n" +" <xsl:template match="greeting">\n" +" <html>\n" +" <body>\n" +" <h1>\n" +" <xsl:value-of select="."/>\n" +" </h1>\n" +" </body>\n" +" </html>\n" +" </xsl:template>\n" +"</xsl:stylesheet>"; + +static const CHAR szTransformOutput[] = +"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +"<html><body><h1>\n" +"Hello World\n" +"</h1></body></html>\n"; + static const WCHAR szNonExistentFile[] = { 'c', ':', '\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0 }; @@ -3130,6 +3159,51 @@ static void test_DocumentSaveToDocument(void) IXMLDOMDocument_Release(doc); }
+static void test_testTransforms(void) +{ + IXMLDOMDocument *doc = NULL; + IXMLDOMDocument *docSS = NULL; + IXMLDOMNode *pNode; + VARIANT_BOOL bSucc; + + HRESULT hr; + + hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc ); + if( hr != S_OK ) + return; + + hr = CoCreateInstance( &CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&docSS ); + if( hr != S_OK ) + { + IXMLDOMDocument_Release(doc); + return; + } + + hr = IXMLDOMDocument_loadXML(doc, _bstr_(szTransformXML), &bSucc); + ok(hr == S_OK, "ret %08x\n", hr ); + + hr = IXMLDOMDocument_loadXML(docSS, _bstr_(szTransformSSXML), &bSucc); + ok(hr == S_OK, "ret %08x\n", hr ); + + hr = IXMLDOMDocument_QueryInterface(docSS, &IID_IXMLDOMNode, (LPVOID*)&pNode ); + ok(hr == S_OK, "ret %08x\n", hr ); + if(hr == S_OK) + { + BSTR bOut; + + hr = IXMLDOMDocument_transformNode(doc, pNode, &bOut); + ok(hr == S_OK, "ret %08x\n", hr ); + ok( !lstrcmpW( bOut, _bstr_(szTransformOutput) ), "Stylesheet output not correct\n"); + + IXMLDOMNode_Release(pNode); + } + + IXMLDOMDocument_Release(docSS); + IXMLDOMDocument_Release(doc); + + free_bstrs(); +} + START_TEST(domdoc) { HRESULT r; @@ -3152,6 +3226,7 @@ START_TEST(domdoc) test_xmlTypes(); test_nodeTypeTests(); test_DocumentSaveToDocument(); + test_testTransforms();
CoUninitialize(); }