msxml3: Implement transformNode.
authorAlistair Leslie-Hughes <leslie_alistair@hotmail.com>
Wed, 26 Mar 2008 08:52:36 +0000 (19:52 +1100)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 17 Apr 2008 10:25:29 +0000 (12:25 +0200)
dlls/msxml3/main.c
dlls/msxml3/node.c
dlls/msxml3/tests/domdoc.c

index 7f03948d444841f1298c89a3d0fc8003dff063ce..7296690eb01f826d35bdbfe10effde77d7e45d8f 100644 (file)
 
 #include "msxml_private.h"
 
+#ifdef HAVE_LIBXSLT
+#include <libxslt/xslt.h>
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 
 static HINSTANCE hInstance;
@@ -170,11 +174,17 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
     case DLL_PROCESS_ATTACH:
 #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();
index ee4e1b25adccd53c3df19c513bbaf103033fbdef..75064607d5d8d898f97fdf6bee97d7201046b50a 100644 (file)
 
 #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(
index 9c6eb66d041f704f4be119a72fcaf5ed490d0bb6..32d3b937dc70cbe817c45f06071969628d31d957 100644 (file)
@@ -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\" 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();
 }