65.9K
CodeProject 正在变化。 阅读更多。
Home

XML 转换 Shell 扩展

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.08/5 (12投票s)

2003年10月12日

3分钟阅读

viewsIcon

86699

downloadIcon

1649

一个用于根据样式表转换 xml 文件的 Shell 扩展

Sample Image - xmlTransformer.jpg

引言

在使用XML和XSLT时,由于没有内置的执行转换的支持,测试更改会变得很繁琐。MSXML SDK包含一个XSLT命令行实用程序,但除非源文件和转换样式表在同一目录下,否则必须输入输入文件的路径。您可以编写一个脚本,就像我多次做的那样,但每次更改输入或输出时都需要更新此脚本。

此实用程序减轻了编写和测试样式表的一些痛苦。转换的输出将保存到磁盘,并使用记事本在其自己的进程中打开。每次进行转换时,此输出都会被覆盖,因此您需要在关闭记事本之前使用“另存为”来保留文档。我决定使用记事本,因为转换并不总是生成有效的XML。

有很多很棒的文章很好地介绍了shell扩展,所以我不会重复这些信息。我将使用MSXML4中的DOMDocument 来介绍简单的转换和解析错误。

使用代码

要使用此实用程序,请复制并注册dll。在资源管理器中,右键单击XML、XSL或XSLT文件,即可获得“使用...转换”选项。系统将提示您输入XSL/XSLT文件以进行转换。记事本将显示结果,即有效输出或解析器错误信息。

任何有效的xml文本都可以加载到DOMDocument中:XML、样式表和模式。我选择仅对XML和样式表提供此功能。要使其可用于其他文件类型,请更新注册脚本并重新构建。以下将包括XML模式的此选项。

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

转换

在执行转换之前,需要将两个输入文件都加载到DOMDocument中。执行此操作的步骤很简单:创建一个DOMDocument对象,关闭异步加载,加载文件并检查解析错误。

    // load the stylesheet into a DOM
    MSXML2::IXMLDOMDocument2Ptr spStyleSheet;
    spStyleSheet.CreateInstance(__uuidof(MSXML2::DOMDocument));
    spStyleSheet->put_async(VARIANT_FALSE);

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

如果一切顺利,XML将使用DOMDocumenttransformNode方法进行转换,并显示结果。如果出现解析错误,尽可能多地获取信息会很有帮助。

Sample screenshot of parse error output

这在ReportParseError中实现。DOMDocument公开了一个与parseError对象交互的接口。通过这个,我们可以获取所有错误信息,包括未解析的源文本。我使用linelinepos属性来获取围绕解析器停止点的文本片段。

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

    int badChar = 0;
    int maxLen = 0;

    if(src.GetLength() < 120)
        maxLen = src.GetLength();
    else
    {
        // 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)    

解析器将在找到第一个无效字符时报告错误。在大多数情况下,这是实际问题的症状,因此我们希望显示该点之前的文本。值得注意的是,srcTxt并不总是包含所有源。SDK声明“如果错误是由格式不正确的XML引起的,并且无法分配给特定行,则此属性将返回一个空字符串”,但我遇到过一些情况,它返回一个部分字符串,其中不包含足够多的文本来查看实际错误。

关注点

此Shell Extension dll是一个使用Visual Studio .NET编写的ATL项目,并编译为Unicode。要重新构建为ASCII,您将需要使用转换宏进行更改,以便与_bstr_t进行交互。

MSXML4是必需的依赖项,可以从MSDN下载,也可以从SDK下载。

© . All rights reserved.