diff options
author | Adrian Kummerländer | 2014-04-26 20:06:17 +0200 |
---|---|---|
committer | Adrian Kummerländer | 2014-04-26 20:06:17 +0200 |
commit | eba5513f82f0e1458543e8646db0317d7211cf96 (patch) | |
tree | 67b0238322b10d34c5caf45200aae1cbd548a7b0 | |
parent | 7e7b112e6c00bcce0b339652748079cf7c9f1430 (diff) | |
download | InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.tar InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.tar.gz InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.tar.bz2 InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.tar.lz InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.tar.xz InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.tar.zst InputXSLT-eba5513f82f0e1458543e8646db0317d7211cf96.zip |
Converted external read-file function output into a node set
* A call to _read-file_ now returns a _content_ and _status_ node
** this enables XSL transformations to easily react to io related errors
* fixed bug in path resolution
** boost::filesystem _canonical_ method is throwing and exception when the given path does not exist, this pulled down the whole stack
** replaced call to _canonical_ with call to _absolute_ which does not have this requirement
-rw-r--r-- | dummy/transform.xsl | 25 | ||||
-rw-r--r-- | src/function/read_file.cc | 89 | ||||
-rw-r--r-- | src/function/read_file.h | 2 | ||||
-rw-r--r-- | src/support/filesystem_context.cc | 2 |
4 files changed, 95 insertions, 23 deletions
diff --git a/dummy/transform.xsl b/dummy/transform.xsl index 62d28c2..323ecdb 100644 --- a/dummy/transform.xsl +++ b/dummy/transform.xsl @@ -1,7 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<xsl:stylesheet version="1.0" +<xsl:stylesheet + version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:external="http://ExternalFunction.xalan-c++.xml.apache.org"> + xmlns:external="http://ExternalFunction.xalan-c++.xml.apache.org" +> <xsl:output method="xml" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" @@ -16,24 +18,27 @@ </head> <body> <div id="raw"> - <xsl:value-of select="external:read-file('test.txt')" /> + <xsl:variable name="testFile" select="external:read-file('test.txt')"/> + <xsl:choose> + <xsl:when test="$testFile/self::status = 'successful'"> + <xsl:value-of select="$testFile/self::content"/> + </xsl:when> + <xsl:otherwise> + Failed to read test.txt + </xsl:otherwise> + </xsl:choose> </div> <ul id="xml"> <xsl:for-each select="external:read-xml-file('test.txt')/tester/eintrag"> <li><xsl:value-of select="."/></li> </xsl:for-each> </ul> - <ul id="filelist"> - <xsl:for-each select="external:read-directory('.')[@type='file']"> - <li><xsl:value-of select="."/></li> - </xsl:for-each> - </ul> - <ul id="filelist2"> + <ul id="filelist1"> <xsl:for-each select="external:read-directory('../')[@type='file']"> <li><xsl:value-of select="."/></li> </xsl:for-each> </ul> - <ul id="filelist3"> + <ul id="filelist2"> <xsl:for-each select="external:read-directory('../')[@type='directory']"> <li><xsl:value-of select="."/></li> </xsl:for-each> diff --git a/src/function/read_file.cc b/src/function/read_file.cc index ac6225a..6f02702 100644 --- a/src/function/read_file.cc +++ b/src/function/read_file.cc @@ -1,13 +1,23 @@ #include "read_file.h" +#include <xercesc/dom/DOMDocument.hpp> +#include <xercesc/dom/DOMImplementation.hpp> +#include <xercesc/dom/DOMElement.hpp> +#include <xercesc/dom/DOMText.hpp> +#include <xercesc/util/XMLString.hpp> + #include "boost/filesystem/fstream.hpp" #include <fstream> +#include "support/xerces_string_guard.h" +#include "support/utility.h" + namespace InputXSLT { FunctionReadFile::FunctionReadFile(const FilesystemContext& context): - fs_context_(context) { } + fs_context_(context), + document_cache_(std::make_shared<DomDocumentCache>()) { } xalan::XObjectPtr FunctionReadFile::execute( xalan::XPathExecutionContext& executionContext, @@ -19,22 +29,77 @@ xalan::XObjectPtr FunctionReadFile::execute( this->fs_context_.resolve(argument->str()) ); - if ( boost::filesystem::is_regular_file(filePath) ) { - boost::filesystem::ifstream file(filePath); + DomDocumentCache::item* const cachedDocument( + this->document_cache_->get(xalanToString(argument->str())) + ); - const std::string fileContent( - (std::istreambuf_iterator<char>(file)), - (std::istreambuf_iterator<char>()) + if ( !cachedDocument->isFinalized() ) { + xercesc::DOMDocument* const domDocument( + cachedDocument->getXercesDocument() ); - return executionContext.getXObjectFactory().createString( - xalan::XalanDOMString(fileContent.data()) - ); - } else { - return executionContext.getXObjectFactory().createString( - xalan::XalanDOMString("io error") + xercesc::DOMNode* const rootNode( + domDocument->getDocumentElement() ); + + if ( boost::filesystem::is_regular_file(filePath) ) { + boost::filesystem::ifstream file(filePath); + + const std::string fileContent( + (std::istreambuf_iterator<char>(file)), + (std::istreambuf_iterator<char>()) + ); + + xercesc::DOMElement* const contentNode( + domDocument->createElement(*XercesStringGuard("content")) + ); + + xercesc::DOMText* const contentTextNode( + domDocument->createTextNode( + *XercesStringGuard(fileContent) + ) + ); + + xercesc::DOMElement* const resultNode( + domDocument->createElement(*XercesStringGuard("status")) + ); + + xercesc::DOMText* const resultTextNode( + domDocument->createTextNode( + *XercesStringGuard("successful") + ) + ); + + contentNode->appendChild(contentTextNode); + resultNode->appendChild(resultTextNode); + + rootNode->appendChild(contentNode); + rootNode->appendChild(resultNode); + } else { + xercesc::DOMElement* const resultNode( + domDocument->createElement(*XercesStringGuard("status")) + ); + + xercesc::DOMText* const resultTextNode( + domDocument->createTextNode( + *XercesStringGuard("error") + ) + ); + + resultNode->appendChild(resultTextNode); + rootNode->appendChild(resultNode); + } } + + xalan::XPathExecutionContext::BorrowReturnMutableNodeRefList nodeList( + executionContext + ); + + nodeList->addNodes( + *cachedDocument->getXalanDocument()->getDocumentElement()->getChildNodes() + ); + + return executionContext.getXObjectFactory().createNodeSet(nodeList); } FunctionReadFile* FunctionReadFile::clone( diff --git a/src/function/read_file.h b/src/function/read_file.h index 2d1dedf..6f38e95 100644 --- a/src/function/read_file.h +++ b/src/function/read_file.h @@ -10,6 +10,7 @@ #include "common.h" #include "support/filesystem_context.h" +#include "support/dom/document_cache.h" namespace InputXSLT { @@ -31,6 +32,7 @@ class FunctionReadFile : public xalan::Function { private: const FilesystemContext& fs_context_; + std::shared_ptr<DomDocumentCache> document_cache_; const xalan::XalanDOMString& getError(xalan::XalanDOMString&) const; diff --git a/src/support/filesystem_context.cc b/src/support/filesystem_context.cc index 9ed9bbf..34b8950 100644 --- a/src/support/filesystem_context.cc +++ b/src/support/filesystem_context.cc @@ -9,7 +9,7 @@ FilesystemContext::FilesystemContext(const std::string& path): boost::filesystem::path FilesystemContext::resolve( const std::string& path) const { - return canonical(this->path_ / path); + return absolute(this->path_ / path); } boost::filesystem::path FilesystemContext::resolve( |