mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-06 05:24:35 +01:00
f610d739fe
Templates are now constructed with their precedence. Variables are too, with a tweak to allow for the immediate evaluation of non-topl-level params and vars. The execution context now no longer needs to track variable precedence, which is good because it will be getting it wrong anyway. Corresponding simplifications follow to compliation context.
94 lines
2.8 KiB
C++
94 lines
2.8 KiB
C++
#ifndef ARABICA_XSLT_VARIABLES_HANDLER_HPP
|
|
#define ARABICA_XSLT_VARIABLES_HANDLER_HPP
|
|
|
|
#include "../xslt_param.hpp"
|
|
#include "../xslt_variable.hpp"
|
|
#include "xslt_item_container_handler.hpp"
|
|
|
|
namespace Arabica
|
|
{
|
|
namespace XSLT
|
|
{
|
|
|
|
template<class VType>
|
|
class VariableHandler : public ItemContainerHandler<VType>
|
|
{
|
|
public:
|
|
VariableHandler(CompilationContext& context) :
|
|
ItemContainerHandler<VType>(context),
|
|
has_select_(false),
|
|
precedence_(Precedence::FrozenPrecedence())
|
|
{
|
|
} // VariableHandler
|
|
|
|
VariableHandler(CompilationContext& context, const Precedence& precedence) :
|
|
ItemContainerHandler<VType>(context),
|
|
has_select_(false),
|
|
precedence_(precedence)
|
|
{
|
|
} // VariableHandler
|
|
|
|
protected:
|
|
virtual VType* createContainer(const std::string& namespaceURI,
|
|
const std::string& localName,
|
|
const std::string& qName,
|
|
const SAX::Attributes<std::string>& atts)
|
|
{
|
|
static const ValueRule rules[] = { { "name", true, 0 },
|
|
{ "select", false, 0 },
|
|
{ 0, false, 0} };
|
|
|
|
|
|
std::map<std::string, std::string> attrs = gatherAttributes(qName, atts, rules);
|
|
|
|
const std::string& select = atts.getValue("select");
|
|
Arabica::XPath::XPathExpressionPtr<std::string> xpath;
|
|
if(select != "")
|
|
{
|
|
xpath = this->context().xpath_expression(select);
|
|
has_select_ = true;
|
|
} // if ...
|
|
|
|
std::pair<std::string, std::string> name = this->context().processInternalQName(attrs["name"]);
|
|
return new VType(name.first, name.second, xpath, precedence_);
|
|
} // createContainer
|
|
|
|
virtual void characters(const std::string& ch)
|
|
{
|
|
if(has_select_)
|
|
{
|
|
for(std::string::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
|
|
if(!Arabica::XML::is_space(*i))
|
|
throw SAX::SAXException("A variable or param can not have both a select attribute and text context");
|
|
}
|
|
ItemContainerHandler<VType>::characters(ch);
|
|
} // characters
|
|
|
|
private:
|
|
bool has_select_;
|
|
const Precedence precedence_;
|
|
}; // class VariableHandler
|
|
|
|
template<class VType>
|
|
class TopLevelVariableHandler : public VariableHandler<VType>
|
|
{
|
|
public:
|
|
TopLevelVariableHandler(CompilationContext& context) :
|
|
VariableHandler<VType>(context, context.precedence())
|
|
{
|
|
} // VariableHandler
|
|
|
|
virtual void endElement(const std::string& namespaceURI,
|
|
const std::string& localName,
|
|
const std::string& qName)
|
|
{
|
|
this->context().stylesheet().add_variable(this->container());
|
|
this->context().pop();
|
|
} // endElement
|
|
|
|
}; // class TopLevelVariableHandler
|
|
|
|
} // namespace XSLT
|
|
} // namespace Arabica
|
|
#endif
|
|
|