Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ex-xslt4.cpp
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN 1
# include <windows.h>
# define DLLHANDLE HMODULE
# define LOADERLIB "p6loader.dll"
# define LOADLIB(fn) LoadLibraryA((fn))
# define LOADSYMBOL(h,s) GetProcAddress((HMODULE)(h),(s))
# define FREELIB(h) FreeLibrary((HMODULE)(h))
#else
# include <errno.h>
# include <dlfcn.h>
# define DLLHANDLE void*
# define LOADERLIB "libp6loader.so"
# define LOADLIB(fn) dlopen((fn),RTLD_NOW)
# define LOADSYMBOL(h,s) dlsym((h),(s))
# define FREELIB(h) !dlclose((h))
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory> // nothrow
#include "filestream.h"
#include "p6xjr.h"
using namespace P6R;
P6DECLARE_CID( p6XSLT );
class CConsoleStream : public P6R::p6IDataStream
{
public:
P6COMMETHOD queryInterface( const P6R::IID &iid, P6R::P6VOID **ppIface )
{
if (!ppIface) return eAccessFault;
*ppIface = NULL;
if(iid == IID_p6ICom) *ppIface = static_cast<p6IDataStream*>(this);
else if(iid == IID_p6IDataStream) *ppIface = static_cast<p6IDataStream*>(this);
else return eNoInterface;
reinterpret_cast<p6ICom*>(*ppIface)->addref();
return eOk;
}
{
return m_cRef++;
}
{
P6INT32 tmp = 0;
if(0 == (tmp = (--m_cRef))) { delete this; }
return tmp;
}
P6COMMETHOD beginStream()
{
return eOk;
}
P6COMMETHOD processStream( const P6R::P6VOID* pData, P6R::P6UINT32 cData )
{
if (m_cBuffer && cData+1 > m_cBuffer)
{
free( m_pBuffer );
m_pBuffer = NULL;
m_cBuffer = 0;
}
if (!m_pBuffer)
{
m_pBuffer = (P6CHAR*) malloc(cData+1);
m_cBuffer = cData;
}
if (m_pBuffer)
{
memcpy( m_pBuffer, pData, cData+1 );
m_pBuffer[cData] = '\0';
printf( m_pBuffer );
}
return eOk;
}
P6COMMETHOD endStream() { return eOk; }
static P6R::P6ERR createInstance( P6R::p6ICom *pOuter, const P6R::IID &iid, P6R::P6VOID **ppIface )
{
P6ERR err = eNoMemory;
CConsoleStream *pObj = NULL;
if (NULL != (pObj = new (std::nothrow) CConsoleStream() ))
{
if (P6FAILED(err = pObj->queryInterface( iid, ppIface ))) delete pObj;
}
return err;
}
CConsoleStream() : m_cRef(0), m_pBuffer(NULL), m_cBuffer(0) {;}
virtual ~CConsoleStream() { if (m_pBuffer) free(m_pBuffer); }
protected:
P6INT32 m_cRef;
P6CHAR *m_pBuffer;
P6UINT32 m_cBuffer;
};
//
static P6R::P6ERR runXSLT( p6IDataStream *pStream )
{
P6CHAR szErr[64];
CFileStream *pObj = NULL;
p6IDataStream *pOutStream = NULL;
P6UINT32 bufSize = 0;
P6ERR err = eOk;
const P6CHAR* pTemplate =
"<?xml version='1.0' encoding='ISO-8859-1'?>\n" \
"<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n" \
" xmlns:p6r='http://www.p6r.com/XSLT/extensions'>\n" \
"<xsl:output method='html' use-character-maps='latin1-accented-letters latin1-symbols'/>\n" \
"<xsl:output name='altchars' method='html' use-character-maps='latin1-entities'/>\n" \
" \n" \
"<xsl:character-map name='NBSP'>\n" \
" <xsl:output-character character='&#160;' string='&amp;nbsp;'/>\n" \
"</xsl:character-map>\n" \
"<xsl:character-map name='latin1-accented-letters'>\n" \
" <xsl:output-character character='&#192;' string='&amp;Agrave;'/>\n" \
" <xsl:output-character character='&#193;' string='&amp;Aacute;'/>\n" \
" <xsl:output-character character='&#194;' string='&amp;Acirc;'/>\n" \
" <xsl:output-character character='&#195;' string='&amp;Atilde;'/>\n" \
" <xsl:output-character character='&#196;' string=''/>\n" \
"</xsl:character-map>\n" \
" \n " \
"<xsl:character-map name='latin1-symbols'>\n" \
" <xsl:output-character character='&#161;' string='&amp;iexcl;'/>\n" \
" <xsl:output-character character='&#162;' string='&amp;cent;'/>\n" \
" <xsl:output-character character='&#163;' string='&amp;pound;'/>\n" \
" <xsl:output-character character='&#164;' string='Henry the Great Dane'/>\n" \
"</xsl:character-map>\n" \
" \n " \
"<xsl:character-map name='latin1-entities' " \
" use-character-maps='latin1-accented-letters NBSP latin1-symbols'/>\n" \
" \n " \
"<xsl:template match='/'>\n" \
"<HTML><BODY>\n" \
" <P>Now is the &#193;time to test &#163; this character *&#196;* mapping thing</P>\n" \
"<ul>\n" \
"<li><p6r:number value='(1,44,33)' format='Hi there-%1$-what is %2$ new?,%3$' /></li>\n" \
"<li><p6r:number value='//name/@id' format='1>%1$,2>%2$,3>%3$,4>%4$'/></li>\n" \
"<li><p6r:number value='(234567)' lang=\"'es-es'\" format='Property costs +%1$ euros'/></li>\n" \
"<li><p6r:number value='/staff/@sku'/></li>\n" \
"<xsl:number count='name | staff' level='multiple' format='[1.1(a)]' />" \
"<xsl:copy-abc-today version='6.1'>\n" \
" <xsl:comment>Version 6.1 should not print</xsl:comment>\n" \
" <xsl:fallback>\n" \
" <xsl:comment>Fallback 1 in version 6.1 element should work</xsl:comment>\n" \
" </xsl:fallback>\n" \
" <xsl:fallback>\n" \
" <xsl:comment>Fallback 2 in version 6.1 element should work</xsl:comment>\n" \
" </xsl:fallback>\n" \
"</xsl:copy-abc-today>\n" \
"</ul>" \
"<xsl:text>A&#195; start text element &#161;&#162;&#163;end text element &#163;</xsl:text>"\
"<P><xsl:text> Replace this char [&#164;] with a simple text string </xsl:text>\n" \
"</BODY></HTML>\n" \
" \n" \
"<xsl:result-document href='charmap1.html' format='altchars'>\n" \
"<HTML><BODY>\n" \
" <xsl:text> ABCDEFGH &#160; IJKL &#194; MNOPQR &#161; STUVWXYZ </xsl:text>\n" \
"</BODY></HTML>\n" \
"</xsl:result-document>\n" \
"<xsl:fallback>\n" \
" <xsl:comment>This should be ignored</xsl:comment>\n" \
"</xsl:fallback>\n" \
"</xsl:template></xsl:stylesheet>";
const P6CHAR* pXMLData =
"<?xml version='1.0' encoding='UTF-8' ?>\n" \
"<staff sku='03'>" \
"<employee>" \
" <name id='55'>Henry Joseph</name>" \
" <name id='2'>Irvin Joseph</name>" \
" <name id='345'>Izzy Joseph</name>" \
" <name id='11'>Basil Joseph</name>" \
" <name id='99'>Mark Joseph</name>" \
" <name id='73'>Jim Susoy</name>" \
"</employee>" \
"</staff>";
// [A] Initialize the components we need
if (P6FAILED( err = p6GetRuntimeIface( VALIDATECOMPTR( p6ISafeString, cpStr )))) return err;
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XSLT, VALIDATECOMPTR( p6IXSLT, cpXSLT ))))
{
printf( "Error: p6IXSLT Initialize failed\n" );
return err;
}
if (NULL != (pObj = new (std::nothrow) CFileStream() ))
{
pObj->initialize( "example-xslt4.html" );
if ( P6FAILED( err = pObj->queryInterface( IID_p6IDataStream, (P6VOID**)&pOutStream )))
{
delete pObj;
return err;
}
else cpOut1 = pOutStream;
}
// Place any warning messages outside of the stylesheet input, if use use cpOut1 instead then
// warnings will be placed into the same output as generated by the stylesheet.
if (NULL != (pObj = new (std::nothrow) CFileStream() ))
{
pObj->initialize( "example-xslt4-warn.txt" );
if ( P6FAILED( err = pObj->queryInterface( IID_p6IDataStream, (P6VOID**)&pOutStream )))
{
delete pObj;
return err;
}
else cpOut2 = pOutStream;
}
// [B] Run the XSLT processor with the XPath extentions
err = cpXSLT->initialize( P6XSLT_NOFLAGS, cpOut2 ); // P6XSLT_XSLTTRACE | P6XSLT_XMLTRACE
if (P6SUCCEEDED( err )) err = cpXSLT->compileTemplates( pTemplate, cpOut2 );
bufSize = (P6UINT32) strlen( pXMLData );
if (P6SUCCEEDED( err )) err = cpXSLT->startTransform( cpOut1, pXMLData, bufSize, P6TRUE );
if (P6FAILED( err )) printf("example failed due to [ %s ]\n", p6ErrToStr(err,&szErr[0],P6CHARCNT(szErr)));
return err;
}
int main(int argc,char *argv[])
{
P6ERR err = eOk;
if ( P6SUCCEEDED(err = CConsoleStream::createInstance( NULL, VALIDATECOMPTR( p6IDataStream, cpDataStream ))))
{
if ( P6SUCCEEDED(err = p6InitializeLoader( cpDataStream, 9, P6SCLF_NOFLAGS )))
{
err = runXSLT( cpDataStream );
printf( "runXSLT result: [ %x ]\n", err );
}
else printf("ERROR: Failed to initialize the loader [ %x ]\n", err );
}
else printf( "ERROR: Failed to create CConsoleStream [ %x ]\n", err );
return err;
}