2016-01-11 54 views
1

我正在嘗試獲取適用於我的應用的MSXML6 XSLT導入(或包含)功能。我曾到處尋找解決辦法,並且找到了許多似乎正在工作的人的參考,所以我想我一定在做錯事,但我無法弄清楚它是什麼。無法獲取xsl:import或xsl:include在MSXML6上工作

是book.xml

<Book> 
    <Title>A Christmas Carol</Title> 
    <Author>Charles Dickens</Author> 
    <Binding>Hardcover</Binding> 
    <Price>14.99</Price> 
    <Comment/> 
</Book> 

DefaultRules.xsl

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:include href="/Temp/Book.xsl"/> 
    <xsl:output method="text" indent="no"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="Book"/> 
    </xsl:template> 
</xsl:stylesheet> 

Book.xsl

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="Book"> 
     <xsl:text>Title: </xsl:text> 
     <xsl:apply-templates select="Title"/> 
     <xsl:text>&#10;</xsl:text> 
     <xsl:apply-templates select="Author"/> 
     <xsl:text> - $</xsl:text> 
     <xsl:apply-templates select="Price"/> 
    </xsl:template> 
</xsl:stylesheet> 

Proto.cpp

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CoInitialize(NULL); 

    variant_t vResult; 
    LPCTSTR output = NULL; 
    MSXML2::IXMLDOMDocumentPtr pXml(__uuidof(MSXML2::DOMDocument60)); 
    MSXML2::IXMLDOMDocumentPtr pXslt(__uuidof(MSXML2::FreeThreadedDOMDocument60)); 
    MSXML2::IXSLTemplatePtr pTemplate(__uuidof(MSXML2::XSLTemplate60)); 
    MSXML2::IXSLProcessorPtr pProcessor; 
    IStream *pOutStream; 
    // load xml file with data and xsl file to transform 
    // xml -> html 
    pXml->async = false; 
    pXml->load(_bstr_t("Book.xml")); 
    pXslt->resolveExternals = true; 
    pXslt->async = false; 
    pXslt->load(_bstr_t("/Temp/DefaultRules.xsl")); 
    pTemplate->stylesheet = pXslt; 
    pProcessor = pTemplate->createProcessor(); 

    CreateStreamOnHGlobal(NULL, TRUE, &pOutStream); 
    pProcessor->put_output(_variant_t(pOutStream)); 
    pProcessor->put_input(_variant_t((IUnknown*)pXml)); 
    pProcessor->transform(); 
    //get results of transformation and print them to stdout 
    HGLOBAL hg = NULL; 
    pOutStream->Write((void const*)"\0\0", 2, 0); 
    GetHGlobalFromStream(pOutStream, &hg); 
    output = (LPCTSTR)GlobalLock(hg); 
    wprintf(L"%s", output); 
    GlobalUnlock(hg); 

    //release before CoUninitialize() 
    pXml.Release(); 
    pXslt.Release(); 
    pTemplate.Release(); 
    pProcessor.Release(); 

    CoUninitialize(); 
    getchar(); 
    return 0; 
} 

的(正確)的輸出,我從一個XML工具(EditiX)得到的是

Title: A Christmas Carol 
Charles Dickens - $14.99 

的(不正確)的輸出,我從MSXML6得到變換

A Christmas CarolCharles DickensHardcover14.99 

它看起來像指定文件包含沒有被導入/包含,所以我只是得到了默認的模板結果,儘管我沒有收到任何錯誤消息。如您所見,我將resolveExternals標誌設置爲true(對於MSXML6是新的)。我也嘗試從當前文件夾加載它以及特定文件夾(上面的代碼使用/ Temp)。我也嘗試使用xsl:import和xsl:include。該解決方案始終在XML工具中工作,但始終使用上述代碼和MSXML6提供不正確的結果。如果可能有關聯,我正在使用Windows 10。

+0

不應該是一個URL(例如,絕對的'''''或相對'')?或者你想從哪裏加載XSLT模塊? –

+0

我試着將href改爲URI格式,但沒有任何區別。我已經嘗試過從當前文件夾包含文件(即),但這對我也不起作用。 我已驗證外部文件(例如DefaultRules.xsl)正在被加載。如果我試圖在其中包含一個xsl:call-template作爲另一個文件中的命名模板,我會收到一條錯誤消息,指出該命名模板不存在。 –

+0

如果您運行以下代替DefaultRules.xsl,會發生什麼情況? http://pastebin.com/uwcHLXeq(嘗試找出它認爲當前的工作目錄是什麼)。 –

回答

2

我覺得問題是你已經設置了pXslt->resolveExternals = true;,你需要使用pXslt->resolveExternals = VARIANT_TRUE;

+0

就是這樣。謝謝。 –