Logo Search packages:      
Sourcecode: kbib version File versions  Download package

xslthandler.cpp

//
// C++ Implementation: xslthandler
//
// Description: 
//
//
// Author: Thach Nguyen <thach.nguyen@rmit.edu.au>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <config.h>
#if HAVE_XSLT
#include "xslthandler.h"

#include <qtextcodec.h>

extern "C" {
#include <libxslt/xslt.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include <libxslt/extensions.h>

#include <libexslt/exslt.h>
}

#include <iostream>


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<QString*>(context);
      *t += QString::fromUtf8(buffer, len);
      return len;
}

static void closeQString(void* context) {
      QString* t = static_cast<QString*>(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<xmlChar*>(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<QCString, QCString>::ConstIterator it = m_params.constBegin();
      QMap<QCString, QCString>::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

Generated by  Doxygen 1.6.0   Back to index