diff options
author | Adrian Kummerlaender | 2014-07-12 16:15:42 +0200 |
---|---|---|
committer | Adrian Kummerlaender | 2014-07-12 16:15:42 +0200 |
commit | 086779c6d3d40f244b6aafd6d402fd29b921a735 (patch) | |
tree | c606a54c92f9b638797a95437adfe0a6fee05030 /src | |
parent | 141725d681dd69f77e993c3d59d613d1ad7014f9 (diff) | |
download | InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.tar InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.tar.gz InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.tar.bz2 InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.tar.lz InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.tar.xz InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.tar.zst InputXSLT-086779c6d3d40f244b6aafd6d402fd29b921a735.zip |
Implemented external "generate" function
* this function essentially provides the same functionality as FunctionTransform with the addition of directly committing the result to the filesystem
** this is needed if one wants to generate doctype-containing transformations from inside a transformation as "write-file" is not able to infer the doctype of a given xalan::XalanNode pointer
** this is a integral limitation of (at least) XSLT 1.0 as implemented in Apache Xalan
*** a document can of course only have a single document type
*** e.g. we can not include a doctype node in the result tree of FunctionTransform
* implemented test case for FunctionGenerate
* transformation "test.xsl" is shared between the FunctionTransform and FunctionGenerate test cases
* modified README.md accordingly
Diffstat (limited to 'src')
-rw-r--r-- | src/function/base.h | 2 | ||||
-rw-r--r-- | src/function/generate.cc | 71 | ||||
-rw-r--r-- | src/function/generate.h | 32 | ||||
-rw-r--r-- | src/plattform_guard.cc | 7 |
4 files changed, 111 insertions, 1 deletions
diff --git a/src/function/base.h b/src/function/base.h index c3e1fb6..2d1e4c4 100644 --- a/src/function/base.h +++ b/src/function/base.h @@ -93,7 +93,7 @@ class FunctionBase : public xalan::Function { template <std::size_t... Index> inline xalan::XalanDocument* callConstructDocument( const XObjectArgVectorType& parameters, - const xalan::Locator* locator, + const xalan::Locator* locator, Sequence<Index...> ) const { XObjectValue valueGetter( diff --git a/src/function/generate.cc b/src/function/generate.cc new file mode 100644 index 0000000..4ece322 --- /dev/null +++ b/src/function/generate.cc @@ -0,0 +1,71 @@ +#include "generate.h" + +#include <xalanc/PlatformSupport/XalanOutputStreamPrintWriter.hpp> +#include <xalanc/PlatformSupport/XalanStdOutputStream.hpp> +#include <xalanc/XMLSupport/FormatterToXML.hpp> + +#include <boost/filesystem.hpp> +#include <boost/filesystem/fstream.hpp> + +#include "transformer_facade.h" +#include "support/xerces_string_guard.h" +#include "support/dom/result_node_facade.h" +#include "support/error/error_capacitor.h" + +namespace InputXSLT { + +DomDocumentCache::document_ptr FunctionGenerate::constructDocument( + xalan::XSLTInputSource inputSource, + xalan::XSLTInputSource transformationSource, + boost::filesystem::path targetPath +) const { + DomDocumentCache::document_ptr domDocument( + DomDocumentCache::createDocument("content") + ); + + ResultNodeFacade result(domDocument.get(), "generation"); + result.setAttribute("path", targetPath.string()); + + boost::filesystem::ofstream file(targetPath); + + if ( file.is_open() ) { + TransformerFacade transformer(this->include_resolver_); + + try { + xalan::XalanStdOutputStream output(file); + xalan::XalanOutputStreamPrintWriter writer(output); + xalan::FormatterToXML targetFormatter(writer); + + targetFormatter.setDoIndent(true); + + transformer.generate( + inputSource, + transformationSource, + targetFormatter + ); + + result.setAttribute("result", "success"); + } + catch (const ErrorCapacitor::exception& exception) { + result.setAttribute("result", "error"); + + for ( auto&& error : *exception ) { + result.setValueNode("error", error); + } + } + + WarningCapacitor::warning_cache_ptr warnings( + transformer.getCachedWarnings() + ); + + for ( auto&& warning : *warnings ) { + result.setValueNode("warning", warning); + } + } else { + result.setAttribute("result", "error"); + } + + return domDocument; +} + +} diff --git a/src/function/generate.h b/src/function/generate.h new file mode 100644 index 0000000..43f5da1 --- /dev/null +++ b/src/function/generate.h @@ -0,0 +1,32 @@ +#ifndef INPUTXSLT_SRC_FUNCTION_GENERATE_H_ +#define INPUTXSLT_SRC_FUNCTION_GENERATE_H_ + +#include <xalanc/XSLT/XSLTInputSource.hpp> + +#include "base.h" + +namespace InputXSLT { + +class FunctionGenerate : public FunctionBase< + FunctionGenerate, + xalan::XSLTInputSource, + xalan::XSLTInputSource, + boost::filesystem::path +> { + public: + using FunctionBase::FunctionBase; + + protected: + friend FunctionBase; + + DomDocumentCache::document_ptr constructDocument( + xalan::XSLTInputSource, + xalan::XSLTInputSource, + boost::filesystem::path + ) const; + +}; + +} + +#endif // INPUTXSLT_SRC_FUNCTION_GENERATE_H_ diff --git a/src/plattform_guard.cc b/src/plattform_guard.cc index cc3c9c0..5d19e32 100644 --- a/src/plattform_guard.cc +++ b/src/plattform_guard.cc @@ -10,6 +10,7 @@ #include "function/write_file.h" #include "function/read_directory.h" #include "function/transform.h" +#include "function/generate.h" #include "function/external_text_formatter.h" namespace InputXSLT { @@ -49,6 +50,12 @@ PlattformGuard::PlattformGuard(const std::vector<std::string>& path): xalan::XalanTransformer::installExternalFunctionGlobal( customNamespace, + xalan::XalanDOMString("generate"), + InputXSLT::FunctionGenerate(&this->include_resolver_) + ); + + xalan::XalanTransformer::installExternalFunctionGlobal( + customNamespace, xalan::XalanDOMString("external-text-formatter"), InputXSLT::FunctionExternalTextFormatter(&this->include_resolver_) ); |