2016-01-11 7 views
1

Я пытаюсь получить MSXML6 XSLT импорт (или включение) функций, работающих для моего приложения. Я искал повсюду решение для этого и нашел несколько ссылок на людей, для которых он работает, поэтому я думаю, что я должен делать что-то неправильно, но я не могу понять, что это такое.Не удается получить xsl: import или xsl: включить для работы на 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; 
} 

The (правильный) выходной я получаю от инструмента XML (EditiX) является

Title: A Christmas Carol 
Charles Dickens - $14.99 

The (неправильно) вывод, который я получаю от MSXML6 преобразование

A Christmas CarolCharles DickensHardcover14.99 

Похоже файла, указанного для включение не импортируется/включено, поэтому я получаю только результаты шаблона по умолчанию, хотя я не получаю никаких сообщений об ошибках. Как вы можете видеть, я устанавливаю флаг resolveExternals в true (новый для MSXML6). Я также попытался загрузить его из текущей папки, а также в определенную папку (в приведенном выше коде используется/Temp). Я также попытался использовать как xsl: import, так и xsl: include. Решение всегда работает в инструменте XML, но всегда дает неверный результат, используя вышеуказанный код и MSXML6. Я использую Windows 10, если это может быть связано.

+0

Не должно быть URL-адреса (например, абсолютный '' или relative '')? Или где вы хотите загрузить модуль XSLT? –

+0

Я пытался изменить href, чтобы быть в формате URI, но это не имело значения. Я уже пытался включить файл из текущей папки (т. Е. ), но это тоже не работает для меня. Я проверил, что внешний файл (например, DefaultRules.xsl) загружается. Если я попытаюсь включить в него шаблон шаблона xsl: для именованного шаблона в другом файле, я получаю сообщение об ошибке, что именованный шаблон не существует. –

+0

Что произойдет, если вы выполните вместо DefaultRules.xsl следующее: http://pastebin.com/uwcHLXeq (попробуйте выяснить, что он думает о текущем рабочем каталоге). –

ответ

2

Я думаю, проблема в том, что вы установили pXslt->resolveExternals = true;, вам нужно использовать pXslt->resolveExternals = VARIANT_TRUE;.

+0

Вот и все. Спасибо. –