Subject: MSXSL C++ compiled stylesheet code From: Andrew Kimball <akimball@xxxxxxxxxxxxx> Date: Wed, 4 Oct 2000 16:20:01 -0700 |
Below is some MSXSL C++ compiled stylesheet code that several people have asked me to post. I haven't thoroughly tested it, so don't fully trust it : ). Also, as soon as I can get it done, I plan to post a simple shell executable on the MS XML site that will perform command-line transformations (by invoking the MSXML DLL). All of the code for the executable (including this excerpt) will probably be available as a sample of how to use the MSXML COM objects. ~Andy Kimball MSXSL Dev HRESULT TransformHelper::LoadDOM(IXMLDOMDocument * pDOM, BSTR bstrFileName) { HRESULT hr = S_OK; VARIANT vFileName; VARIANT_BOOL fSuccess; V_VT(&vFileName) = VT_BSTR; V_BSTR(&vFileName) = bstrFileName; ChkSucc(pDOM->put_async(VARIANT_FALSE)); ChkSucc(pDOM->load(vFileName, &fSuccess)); if (fSuccess == VARIANT_FALSE) { hr = E_FAIL; } Cleanup: return hr; } HRESULT TransformHelper::Transform() { HRESULT hr = S_OK; LARGE_INTEGER start = {0, 0}; ULARGE_INTEGER cb; IXMLDOMDocument * pInput = NULL; IXMLDOMDocument * pStylesheet = NULL; IXSLTemplate * pTemplate = NULL; IXSLProcessor * pProcessor = NULL; VARIANT vOut, vInput; VARIANT_BOOL fDone; BYTE * pbOutput = NULL; Assert(_bstrInput && _bstrStylesheet && _bstrOutput); // Initialized in-memory stream (faster than writing to a BSTR) if (!_pIStream) { ChkSucc(CreateStreamOnHGlobal(0, TRUE, &_pIStream)); ChkSucc(::GetHGlobalFromStream(_pIStream, &_hOutput)); } else { // Seek to beginning of stream (reset it) ChkSucc(_pIStream->Seek(start, STREAM_SEEK_SET, NULL)); } ChkSucc(::CoCreateInstance( CLSID_FreeThreadedDOMDocument, NULL, CLSCTX_SERVER, IID_IXMLDOMDocument, (void **) &pStylesheet)); // Load stylesheet document ChkSucc(LoadDOM(pStylesheet, _bstrStylesheet)); ChkSucc(::CoCreateInstance( CLSID_DOMDocument, NULL, CLSCTX_SERVER, IID_IXMLDOMDocument, (void **) &pInput)); // Load source document ChkSucc(LoadDOM(pInput, _bstrInput)); ChkSucc(::CoCreateInstance( CLSID_XSLTemplate, NULL, CLSCTX_SERVER, IID_IXSLTemplate, (void **) &pTemplate)); // Compile stylesheet ChkSucc(pTemplate->putref_stylesheet(pStylesheet)); // createProcessor can be concurrently called on multiple threads (i.e. in a server environment), allowing multiple threads // to transform different XML files, using different parameters, while using the same stylesheet. While the XSLTemplate // is thread-safe in order to enable this scenario, each XSLProcessor must be used on only one thread at a time. ChkSucc(pTemplate->createProcessor(&pProcessor)); // Provide the source document to the XSLProcessor V_VT(&vInput) = VT_UNKNOWN; V_UNKNOWN(&vInput) = (IUnknown *) pInput; ChkSucc(pProcessor->put_input(vInput)); // Provide the output stream to the XSLProcessor V_VT(&vOut) = VT_UNKNOWN; V_UNKNOWN(&vOut) = (IUnknown *) _pIStream; ChkSucc(pProcessor->put_output(vOut)); // Execute stylesheet ChkSucc(pProcessor->transform(&fDone)); // Get number of bytes written to output stream (unless you may output more than 4 GB, cb.LowPart has the total #bytes) ChkSucc(_pIStream->Seek(start, STREAM_SEEK_CUR, &cb)); // Get pointer to stream's memory pbOutput = (BYTE *) ::GlobalLock(_hOutput); // ==== Insert code here to output to a file, etc. using pbOutput & cb ==== Cleanup: if (pbOutput) ::GlobalUnlock(_hOutput); SafeRelease(pInput); SafeRelease(pStylesheet); SafeRelease(pProcessor); SafeRelease(pTemplate); return hr; } XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: your mail, T.Pospisek's MailLis | Thread | XSL attribute expression, Dwight Kelly |
RE: where to put the filter?, Evan Lenz | Date | XSL attribute expression, Dwight Kelly |
Month |