diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-08-21 13:06:27 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-08-21 13:06:27 +0100 |
commit | b388a5537f2e3b459021118fcda18e2a58da3492 (patch) | |
tree | 52f8beda2b103d5411b63cef900060a7433708ae /icespider/xslt | |
parent | Allow inclusion of user headers (diff) | |
download | icespider-b388a5537f2e3b459021118fcda18e2a58da3492.tar.bz2 icespider-b388a5537f2e3b459021118fcda18e2a58da3492.tar.xz icespider-b388a5537f2e3b459021118fcda18e2a58da3492.zip |
Add support for custom output serializers
Diffstat (limited to 'icespider/xslt')
-rw-r--r-- | icespider/xslt/Jamfile.jam | 22 | ||||
-rw-r--r-- | icespider/xslt/exslt.cpp | 17 | ||||
-rw-r--r-- | icespider/xslt/xsltStreamSerializer.cpp | 70 | ||||
-rw-r--r-- | icespider/xslt/xsltStreamSerializer.h | 34 |
4 files changed, 143 insertions, 0 deletions
diff --git a/icespider/xslt/Jamfile.jam b/icespider/xslt/Jamfile.jam new file mode 100644 index 0000000..1bf62a8 --- /dev/null +++ b/icespider/xslt/Jamfile.jam @@ -0,0 +1,22 @@ +lib adhocutil : : : : <include>/usr/include/adhocutil ; +lib slicer-xml : : : : <include>/usr/include/slicer ; +lib boost_system ; +lib IceUtil ; +lib xslt ; +lib exslt ; + +lib icespider-xslt : + [ glob-tree *.cpp : bin ] + : + <library>adhocutil + <library>slicer-xml + <library>boost_system + <library>IceUtil + <library>xslt + <library>exslt + <library>../..//libxmlpp + : : + <include>. + <library>../..//libxmlpp + ; + diff --git a/icespider/xslt/exslt.cpp b/icespider/xslt/exslt.cpp new file mode 100644 index 0000000..63bd0d1 --- /dev/null +++ b/icespider/xslt/exslt.cpp @@ -0,0 +1,17 @@ +#include <libexslt/exslt.h> +#include <libxslt/transform.h> + +static void initLibXml() __attribute__((constructor(102))); +void initLibXml() +{ + xmlInitParser(); + exsltRegisterAll(); +} + +static void cleanupLibXml() __attribute__((destructor(102))); +void cleanupLibXml() +{ + xsltCleanupGlobals(); + xmlCleanupParser(); +} + diff --git a/icespider/xslt/xsltStreamSerializer.cpp b/icespider/xslt/xsltStreamSerializer.cpp new file mode 100644 index 0000000..bbe3943 --- /dev/null +++ b/icespider/xslt/xsltStreamSerializer.cpp @@ -0,0 +1,70 @@ +#include "xsltStreamSerializer.h" +#include <libxslt/xsltInternals.h> +#include <libxml/HTMLtree.h> +#include <factory.impl.h> + +namespace IceSpider { + static int xmlstrmclosecallback(void * context) + { + ((std::ostream*)context)->flush(); + return 0; + } + + static int xmlstrmwritecallback(void * context, const char * buffer, int len) + { + ((std::ostream*)context)->write(buffer, len); + return len; + } + + XsltStreamSerializer::IceSpiderFactory::IceSpiderFactory(const char * path) : + stylesheet(xsltParseStylesheetFile(BAD_CAST path)) + { + if (!stylesheet) { + throw xmlpp::exception("Failed to load stylesheet"); + } + } + + XsltStreamSerializer::IceSpiderFactory::~IceSpiderFactory() + { + xsltFreeStylesheet(stylesheet); + } + + XsltStreamSerializer * + XsltStreamSerializer::IceSpiderFactory::create(std::ostream & strm) const + { + return new XsltStreamSerializer(strm, stylesheet); + } + + XsltStreamSerializer::XsltStreamSerializer(std::ostream & os, xsltStylesheet * ss) : + Slicer::XmlDocumentSerializer(doc), + strm(os), + doc(nullptr), + stylesheet(ss) + { + } + + XsltStreamSerializer::~XsltStreamSerializer() + { + delete doc; + } + + void + XsltStreamSerializer::Serialize(Slicer::ModelPartPtr mp) + { + Slicer::XmlDocumentSerializer::Serialize(mp); + auto result = xsltApplyStylesheet(stylesheet, doc->cobj(), nullptr); + if (!result) { + throw xmlpp::exception("Failed to apply XSL transform"); + } + xmlOutputBufferPtr buf = xmlOutputBufferCreateIO(xmlstrmwritecallback, xmlstrmclosecallback, &strm, NULL); + if (xmlStrcmp(stylesheet->method, BAD_CAST "html") == 0) { + htmlDocContentDumpFormatOutput(buf, result, (const char *) stylesheet->encoding, 0); + } + else { + xmlNodeDumpOutput(buf, result, result->children, 0, 0, (const char *) stylesheet->encoding); + } + xmlOutputBufferClose(buf); + xmlFreeDoc(result); + } +} + diff --git a/icespider/xslt/xsltStreamSerializer.h b/icespider/xslt/xsltStreamSerializer.h new file mode 100644 index 0000000..d8000d1 --- /dev/null +++ b/icespider/xslt/xsltStreamSerializer.h @@ -0,0 +1,34 @@ +#ifndef ICESPIDER_CORE_XSLTSTREAMSERIALIZER_H +#define ICESPIDER_CORE_XSLTSTREAMSERIALIZER_H + +#include <slicer/xml/serializer.h> +#include <visibility.h> +#include <libxslt/transform.h> + +namespace IceSpider { + class DLL_PUBLIC XsltStreamSerializer : public Slicer::XmlDocumentSerializer { + public: + class IceSpiderFactory : public Slicer::StreamSerializerFactory { + public: + IceSpiderFactory(const char *); + ~IceSpiderFactory(); + + XsltStreamSerializer * create(std::ostream &) const override; + + xsltStylesheet * stylesheet; + }; + + XsltStreamSerializer(std::ostream &, xsltStylesheet *); + ~XsltStreamSerializer(); + + void Serialize(Slicer::ModelPartPtr mp) override; + + protected: + std::ostream & strm; + xmlpp::Document * doc; + xsltStylesheet * stylesheet; + }; +} + +#endif + |