// // C++ Implementation: xslthandler // // Description: // // // Author: Thach Nguyen , (C) 2006 // // Copyright: See COPYING file that comes with this distribution // // #include #if HAVE_XSLT #include "xslthandler.h" #include extern "C" { #include #include #include #include #include } #include static const int xml_options = XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOCDATA; static const int xslt_options = xml_options; static int writeToQString(void* context, const char* buffer, int len) { QString* t = static_cast(context); *t += QString::fromUtf8(buffer, len); return len; } static void closeQString(void* context) { QString* t = static_cast(context); *t += QString::fromLatin1("\n"); } XSLTHandler::XMLOutputBuffer::XMLOutputBuffer() : m_res(QString::null) { m_buf = xmlOutputBufferCreateIO((xmlOutputWriteCallback)writeToQString, (xmlOutputCloseCallback)closeQString, &m_res, 0); if(m_buf) { m_buf->written = 0; } else { std::cerr << "XMLOutputBuffer::XMLOutputBuffer() - error writing output buffer!\n"; } } XSLTHandler::XMLOutputBuffer::~XMLOutputBuffer() { if(m_buf) { xmlOutputBufferClose(m_buf); //also flushes m_buf = 0; } } int XSLTHandler::s_initCount = 0; XSLTHandler::XSLTHandler(const KURL& xsltURL_) : m_stylesheet(0), m_docIn(0), m_docOut(0) { init(); if(xsltURL_.isValid() && xsltURL_.isLocalFile()) { xmlDocPtr xsltDoc = xmlReadFile(xsltURL_.encodedPathAndQuery().utf8(), NULL, xslt_options); m_stylesheet = xsltParseStylesheetDoc(xsltDoc); if(!m_stylesheet) { std::cerr << "XSLTHandler::XSLTHandler() - null stylesheet pointer for " << xsltURL_.path() << "\n"; } } } XSLTHandler::~XSLTHandler() { if(m_stylesheet) { xsltFreeStylesheet(m_stylesheet); } if(m_docIn) { xmlFreeDoc(m_docIn); } if(m_docOut) { xmlFreeDoc(m_docOut); } --s_initCount; if(s_initCount == 0) { xsltUnregisterExtModule(EXSLT_STRINGS_NAMESPACE); xsltUnregisterExtModule(EXSLT_DYNAMIC_NAMESPACE); xsltCleanupGlobals(); xmlCleanupParser(); } } void XSLTHandler::init() { if(s_initCount == 0) { xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 0; // register all exslt extensions exsltRegisterAll(); } ++s_initCount; m_params.clear(); } QString XSLTHandler::applyStylesheet(const QString& text_) { if(!m_stylesheet) { std::cerr << "XSLTHandler::applyStylesheet() - null stylesheet pointer!\n"; return QString::null; } m_docIn = xmlReadDoc(reinterpret_cast(text_.utf8().data()), NULL, NULL, xml_options); return process(); } QString XSLTHandler::process() { if(!m_docIn) { std::cerr << "XSLTHandler::process() - error parsing input string!\n"; return QString::null; } /* const char* params[2*m_params.count() + 1]; params[0] = NULL; QMap::ConstIterator it = m_params.constBegin(); QMap::ConstIterator end = m_params.constEnd(); for(uint i = 0; it != end; ++it) { params[i ] = qstrdup(it.key()); params[i+1] = qstrdup(it.data()); params[i+2] = NULL; i += 2; } */ // returns NULL on error //m_docOut = xsltApplyStylesheet(m_stylesheet, m_docIn, params); m_docOut = xsltApplyStylesheet(m_stylesheet, m_docIn, NULL); /* for(uint i = 0; i < 2*m_params.count(); ++i) { delete[] params[i]; } */ if(!m_docOut) { std::cerr << "XSLTHandler::applyStylesheet() - error applying stylesheet!\n"; return QString::null; } XMLOutputBuffer output; if(output.isValid()) { int num_bytes = xsltSaveResultTo(output.buffer(), m_docOut, m_stylesheet); if(num_bytes == -1) { std::cerr << "XSLTHandler::applyStylesheet() - error saving output buffer!\n"; } } return output.result(); } #endif