From bd39d49464dbd17eb3d4cdbb5784431e43e56fbf Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sun, 29 Jun 2014 20:36:28 +0200 Subject: Switched FunctionWriteFile content parameter to xalan::XalanNode pointer * i.e. "write-file" now supports the serialization of given DOM structures ** this will be needed e.g. if FunctionTransform returns the result as a DOM tree instead of as a plain string ** enables the creation of multiple XML documents from within a single transformation *** i.e. backports the functionality provided in XSLT 2.0 by "xsl:result-document" to xalan's XSLT 1.0 * changed test cases accordingly --- src/function/write_file.cc | 53 ++++++++++++++++++++++++++++++++------- src/function/write_file.h | 4 +-- src/support/type/xobject_value.cc | 30 ++++++++++++++-------- 3 files changed, 66 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/function/write_file.cc b/src/function/write_file.cc index 39495d8..024a87a 100644 --- a/src/function/write_file.cc +++ b/src/function/write_file.cc @@ -1,5 +1,10 @@ #include "write_file.h" +#include +#include +#include +#include + #include #include #include @@ -7,21 +12,47 @@ #include #include +#include "support/xalan_string.h" #include "support/xerces_string_guard.h" #include "support/dom/result_node_facade.h" namespace { -bool writeFile( +bool serializeNodeToFile( const boost::filesystem::path& filePath, - const std::string& content + xalan::XalanNode* const contentNode ) { - boost::filesystem::ofstream file(filePath); + const xalan::XalanNode::NodeType contentType( + contentNode->getNodeType() + ); + + if ( contentType != xalan::XalanNode::DOCUMENT_NODE && + contentType != xalan::XalanNode::ATTRIBUTE_NODE ) { + boost::filesystem::ofstream file(filePath); + + if ( file.is_open() ) { + if ( contentType == xalan::XalanNode::TEXT_NODE ) { + file << InputXSLT::toString(contentNode->getNodeValue()); + } else { + xalan::XalanStdOutputStream outputStream(file); + xalan::XalanOutputStreamPrintWriter outputWriter(outputStream); + + xalan::FormatterToXML formatter(outputWriter); + xalan::FormatterTreeWalker walker(formatter); + + formatter.startDocument(); + + walker.traverseSubtree(contentNode); + + formatter.endDocument(); + } - if ( file.is_open() ) { - file << content << std::endl; + file << std::endl; - return true; + return true; + } else { + return false; + } } else { return false; } @@ -33,7 +64,7 @@ namespace InputXSLT { xercesc::DOMDocument* FunctionWriteFile::constructDocument( boost::filesystem::path filePath, - std::string content + xalan::XalanNode* const contentNode ) { xercesc::DOMDocument* const domDocument( xercesc::DOMImplementation::getImplementation()->createDocument( @@ -50,8 +81,12 @@ xercesc::DOMDocument* FunctionWriteFile::constructDocument( ResultNodeFacade result(domDocument, rootNode, "file"); result.setAttribute("path", filePath.string()); - if ( writeFile(filePath, content) ) { - result.setAttribute("result", "success"); + if ( contentNode != nullptr ) { + if ( serializeNodeToFile(filePath, contentNode) ) { + result.setAttribute("result", "success"); + } else { + result.setAttribute("result", "error"); + } } else { result.setAttribute("result", "error"); } diff --git a/src/function/write_file.h b/src/function/write_file.h index 2260055..5fd9f3e 100644 --- a/src/function/write_file.h +++ b/src/function/write_file.h @@ -8,7 +8,7 @@ namespace InputXSLT { class FunctionWriteFile : public FunctionBase< FunctionWriteFile, boost::filesystem::path, - std::string + xalan::XalanNode* > { public: using FunctionBase::FunctionBase; @@ -18,7 +18,7 @@ class FunctionWriteFile : public FunctionBase< xercesc::DOMDocument* constructDocument( boost::filesystem::path, - std::string + xalan::XalanNode* const ); }; diff --git a/src/support/type/xobject_value.cc b/src/support/type/xobject_value.cc index 46ce53c..a788e8e 100644 --- a/src/support/type/xobject_value.cc +++ b/src/support/type/xobject_value.cc @@ -46,25 +46,35 @@ xalan::XObjectPtr XObjectValue::get( } template <> -xalan::XSLTInputSource XObjectValue::get( +xalan::XalanNode* XObjectValue::get( const xalan::XObjectPtr& ptr) const { switch ( ptr->getType() ) { case xalan::XObject::eObjectType::eTypeNodeSet: { - return xalan::XSLTInputSource( - ptr->nodeset().item(0) - ); + return ptr->nodeset().item(0); } case xalan::XObject::eObjectType::eTypeResultTreeFrag: { - return xalan::XSLTInputSource( - ptr->rtree().getFirstChild() - ); + return ptr->rtree().getFirstChild(); } default: { - return xalan::XSLTInputSource( - this->get(ptr).string().data() - ); + return nullptr; } } } +template <> +xalan::XSLTInputSource XObjectValue::get( + const xalan::XObjectPtr& ptr) const { + xalan::XalanNode* const node( + this->get(ptr) + ); + + if ( node == nullptr ) { + return xalan::XSLTInputSource( + this->get(ptr).string().data() + ); + } else { + return xalan::XSLTInputSource(node); + } +} + } -- cgit v1.2.3