Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/bsc.c | 25 ++++++++-- dlls/msxml3/domdoc.c | 49 ++++++++---------- dlls/msxml3/msxml_private.h | 1 + dlls/msxml3/tests/domdoc.c | 118 ++++++++++++++++++++++++++++---------------- 4 files changed, 118 insertions(+), 75 deletions(-)
diff --git a/dlls/msxml3/bsc.c b/dlls/msxml3/bsc.c index d9519f37a8..05977a610b 100644 --- a/dlls/msxml3/bsc.c +++ b/dlls/msxml3/bsc.c @@ -242,24 +242,24 @@ static const struct IBindStatusCallbackVtbl bsc_vtbl = bsc_OnObjectAvailable };
-HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon) +HRESULT create_uri(const WCHAR *url, IUri **uri) { WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
TRACE("%s\n", debugstr_w(url));
- if(!PathIsURLW(url)) + if (!PathIsURLW(url)) { WCHAR fullpath[MAX_PATH]; DWORD needed = sizeof(fileUrl)/sizeof(WCHAR);
- if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR))) + if (!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR))) { WARN("can't find path\n"); return E_FAIL; }
- if(FAILED(UrlCreateFromPathW(fullpath, fileUrl, &needed, 0))) + if (FAILED(UrlCreateFromPathW(fullpath, fileUrl, &needed, 0))) { ERR("can't create url from path\n"); return E_FAIL; @@ -267,7 +267,22 @@ HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon) url = fileUrl; }
- return CreateURLMonikerEx(NULL, url, mon, 0); + return CreateUri(url, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri); +} + +HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon) +{ + HRESULT hr; + IUri *uri; + + TRACE("%s\n", debugstr_w(url)); + + if (FAILED(hr = create_uri(url, &uri))) + return hr; + + hr = CreateURLMonikerEx2(NULL, uri, mon, 0); + IUri_Release(uri); + return hr; }
HRESULT bind_url(IMoniker *mon, HRESULT (*onDataAvailable)(void*,char*,DWORD), diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index a40fac2106..87a167e46e 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -86,7 +86,7 @@ typedef struct { xmlChar const* selectNsStr; LONG selectNsStr_len; BOOL XPath; - WCHAR *url; + IUri *uri; } domdoc_properties;
typedef struct ConnectionPoint ConnectionPoint; @@ -298,8 +298,8 @@ static domdoc_properties *create_properties(MSXML_VERSION version) properties->version = version; properties->XPath = (version == MSXML4 || version == MSXML6);
- /* document url */ - properties->url = NULL; + /* document uri */ + properties->uri = NULL;
return properties; } @@ -335,16 +335,9 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties) list_add_tail(&pcopy->selectNsList, &new_ns->entry); }
- if (properties->url) - { - int len = strlenW(properties->url); - - pcopy->url = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); - memcpy(pcopy->url, properties->url, len*sizeof(WCHAR)); - pcopy->url[len] = 0; - } - else - pcopy->url = NULL; + pcopy->uri = properties->uri; + if (pcopy->uri) + IUri_AddRef(pcopy->uri); }
return pcopy; @@ -358,7 +351,8 @@ static void free_properties(domdoc_properties* properties) IXMLDOMSchemaCollection2_Release(properties->schemaCache); clear_selectNsList(&properties->selectNsList); heap_free((xmlChar*)properties->selectNsStr); - CoTaskMemFree(properties->url); + if (properties->uri) + IUri_Release(properties->uri); heap_free(properties); } } @@ -2293,16 +2287,20 @@ static HRESULT WINAPI domdoc_load( if ( filename ) { IMoniker *mon; + IUri *uri;
- CoTaskMemFree(This->properties->url); - This->properties->url = NULL; + if (This->properties->uri) + { + IUri_Release(This->properties->uri); + This->properties->uri = NULL; + }
- hr = create_moniker_from_url( filename, &mon); + hr = create_uri(filename, &uri); + if (SUCCEEDED(hr)) + hr = CreateURLMonikerEx2(NULL, uri, &mon, 0); if ( SUCCEEDED(hr) ) { hr = domdoc_load_moniker( This, mon ); - if (hr == S_OK) - IMoniker_GetDisplayName(mon, NULL, NULL, &This->properties->url); IMoniker_Release(mon); }
@@ -2310,6 +2308,7 @@ static HRESULT WINAPI domdoc_load( This->error = E_FAIL; else { + This->properties->uri = uri; hr = This->error = S_OK; *isSuccessful = VARIANT_TRUE; } @@ -2374,16 +2373,10 @@ static HRESULT WINAPI domdoc_get_url( if (!url) return E_INVALIDARG;
- if (This->properties->url) - { - *url = SysAllocString(This->properties->url); - if (!*url) - return E_OUTOFMEMORY; - - return S_OK; - } - else + if (!This->properties->uri) return return_null_bstr(url); + + return IUri_GetPropertyBSTR(This->properties->uri, Uri_PROPERTY_DISPLAY_URI, url, 0); }
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 4bcac932d0..8d7833b083 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -544,6 +544,7 @@ static inline const CLSID* SchemaCache_version(MSXML_VERSION v) typedef struct bsc_t bsc_t;
HRESULT create_moniker_from_url(LPCWSTR, IMoniker**) DECLSPEC_HIDDEN; +HRESULT create_uri(const WCHAR *, IUri **) DECLSPEC_HIDDEN; HRESULT bind_url(IMoniker*, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, bsc_t**) DECLSPEC_HIDDEN; HRESULT detach_bsc(bsc_t*) DECLSPEC_HIDDEN;
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 7c56015235..81e24935a4 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10152,13 +10152,68 @@ static void write_to_file(const char *name, const char *data) CloseHandle(hfile); }
+static void test_doc_load_from_path(IXMLDOMDocument *doc, const char *path) +{ + IXMLDOMDocument *doc2; + IXMLDOMElement *elem; + BSTR url, url2; + VARIANT_BOOL b; + VARIANT src; + HRESULT hr; + + url = _bstr_(path); + + V_VT(&src) = VT_BSTR; + V_BSTR(&src) = url; + hr = IXMLDOMDocument_load(doc, src, &b); + ok(hr == S_OK, "Failed to load document, %#x.\n", hr); + ok(b == VARIANT_TRUE, "got %d\n", b); + + V_VT(&src) = VT_BSTR | VT_BYREF; + V_BSTRREF(&src) = &url; + hr = IXMLDOMDocument_load(doc, src, &b); + ok(hr == S_OK, "Failed to load document, %#x.\n", hr); + ok(b == VARIANT_TRUE, "got %d\n", b); + + url = NULL; + hr = IXMLDOMDocument_get_url(doc, &url); + ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* Create another instance for the same document, check url */ + hr = IXMLDOMElement_get_ownerDocument(elem, &doc2); + ok(hr == S_OK, "Failed to get owner document, hr %#x.\n", hr); + + hr = IXMLDOMDocument_get_url(doc2, &url2); + ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr); + ok(!lstrcmpW(url, url2), "Unexpected url %s.\n", wine_dbgstr_w(url2)); + + IXMLDOMDocument_Release(doc2); + IXMLDOMElement_Release(elem); + SysFreeString(url2); + SysFreeString(url); +} + +static void url_forward_slash(char *url) +{ + char *p = url; + + while (*p) + { + if (*p == '\') + *p = '/'; + p++; + } +} + static void test_load(void) { - IXMLDOMDocument *doc, *doc2; - BSTR pathW, bstr1, bstr2; + char path[MAX_PATH], path2[MAX_PATH]; IXMLDOMNodeList *list; - IXMLDOMElement *elem; - char path[MAX_PATH]; + IXMLDOMDocument *doc; + BSTR bstr1, bstr2; VARIANT_BOOL b; VARIANT src; HRESULT hr; @@ -10179,47 +10234,26 @@ static void test_load(void) EXPECT_HR(hr, E_INVALIDARG); ok(b == VARIANT_FALSE, "got %d\n", b);
- pathW = _bstr_(path); - - /* load from path: VT_BSTR */ - V_VT(&src) = VT_BSTR; - V_BSTR(&src) = pathW; - hr = IXMLDOMDocument_load(doc, src, &b); - EXPECT_HR(hr, S_OK); - ok(b == VARIANT_TRUE, "got %d\n", b); - - bstr1 = NULL; - hr = IXMLDOMDocument_get_url(doc, &bstr1); - ok(hr == S_OK, "got 0x%08x\n", hr); - SysFreeString(bstr1); - - /* load from a path: VT_BSTR|VT_BYREF */ - V_VT(&src) = VT_BSTR | VT_BYREF; - V_BSTRREF(&src) = &pathW; - hr = IXMLDOMDocument_load(doc, src, &b); - EXPECT_HR(hr, S_OK); - ok(b == VARIANT_TRUE, "got %d\n", b); - - bstr1 = NULL; - hr = IXMLDOMDocument_get_url(doc, &bstr1); - ok(hr == S_OK, "got 0x%08x\n", hr); - - hr = IXMLDOMDocument_get_documentElement(doc, &elem); - ok(hr == S_OK, "got 0x%08x\n", hr); + /* "file://" url */ + strcpy(path2, "file://"); + strcat(path2, path); + test_doc_load_from_path(doc, path2);
- /* create another instance for the same document, check url */ - hr = IXMLDOMElement_get_ownerDocument(elem, &doc2); - ok(hr == S_OK, "got 0x%08x\n", hr); + /* file:// url, forward slashes */ + url_forward_slash(path2); + test_doc_load_from_path(doc, path2);
- hr = IXMLDOMDocument_get_url(doc, &bstr2); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(!lstrcmpW(bstr1, bstr2), "got %s\n", wine_dbgstr_w(bstr2)); + /* "file:/" url */ + strcpy(path2, "file:/"); + strcat(path2, path); + test_doc_load_from_path(doc, path);
- IXMLDOMDocument_Release(doc2); - IXMLDOMElement_Release(elem); + /* file:/ with forward slashes. */ + url_forward_slash(path2); + test_doc_load_from_path(doc, path2);
- SysFreeString(bstr1); - SysFreeString(bstr2); + /* Regular local path. */ + test_doc_load_from_path(doc, path);
/* load from a path: VT_BSTR|VT_BYREF, null ptr */ V_VT(&src) = VT_BSTR | VT_BYREF; @@ -10239,7 +10273,7 @@ static void test_load(void) write_to_file(path, nocontent);
V_VT(&src) = VT_BSTR; - V_BSTR(&src) = pathW; + V_BSTR(&src) = _bstr_(path); b = VARIANT_TRUE; hr = IXMLDOMDocument_load(doc, src, &b); ok(hr == S_FALSE, "got 0x%08x\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/domdoc.c | 1 + dlls/msxml3/main.c | 6 ++ dlls/msxml3/msxml_private.h | 12 ++- dlls/msxml3/node.c | 189 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 204 insertions(+), 4 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index 87a167e46e..ddd756582b 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -2308,6 +2308,7 @@ static HRESULT WINAPI domdoc_load( This->error = E_FAIL; else { + get_doc(This)->name = (char *)xmlchar_from_wcharn(filename, -1, TRUE); This->properties->uri = uri; hr = This->error = S_OK; *isSuccessful = VARIANT_TRUE; diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c index 1905f57be4..311fd66e0a 100644 --- a/dlls/msxml3/main.c +++ b/dlls/msxml3/main.c @@ -39,6 +39,7 @@ # include <libxslt/xsltutils.h> # include <libxslt/variables.h> # include <libxslt/xsltInternals.h> +# include <libxslt/documents.h> # endif #endif
@@ -176,6 +177,7 @@ DECL_FUNCPTR(xsltNextImport); DECL_FUNCPTR(xsltParseStylesheetDoc); DECL_FUNCPTR(xsltQuoteUserParams); DECL_FUNCPTR(xsltSaveResultTo); +DECL_FUNCPTR(xsltSetLoaderFunc); # undef DECL_FUNCPTR #endif
@@ -202,10 +204,14 @@ static void init_libxslt(void) LOAD_FUNCPTR(xsltParseStylesheetDoc, 1); LOAD_FUNCPTR(xsltQuoteUserParams, 1); LOAD_FUNCPTR(xsltSaveResultTo, 1); + LOAD_FUNCPTR(xsltSetLoaderFunc, 1); #undef LOAD_FUNCPTR
if (pxsltInit) pxsltInit(); + + pxsltSetLoaderFunc(xslt_doc_default_loader); + return;
sym_not_found: diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 8d7833b083..1c052152be 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -379,6 +379,12 @@ extern BSTR EnsureCorrectEOL(BSTR) DECLSPEC_HIDDEN;
extern xmlChar* tagName_to_XPath(const BSTR tagName) DECLSPEC_HIDDEN;
+#ifdef SONAME_LIBXSLT +# include <libxslt/documents.h> +extern xmlDocPtr xslt_doc_default_loader(const xmlChar *uri, xmlDictPtr dict, int options, + void *_ctxt, xsltLoadType type) DECLSPEC_HIDDEN; +#endif /* SONAME_LIBXSLT */ + static inline BSTR bstr_from_xmlChar(const xmlChar *str) { BSTR ret = NULL; @@ -395,12 +401,12 @@ static inline BSTR bstr_from_xmlChar(const xmlChar *str) return ret; }
-static inline xmlChar *xmlchar_from_wcharn(const WCHAR *str, int nchars) +static inline xmlChar *xmlchar_from_wcharn(const WCHAR *str, int nchars, BOOL use_xml_alloc) { xmlChar *xmlstr; DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, nchars, NULL, 0, NULL, NULL );
- xmlstr = heap_alloc( len+1 ); + xmlstr = use_xml_alloc ? xmlMalloc( len + 1 ) : heap_alloc( len + 1 ); if ( xmlstr ) { WideCharToMultiByte( CP_UTF8, 0, str, nchars, (LPSTR) xmlstr, len+1, NULL, NULL ); @@ -411,7 +417,7 @@ static inline xmlChar *xmlchar_from_wcharn(const WCHAR *str, int nchars)
static inline xmlChar *xmlchar_from_wchar( const WCHAR *str ) { - return xmlchar_from_wcharn(str, -1); + return xmlchar_from_wcharn(str, -1, FALSE); }
static inline xmlChar *heap_strdupxmlChar(const xmlChar *str) diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index ece82efa10..bcb4181374 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -26,6 +26,7 @@
#ifdef HAVE_LIBXML2 # include <libxml/parser.h> +# include <libxml/parserInternals.h> # include <libxml/xmlerror.h> # include <libxml/HTMLtree.h> # ifdef SONAME_LIBXSLT @@ -39,6 +40,7 @@ # include <libxslt/variables.h> # include <libxslt/xsltutils.h> # include <libxslt/xsltInternals.h> +# include <libxslt/documents.h> # endif #endif
@@ -1313,7 +1315,192 @@ static HRESULT node_transform_write_to_stream(xsltStylesheetPtr style, xmlDocPtr return hr; }
-#endif +struct import_buffer +{ + char *data; + int cur; + int len; +}; + +static int XMLCALL import_loader_io_read(void *context, char *out, int len) +{ + struct import_buffer *buffer = (struct import_buffer *)context; + + TRACE("%p, %p, %d\n", context, out, len); + + if (buffer->cur == buffer->len) + return 0; + + len = min(len, buffer->len - buffer->cur); + memcpy(out, &buffer->data[buffer->cur], len); + buffer->cur += len; + + TRACE("read %d\n", len); + + return len; +} + +static int XMLCALL import_loader_io_close(void * context) +{ + struct import_buffer *buffer = (struct import_buffer *)context; + + TRACE("%p\n", context); + + heap_free(buffer->data); + heap_free(buffer); + return 0; +} + +static HRESULT import_loader_onDataAvailable(void *ctxt, char *ptr, DWORD len) +{ + xmlParserInputPtr *input = (xmlParserInputPtr *)ctxt; + xmlParserInputBufferPtr inputbuffer; + struct import_buffer *buffer; + + buffer = heap_alloc(sizeof(*buffer)); + + buffer->data = heap_alloc(len); + memcpy(buffer->data, ptr, len); + buffer->cur = 0; + buffer->len = len; + + inputbuffer = xmlParserInputBufferCreateIO(import_loader_io_read, import_loader_io_close, buffer, + XML_CHAR_ENCODING_NONE); + *input = xmlNewIOInputStream(ctxt, inputbuffer, XML_CHAR_ENCODING_NONE); + if (!*input) + xmlFreeParserInputBuffer(inputbuffer); + + return *input ? S_OK : E_FAIL; +} + +static HRESULT xslt_doc_get_uri(const xmlChar *uri, void *_ctxt, xsltLoadType type, IUri **doc_uri) +{ + xsltStylesheetPtr style = (xsltStylesheetPtr)_ctxt; + IUri *href_uri; + HRESULT hr; + BSTR uriW; + + *doc_uri = NULL; + + uriW = bstr_from_xmlChar(uri); + hr = CreateUri(uriW, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &href_uri); + SysFreeString(uriW); + if (FAILED(hr)) + { + WARN("Failed to create href uri, %#x.\n", hr); + return hr; + } + + if (type == XSLT_LOAD_STYLESHEET && style->doc && style->doc->name) + { + IUri *base_uri; + BSTR baseuriW; + + baseuriW = bstr_from_xmlChar((xmlChar *)style->doc->name); + hr = CreateUri(baseuriW, Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &base_uri); + SysFreeString(baseuriW); + if (FAILED(hr)) + { + WARN("Failed to create base uri, %#x.\n", hr); + return hr; + } + + hr = CoInternetCombineIUri(base_uri, href_uri, 0, doc_uri, 0); + IUri_Release(base_uri); + if (FAILED(hr)) + WARN("Failed to combine uris, %#x.\n", hr); + } + else + { + *doc_uri = href_uri; + IUri_AddRef(*doc_uri); + } + + IUri_Release(href_uri); + + return hr; +} + +xmlDocPtr xslt_doc_default_loader(const xmlChar *uri, xmlDictPtr dict, int options, + void *_ctxt, xsltLoadType type) +{ + IUri *import_uri = NULL; + xmlParserInputPtr input; + xmlParserCtxtPtr pctxt; + xmlDocPtr doc = NULL; + IMoniker *moniker; + HRESULT hr; + bsc_t *bsc; + BSTR uriW; + + TRACE("%s, %p, %#x, %p, %d\n", debugstr_a((const char *)uri), dict, options, _ctxt, type); + + pctxt = xmlNewParserCtxt(); + if (!pctxt) + return NULL; + + if (dict && pctxt->dict) + { + xmlDictFree(pctxt->dict); + pctxt->dict = NULL; + } + + if (dict) + { + pctxt->dict = dict; + xmlDictReference(pctxt->dict); + } + + xmlCtxtUseOptions(pctxt, options); + + hr = xslt_doc_get_uri(uri, _ctxt, type, &import_uri); + if (FAILED(hr)) + goto failed; + + hr = CreateURLMonikerEx2(NULL, import_uri, &moniker, 0); + if (FAILED(hr)) + goto failed; + + hr = bind_url(moniker, import_loader_onDataAvailable, &input, &bsc); + IMoniker_Release(moniker); + if (FAILED(hr)) + goto failed; + + if (FAILED(detach_bsc(bsc))) + goto failed; + + if (!input) + goto failed; + + inputPush(pctxt, input); + xmlParseDocument(pctxt); + + if (pctxt->wellFormed) + { + doc = pctxt->myDoc; + /* Set imported uri, to give nested imports a chance. */ + if (IUri_GetPropertyBSTR(import_uri, Uri_PROPERTY_ABSOLUTE_URI, &uriW, 0) == S_OK) + { + doc->name = (char *)xmlchar_from_wcharn(uriW, SysStringLen(uriW), TRUE); + SysFreeString(uriW); + } + } + else + { + doc = NULL; + xmlFreeDoc(pctxt->myDoc); + pctxt->myDoc = NULL; + } + +failed: + xmlFreeParserCtxt(pctxt); + if (import_uri) + IUri_Release(import_uri); + + return doc; +} + +#endif /* SONAME_LIBXSLT */
HRESULT node_transform_node_params(const xmlnode *This, IXMLDOMNode *stylesheet, BSTR *p, ISequentialStream *stream, const struct xslprocessor_params *params)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c index 311fd66e0a..0d056ea981 100644 --- a/dlls/msxml3/main.c +++ b/dlls/msxml3/main.c @@ -40,6 +40,8 @@ # include <libxslt/variables.h> # include <libxslt/xsltInternals.h> # include <libxslt/documents.h> +# include <libxslt/extensions.h> +# include <libxslt/extra.h> # endif #endif
@@ -172,10 +174,12 @@ DECL_FUNCPTR(xsltApplyStylesheetUser); DECL_FUNCPTR(xsltCleanupGlobals); DECL_FUNCPTR(xsltFreeStylesheet); DECL_FUNCPTR(xsltFreeTransformContext); +DECL_FUNCPTR(xsltFunctionNodeSet); DECL_FUNCPTR(xsltNewTransformContext); DECL_FUNCPTR(xsltNextImport); DECL_FUNCPTR(xsltParseStylesheetDoc); DECL_FUNCPTR(xsltQuoteUserParams); +DECL_FUNCPTR(xsltRegisterExtModuleFunction); DECL_FUNCPTR(xsltSaveResultTo); DECL_FUNCPTR(xsltSetLoaderFunc); # undef DECL_FUNCPTR @@ -199,10 +203,12 @@ static void init_libxslt(void) LOAD_FUNCPTR(xsltCleanupGlobals, 1); LOAD_FUNCPTR(xsltFreeStylesheet, 1); LOAD_FUNCPTR(xsltFreeTransformContext, 1); + LOAD_FUNCPTR(xsltFunctionNodeSet, 1); LOAD_FUNCPTR(xsltNewTransformContext, 1); LOAD_FUNCPTR(xsltNextImport, 1); LOAD_FUNCPTR(xsltParseStylesheetDoc, 1); LOAD_FUNCPTR(xsltQuoteUserParams, 1); + LOAD_FUNCPTR(xsltRegisterExtModuleFunction, 1); LOAD_FUNCPTR(xsltSaveResultTo, 1); LOAD_FUNCPTR(xsltSetLoaderFunc, 1); #undef LOAD_FUNCPTR @@ -211,6 +217,10 @@ static void init_libxslt(void) pxsltInit();
pxsltSetLoaderFunc(xslt_doc_default_loader); + pxsltRegisterExtModuleFunction( + (const xmlChar *)"node-set", + (const xmlChar *)"urn:schemas-microsoft-com:xslt", + pxsltFunctionNodeSet);
return;