aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerländer2014-04-26 20:06:17 +0200
committerAdrian Kummerländer2014-04-26 20:06:17 +0200
commiteba5513f82f0e1458543e8646db0317d7211cf96 (patch)
tree67b0238322b10d34c5caf45200aae1cbd548a7b0
parent7e7b112e6c00bcce0b339652748079cf7c9f1430 (diff)
downloadInputXSLT-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.xsl25
-rw-r--r--src/function/read_file.cc89
-rw-r--r--src/function/read_file.h2
-rw-r--r--src/support/filesystem_context.cc2
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(