2007-07-19 19:01:42 +02:00
|
|
|
#ifndef ARABICA_XSLT_CHOOSE_HANDLER_HPP
|
|
|
|
#define ARABICA_XSLT_CHOOSE_HANDLER_HPP
|
|
|
|
|
|
|
|
#include "../xslt_choose.hpp"
|
|
|
|
|
|
|
|
namespace Arabica
|
|
|
|
{
|
|
|
|
namespace XSLT
|
|
|
|
{
|
|
|
|
|
2012-11-04 23:34:40 +01:00
|
|
|
template<class stringT, class adaptorT>
|
|
|
|
class WhenHandler : public ItemContainerHandler<When<stringT, adaptorT> >
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-04 23:34:40 +01:00
|
|
|
public:
|
|
|
|
typedef stringT string_type;
|
|
|
|
typedef adaptorT string_adaptor;
|
|
|
|
|
|
|
|
private:
|
2012-11-03 00:30:39 +01:00
|
|
|
typedef ItemContainerHandler<When<string_type, string_adaptor> > baseT;
|
2012-11-12 22:46:08 +01:00
|
|
|
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
2012-11-15 23:03:42 +01:00
|
|
|
typedef AttributeValidators<string_type, string_adaptor> AV;
|
2007-07-19 19:01:42 +02:00
|
|
|
public:
|
2012-11-02 23:46:11 +01:00
|
|
|
WhenHandler(Choose<string_type, string_adaptor>* choose,
|
|
|
|
CompilationContext<string_type, string_adaptor>& context) :
|
2012-11-03 00:30:39 +01:00
|
|
|
baseT(context),
|
2007-07-19 19:01:42 +02:00
|
|
|
choose_(choose)
|
|
|
|
{
|
|
|
|
} // WhenHandler
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual When<string_type, string_adaptor>* createContainer(const string_type& /* namespaceURI */,
|
|
|
|
const string_type& /* localName */,
|
|
|
|
const string_type& qName,
|
|
|
|
const SAX::Attributes<string_type, string_adaptor>& atts)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-15 23:03:42 +01:00
|
|
|
static const AV rules = AV::rule(SC::test, true);
|
|
|
|
string_type test = rules.gather(qName, atts)[SC::test];
|
2007-07-19 19:01:42 +02:00
|
|
|
|
2012-11-03 00:33:41 +01:00
|
|
|
return new When<string_type, string_adaptor>(baseT::context().xpath_expression(test));
|
2007-07-19 19:01:42 +02:00
|
|
|
} // startElement
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual void endElement(const string_type& /* namespaceURI */,
|
|
|
|
const string_type& /* localName */,
|
|
|
|
const string_type& /* qName */)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-03 00:33:41 +01:00
|
|
|
choose_->add_when(baseT::container());
|
2012-11-03 00:30:39 +01:00
|
|
|
baseT::context().pop();
|
2007-07-19 19:01:42 +02:00
|
|
|
} // endElement
|
|
|
|
|
|
|
|
private:
|
2012-11-02 23:46:11 +01:00
|
|
|
Choose<string_type, string_adaptor>* choose_;
|
2007-07-19 19:01:42 +02:00
|
|
|
}; // class WhenHandler
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class OtherwiseHandler : public ItemContainerHandler<Otherwise<string_type, string_adaptor> >
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-03 00:33:41 +01:00
|
|
|
typedef ItemContainerHandler<Otherwise<string_type, string_adaptor> > baseT;
|
2012-11-12 22:46:08 +01:00
|
|
|
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
2012-11-03 00:33:41 +01:00
|
|
|
|
2007-07-19 19:01:42 +02:00
|
|
|
public:
|
2012-11-02 23:46:11 +01:00
|
|
|
OtherwiseHandler(Choose<string_type, string_adaptor>* choose,
|
|
|
|
CompilationContext<string_type, string_adaptor>& context) :
|
2012-11-03 00:33:41 +01:00
|
|
|
baseT(context),
|
2007-07-19 19:01:42 +02:00
|
|
|
choose_(choose)
|
|
|
|
{
|
|
|
|
} // OtherwiseHandler
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual Otherwise<string_type, string_adaptor>* createContainer(const string_type& /* namespaceURI */,
|
|
|
|
const string_type& /* localName */,
|
|
|
|
const string_type& /* qName */,
|
|
|
|
const SAX::Attributes<string_type, string_adaptor>& atts)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
|
|
|
if(atts.getLength())
|
|
|
|
throw SAX::SAXException("xsl:otherwise may not have any attributes");
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
return new Otherwise<string_type, string_adaptor>();
|
2007-07-19 19:01:42 +02:00
|
|
|
} // createContainer
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual void endElement(const string_type& /* namespaceURI */,
|
|
|
|
const string_type& /* localName */,
|
|
|
|
const string_type& /* qName */)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-03 00:33:41 +01:00
|
|
|
choose_->set_otherwise(baseT::container());
|
|
|
|
baseT::context().pop();
|
2007-07-19 19:01:42 +02:00
|
|
|
} // endElement
|
|
|
|
|
|
|
|
private:
|
2012-11-02 23:46:11 +01:00
|
|
|
Choose<string_type, string_adaptor>* choose_;
|
2007-07-19 19:01:42 +02:00
|
|
|
}; // class OtherwiseHandler
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class ChooseHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-12 22:46:08 +01:00
|
|
|
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
2007-07-19 19:01:42 +02:00
|
|
|
public:
|
2012-11-02 23:46:11 +01:00
|
|
|
ChooseHandler(CompilationContext<string_type, string_adaptor>& context) :
|
2007-07-19 19:01:42 +02:00
|
|
|
context_(context),
|
|
|
|
choose_(0),
|
2007-11-16 23:03:47 +01:00
|
|
|
seenWhere_(false),
|
2007-07-19 19:01:42 +02:00
|
|
|
seenOtherwise_(false)
|
|
|
|
{
|
|
|
|
} // ChooseHandler
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual void startElement(const string_type& namespaceURI,
|
|
|
|
const string_type& localName,
|
|
|
|
const string_type& qName,
|
|
|
|
const SAX::Attributes<string_type, string_adaptor>& atts)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
|
|
|
if(!choose_)
|
|
|
|
{
|
|
|
|
if(atts.getLength() != 0)
|
|
|
|
throw SAX::SAXException("xsl:choose can not have attributes");
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
choose_ = new Choose<string_type, string_adaptor>();
|
2007-07-19 19:01:42 +02:00
|
|
|
return;
|
|
|
|
} // if ...
|
|
|
|
|
2012-11-12 22:46:08 +01:00
|
|
|
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-12 22:46:08 +01:00
|
|
|
if(localName == SC::when)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2007-11-16 23:03:47 +01:00
|
|
|
seenWhere_ = true;
|
2007-07-19 19:01:42 +02:00
|
|
|
if(seenOtherwise_)
|
|
|
|
throw SAX::SAXException("xsl:otherwise must be the last element in an xsl:choose");
|
|
|
|
|
|
|
|
context_.push(0,
|
2012-11-02 23:46:11 +01:00
|
|
|
new WhenHandler<string_type, string_adaptor>(choose_, context_),
|
2007-07-19 19:01:42 +02:00
|
|
|
namespaceURI,
|
|
|
|
localName,
|
2009-04-24 20:02:14 +02:00
|
|
|
qName,
|
2007-07-19 19:01:42 +02:00
|
|
|
atts);
|
|
|
|
return;
|
|
|
|
} // if(localName == "when")
|
|
|
|
|
2012-11-12 22:46:08 +01:00
|
|
|
if(localName == SC::otherwise)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2007-11-16 23:03:47 +01:00
|
|
|
if(seenOtherwise_)
|
|
|
|
throw SAX::SAXException("xsl:choose may only have one xsl:otherwise element");
|
2007-07-19 19:01:42 +02:00
|
|
|
seenOtherwise_ = true;
|
|
|
|
context_.push(0,
|
2012-11-02 23:46:11 +01:00
|
|
|
new OtherwiseHandler<string_type, string_adaptor>(choose_, context_),
|
2007-07-19 19:01:42 +02:00
|
|
|
namespaceURI,
|
|
|
|
localName,
|
2009-04-24 20:02:14 +02:00
|
|
|
qName,
|
2007-07-19 19:01:42 +02:00
|
|
|
atts);
|
|
|
|
return;
|
|
|
|
} // if(localName == "otherwise")
|
|
|
|
} // if ...
|
2012-11-12 22:46:08 +01:00
|
|
|
throw SAX::SAXException("xsl:choose can not contain " + string_adaptor::asStdString(qName) + ". Only xsl:when and xsl:otherwise are allowed");
|
2007-07-19 19:01:42 +02:00
|
|
|
} // startElement
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual void endElement(const string_type& /* namespaceURI */,
|
|
|
|
const string_type& /* localName */,
|
|
|
|
const string_type& /* qName */)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2007-11-16 23:03:47 +01:00
|
|
|
if(!seenWhere_)
|
|
|
|
throw SAX::SAXException("xsl:choose must contain at least one xsl:where element");
|
2007-07-19 19:01:42 +02:00
|
|
|
context_.parentContainer().add_item(choose_);
|
|
|
|
context_.pop();
|
|
|
|
} // endElement
|
|
|
|
|
2012-11-02 23:46:11 +01:00
|
|
|
virtual void characters(const string_type& ch)
|
2007-07-19 19:01:42 +02:00
|
|
|
{
|
2012-11-12 22:46:08 +01:00
|
|
|
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::choose);
|
2007-07-19 19:01:42 +02:00
|
|
|
} // characters
|
|
|
|
|
|
|
|
private:
|
2012-11-02 23:46:11 +01:00
|
|
|
CompilationContext<string_type, string_adaptor>& context_;
|
|
|
|
Choose<string_type, string_adaptor>* choose_;
|
2007-11-16 23:03:47 +01:00
|
|
|
bool seenWhere_;
|
2007-07-19 19:01:42 +02:00
|
|
|
bool seenOtherwise_;
|
|
|
|
}; // class ChooseHandler
|
|
|
|
|
|
|
|
} // namespace XSLT
|
|
|
|
} // namespace Arabica
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|