xsl:message can contain an xsl:message - now handled properly

This commit is contained in:
jez 2007-11-11 21:31:10 +00:00
parent 8228130d7a
commit a1c71b3625
2 changed files with 22 additions and 5 deletions

View file

@ -40,7 +40,7 @@ public:
stylesheet_(stylesheet), stylesheet_(stylesheet),
sink_(output.asOutput()), sink_(output.asOutput()),
message_sink_(error_output), message_sink_(error_output),
to_msg_(false) to_msg_(0)
{ {
xpathContext_.setVariableResolver(stack_); xpathContext_.setVariableResolver(stack_);
} // ExecutionContext } // ExecutionContext
@ -65,7 +65,8 @@ public:
{ {
return !to_msg_ ? sink_ : message_sink_.asOutput(); return !to_msg_ ? sink_ : message_sink_.asOutput();
} // sink } // sink
void redirectToMessageSink(bool redirect) { to_msg_ = redirect; } void redirectToMessageSink() { ++to_msg_; }
void revertFromMessageSink() { --to_msg_; }
const Arabica::XPath::ExecutionContext<std::string>& xpathContext() const { return xpathContext_; } const Arabica::XPath::ExecutionContext<std::string>& xpathContext() const { return xpathContext_; }
@ -102,7 +103,7 @@ private:
Arabica::XPath::ExecutionContext<std::string> xpathContext_; Arabica::XPath::ExecutionContext<std::string> xpathContext_;
Output& sink_; Output& sink_;
StreamSink message_sink_; StreamSink message_sink_;
bool to_msg_; int to_msg_;
friend class StackFrame; friend class StackFrame;
friend class ChainStackFrame; friend class ChainStackFrame;

View file

@ -20,9 +20,8 @@ public:
virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const
{ {
context.redirectToMessageSink(true); RedirectionFrame toMessageSink(context);
execute_children(node, context); execute_children(node, context);
context.redirectToMessageSink(false);
if(terminate_) if(terminate_)
throw SAX::SAXException("Stylesheet terminated by xsl:message"); throw SAX::SAXException("Stylesheet terminated by xsl:message");
@ -30,6 +29,23 @@ public:
private: private:
bool terminate_; bool terminate_;
class RedirectionFrame
{
public:
RedirectionFrame(ExecutionContext& context) : context_(context) { context_.redirectToMessageSink(); }
~RedirectionFrame() { context_.revertFromMessageSink(); }
private:
ExecutionContext& context_;
RedirectionFrame();
RedirectionFrame(const RedirectionFrame&);
bool operator=(const RedirectionFrame&);
}; // class RedirectionFrame
}; // class Message }; // class Message
} // namespace XSLT } // namespace XSLT