Click here to Skip to main content
13,559,184 members
Click here to Skip to main content
Add your own
alternative version


27 bookmarked
Posted 11 Oct 2003

XML Transform Shell Extension

, 11 Oct 2003
Rate this:
Please Sign up or sign in to vote.
A shell extension to transform xml files against a stylesheet

Sample Image - xmlTransformer.jpg


When working with XML and XSLT, it becomes tedious testing changes since there is no built-in support for executing the transformation. The MSXML SDK includes an XSLT command-line utility but unless the source and transforming stylesheet are in the same directory you must enter the paths for the inputs. You could write a script, as I have done many times, but this will need to be updated each time you change inputs or outputs.

This utility takes some of the pain out of writing and testing stylesheets. The output of the transformation is saved to disk and opened in its own process using notepad. This output is overwritten each time a transformation is done so you will need to 'Save As' to keep the document before closing notepad. I decided to use notepad because a transformation does not always result in valid XML.

There are a number of great articles that cover shell extensions quite well so I won't re-hash that information. I will cover simple transformations and parse errors using the DOMDocument in MSXML4.

Using the code

To use this utility, copy and register the dll. In Explorer, right click on an XML, XSL, or XSLT file to get the 'Transform with...' option. You will be prompted for an XSL/XSLT file to do the transformation. Notepad will display the results, being valid output or parser error information.

Any valid xml text can be loaded into a DOMDocument: XML, stylesheets and schemas. I have chosen to make this functionality available only to XML and stylesheets. To make this available to other file types, update the registrar script and rebuild. The following will include this option for XML schemas.

NoRemove xsdfile{
   NoRemove Shellex{
      NoRemove ContextMenuHandlers{
         RegSvrEx = s '{737E08D6-7EEA-4AD6-B15F-373B2BCDF5B7}'
}  }  }    

The Transformation

Both input files need to be loaded into a DOMDocument before we can perform a transformation. The steps to do this are simple: create a DOMDocument object, turn off asynchronous loading, load the file and check for parse errors.

// load the stylesheet into a DOM
MSXML2::IXMLDOMDocument2Ptr spStyleSheet;

if( spStyleSheet->load(_variant_t(szStyleSheet)) == VARIANT_FALSE)
    ReportParseError(spStyleSheet->parseError, szStyleSheet);
    return S_FALSE;

If everything goes well, the XML is transformed using the transformNode method of the DOMDocument and the results are displayed. If there are parse errors, it is helpful to have as much information as we can.

Sample screenshot of parse error output

This is accomplished in ReportParseError. The DOMDocument exposes an interface to the parseError object. With this, we can get all error information, including the unparsed source text. I use the line and linepos properties to get a snippet of text surrounding the point where the parser stopped.

CString src = pParseError->srcText.GetBSTR();

int badChar = 0;
int maxLen = 0;

if(src.GetLength() < 120)
    maxLen = src.GetLength();
    // move to the correct line
    for(int x=0; x < pParseError->line - 1; x++)
        badChar = src.Find(_T("\n"), badChar);

    // get 120 characters starting at 60 before error
    badChar -= (60 - pParseError->linepos);
    maxLen = 120;
src.Mid(badChar, maxLen)

The parser will report an error on the first character found to be invalid. In most cases, this is a symptom of the real issue so we want to display text prior to that point. Something interesting to note is that srcTxt doesn't always contain all of the source. The SDK states that "this property returns an empty string if the error is caused by XML that is not well-formed and cannot be assigned to a specific line", but I had cases where it returns a partial string that doesn't contian enough text to see the actual error.

Points of Interest

This Shell Extension dll is an ATL project written using Visual Studio .NET and compiled for Unicode. To rebuild for ASCII, you will need to make changes using the conversion macros in order to interact with _bstr_t.

MSXML4 is a required dependency and can be downloaded, along with the SDK from MSDN.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Doug Mitchell
Web Developer
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralCan't build under VS.NET 2003 Pin
Doug Schmidt14-Oct-03 4:54
memberDoug Schmidt14-Oct-03 4:54 
I can't build xmlTransformer under VS.NET 2003. I've tried building both solutions in the ZIP archive, and I get the same results, shown below.

By the way, why *are* there two nearly-identical-but-not-quite solutions in the source code, one rooted at .\*, and the other rooted at src\*. I don't get it.

Here are my build results from VS.NET 2003:
d:\DougTools\xmlTransformer\xmlTransformerShlExt.h(49) : error C2787: 'IContextMenu' : no GUID has been associated with this object
d:\DougTools\xmlTransformer\xmlTransformerShlExt.h(49) : error C2440: 'initializing' : cannot convert from 'DWORD_PTR' to 'const IID *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
d:\DougTools\xmlTransformer\xmlTransformerShlExt.h(49) : error C2440: 'initializing' : cannot convert from 'ATL::_ATL_CREATORARGFUNC (__stdcall *)' to 'DWORD_PTR'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast

I can't seem to find any definition of IContextMenu anywhere in the platform SDK. What am I missing?

Doug Schmidt
GeneralRe: Can't build under VS.NET 2003 Pin
Doug Mitchell14-Oct-03 15:41
memberDoug Mitchell14-Oct-03 15:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.180515.1 | Last Updated 12 Oct 2003
Article Copyright 2003 by Doug Mitchell
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid