All done. Compiles and runs again.

This commit is contained in:
Jez Higgins 2012-11-15 22:03:42 +00:00
parent 5043f5bd4d
commit 5ebb3f02b0
22 changed files with 180 additions and 196 deletions

View file

@ -14,6 +14,7 @@ template<class stringT, class adaptorT>
class ApplyTemplatesHandler : public SAX::DefaultHandler<stringT, adaptorT>
{
typedef StylesheetConstant<stringT, adaptorT> SC;
typedef AttributeValidators<stringT, adaptorT> AV;
public:
typedef stringT string_type;
@ -32,10 +33,10 @@ public:
{
if(applyTemplates_ == 0)
{
static const ValueRule<string_type> rules[] = { { SC::select, false, 0, 0 },
{ SC::mode, false, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0} };
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
static const AV rules = AV::rule(SC::select, false)
.rule(SC::mode, false);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
const string_type& select = attrs[SC::select];
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> xpath;

View file

@ -14,6 +14,7 @@ class AttributeHandler : public ItemContainerHandler<Attribute<string_type, stri
{
typedef ItemContainerHandler<Attribute<string_type, string_adaptor> > baseT;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
AttributeHandler(CompilationContext<string_type, string_adaptor>& context) :
baseT(context)
@ -26,11 +27,10 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
{ SC::namespace_, false, string_adaptor::empty_string(), 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
static const AV rules = AV::rule(SC::name, true)
.rule(SC::namespace_, false, string_adaptor::empty_string());
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> name =
baseT::context().xpath_attribute_value_template(attrs[SC::name]);

View file

@ -13,6 +13,7 @@ template<class stringT, class adaptorT>
class CallTemplateHandler : public SAX::DefaultHandler<stringT, adaptorT>
{
typedef StylesheetConstant<stringT, adaptorT> SC;
typedef AttributeValidators<stringT, adaptorT> AV;
public:
typedef stringT string_type;
typedef adaptorT string_adaptor;
@ -30,10 +31,9 @@ public:
{
if(callTemplate_ == 0)
{
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
static const AV rules = AV::rule(SC::name, true);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
string_type name = context_.processInternalQName(attrs[SC::name]).clarkName();

View file

@ -18,7 +18,7 @@ public:
private:
typedef ItemContainerHandler<When<string_type, string_adaptor> > baseT;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
WhenHandler(Choose<string_type, string_adaptor>* choose,
CompilationContext<string_type, string_adaptor>& context) :
@ -32,9 +32,8 @@ public:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::test, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
string_type test = gatherAttributes(qName, atts, rules)[SC::test];
static const AV rules = AV::rule(SC::test, true);
string_type test = rules.gather(qName, atts)[SC::test];
return new When<string_type, string_adaptor>(baseT::context().xpath_expression(test));
} // startElement

View file

@ -12,6 +12,7 @@ template<class string_type, class string_adaptor>
class CopyHandler : public ItemContainerHandler<Copy<string_type, string_adaptor> >
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
CopyHandler(CompilationContext<string_type, string_adaptor>& context) :
ItemContainerHandler<Copy<string_type, string_adaptor> >(context)
@ -23,9 +24,8 @@ public:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::use_attribute_sets, false, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
string_type sets = gatherAttributes(qName, atts, rules)[SC::use_attribute_sets];
static const AV rules = AV::rule(SC::use_attribute_sets, false);
string_type sets = rules.gather(qName, atts)[SC::use_attribute_sets];
return new Copy<string_type, string_adaptor>(sets);
} // createContainer
@ -35,6 +35,7 @@ template<class string_type, class string_adaptor>
class CopyOfHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
CopyOfHandler(CompilationContext<string_type, string_adaptor>& context) :
context_(context),
@ -49,9 +50,8 @@ public:
{
if(copyOf_ == 0)
{
static const ValueRule<string_type> rules[] = { { SC::select, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
string_type select = gatherAttributes(qName, atts, rules)[SC::select];
static const AV rules = AV::rule(SC::select, true);
string_type select = rules.gather(qName, atts)[SC::select];
copyOf_ = new CopyOf<string_type, string_adaptor>(context_.xpath_expression(select));

View file

@ -14,6 +14,7 @@ class ElementHandler : public ItemContainerHandler<Element<string_type, string_a
{
typedef ItemContainerHandler<Element<string_type, string_adaptor> > baseT;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
ElementHandler(CompilationContext<string_type, string_adaptor>& context) :
ItemContainerHandler<Element<string_type, string_adaptor> >(context)
@ -26,12 +27,11 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
{ SC::namespace_, false, string_adaptor::empty_string(), 0 },
{ SC::use_attribute_sets, false, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
static const AV rules = AV::rule(SC::name, true)
.rule(SC::namespace_, false, string_adaptor::empty_string())
.rule(SC::use_attribute_sets, false);
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> name =
baseT::context().xpath_attribute_value_template(attrs[SC::name]);

View file

@ -14,6 +14,7 @@ template<class string_type, class string_adaptor>
class ForEachHandler : public ItemContainerHandler<ForEach<string_type, string_adaptor> >
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
typedef ItemContainerHandler<ForEach<string_type, string_adaptor> > baseT;
public:
@ -29,9 +30,8 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::select, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
string_type select = gatherAttributes(qName, atts, rules)[SC::select];
static const AV rules = AV::rule(SC::select, true);
string_type select = rules.gather(qName, atts)[SC::select];
return new ForEach<string_type, string_adaptor>(baseT::context().xpath_expression(select));
} // createContainer

View file

@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
class IfHandler : public ItemContainerHandler<If<string_type, string_adaptor> >
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
IfHandler(CompilationContext<string_type, string_adaptor>& context) :
ItemContainerHandler<If<string_type, string_adaptor> >(context)
@ -24,9 +25,8 @@ public:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::test, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
string_type test = gatherAttributes(qName, atts, rules)[SC::test];
static const AV rules = AV::rule(SC::test, true);
string_type test = rules.gather(qName, atts)[SC::test];
return new If<string_type, string_adaptor>(ItemContainerHandler<If<string_type, string_adaptor> >::context().xpath_expression(test));
} // startElement

View file

@ -15,6 +15,7 @@ class IncludeHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
struct ImportHref;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
IncludeHandler() :
@ -122,9 +123,8 @@ public:
private:
string_type validate_href(const string_type& qName, const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::href, true, 0, 0 },
{ 0, false, 0, 0 } };
string_type href = gatherAttributes(qName, atts, rules)[SC::href];
static const AV rules = AV::rule(SC::href, true);
string_type href = rules.gather(qName, atts)[SC::href];
no_content_ = true;
// std::cout << "Base : " << context_->currentBase() << ", href : " << href << "\n";
return context_->makeAbsolute(href);

View file

@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
class KeyHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
typedef typename Key<string_type, string_adaptor>::MatchExprList MatchExprList;
public:
KeyHandler(CompilationContext<string_type, string_adaptor>& context) :
@ -29,12 +30,11 @@ public:
if(key_ != 0)
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
{ SC::match, true, 0, 0 },
{ SC::use, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
static const AV rules = AV::rule(SC::name, true)
.rule(SC::match, true)
.rule(SC::use, true);
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
name_ = context_.processInternalQName(attrs[SC::name]).clarkName();
try
{

View file

@ -14,6 +14,7 @@ class MessageHandler : public ItemContainerHandler<Message<string_type, string_a
{
typedef ItemContainerHandler<Message<string_type, string_adaptor> > baseT;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
MessageHandler(CompilationContext<string_type, string_adaptor>& context) :
baseT(context)
@ -26,9 +27,8 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::terminate, false, SC::no, SC::AllowedYesNo },
{ string_adaptor::empty_string(), false, 0, 0 } };
return new Message<string_type, string_adaptor>(gatherAttributes(qName, atts, rules)[SC::terminate] == SC::yes);
static const AV rules = AV::rule(SC::terminate, false, SC::no, AllowedValues<string_type>(SC::yes, SC::no));
return new Message<string_type, string_adaptor>(rules.gather(qName, atts)[SC::terminate] == SC::yes);
} // createContainer
}; // class MessageHandler

View file

@ -14,6 +14,7 @@ template<class string_type, class string_adaptor>
class NamespaceAliasHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
NamespaceAliasHandler(CompilationContext<string_type, string_adaptor>& context) :
@ -29,11 +30,10 @@ public:
{
if(!done_)
{
static const ValueRule<string_type> rules[] = { { SC::stylesheet_prefix, true, 0, 0 },
{ SC::result_prefix, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
static const AV rules = AV::rule(SC::stylesheet_prefix, true)
.rule(SC::result_prefix, true);
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
string_type stylesheet_prefix = attrs[SC::stylesheet_prefix];
string_type result_prefix = attrs[SC::result_prefix];

View file

@ -10,6 +10,7 @@ template<class string_type, class string_adaptor>
class OutputHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
OutputHandler(CompilationContext<string_type, string_adaptor>& context) :
@ -24,20 +25,18 @@ public:
{
if(settings_.empty())
{
static string_type AllowedMethods[] = { SC::xml, SC::html, SC::text, string_adaptor::empty_string() };
static const ValueRule<string_type> rules[] =
{ { SC::method, false, SC::xml, AllowedMethods },
{ SC::version, false, SC::Version, 0 },
{ SC::encoding, false, SC::utf8, 0 },
{ SC::omit_xml_declaration, false, SC::no, SC::AllowedYesNo },
{ SC::standalone, false, string_adaptor::empty_string(), SC::AllowedYesNo },
{ SC::doctype_public, false, string_adaptor::empty_string(), 0 },
{ SC::doctype_system, false, string_adaptor::empty_string(), 0 },
{ SC::cdata_section_elements, false, string_adaptor::empty_string(), 0 },
{ SC::indent, false, SC::no, SC::AllowedYesNo },
{ SC::media_type, false, string_adaptor::empty_string(), 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
settings_ = gatherAttributes(qName, atts, rules);
static const AV rules = AV::rule(SC::method, false, SC::xml, AllowedValues<string_type>(SC::xml, SC::html, SC::text))
.rule(SC::version, false, SC::Version)
.rule(SC::encoding, false, SC::utf8)
.rule(SC::omit_xml_declaration, false, SC::no, AllowedValues<string_type>(SC::yes, SC::no))
.rule(SC::standalone, false, string_adaptor::empty_string(), AllowedValues<string_type>(SC::yes, SC::no))
.rule(SC::doctype_public, false, string_adaptor::empty_string())
.rule(SC::doctype_system, false, string_adaptor::empty_string())
.rule(SC::cdata_section_elements, false, string_adaptor::empty_string())
.rule(SC::indent, false, SC::no, AllowedValues<string_type>(SC::yes, SC::no))
.rule(SC::media_type, false, string_adaptor::empty_string());
settings_ = rules.gather(qName, atts);
cdataElements_ = extractCDATAElements(settings_[SC::cdata_section_elements]);
return;

View file

@ -14,6 +14,7 @@ class ProcessingInstructionHandler : public ItemContainerHandler<ProcessingInstr
{
typedef ItemContainerHandler<ProcessingInstruction<string_type, string_adaptor> > baseT;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
ProcessingInstructionHandler(CompilationContext<string_type, string_adaptor>& context) :
@ -26,9 +27,8 @@ public:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0} };
string_type name = gatherAttributes(qName, atts, rules)[SC::name];
static const AV rules = AV::rule(SC::name, true);
string_type name = rules.gather(qName, atts)[SC::name];
return new ProcessingInstruction<string_type, string_adaptor>(baseT::context().xpath_attribute_value_template(name));
} // createContainer

View file

@ -12,7 +12,7 @@ template<class string_type, class string_adaptor>
class SortHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
SortHandler(CompilationContext<string_type, string_adaptor>& context,
Sortable<string_type, string_adaptor>& sortee) :
@ -29,14 +29,13 @@ public:
{
if(sort_ == 0)
{
static const ValueRule<string_type> rules[] = { { SC::select, false, SC::current_xpath, 0 },
{ SC::lang, false, 0, 0 },
{ SC::data_type, false, SC::text, 0 },
{ SC::order, false, SC::ascending, 0 },
{ SC::case_order, false, SC::upper_first, 0 },
{ 0, false, 0, 0 } };
static const AV rules = AV::rule(SC::select, false, SC::current_xpath)
.rule(SC::lang, false)
.rule(SC::data_type, false, SC::text)
.rule(SC::order, false, SC::ascending)
.rule(SC::case_order, false, SC::upper_first);
std::map<string_type, string_type> attr = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attr = rules.gather(qName, atts);
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select, lang, datatype, order, caseorder;
select = context_.xpath_expression(attr[SC::select]);

View file

@ -14,6 +14,7 @@ class TemplateHandler : public ItemContainerHandler<Template<string_type, string
{
typedef ItemContainerHandler<Template<string_type, string_adaptor> > baseT;
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
TemplateHandler(CompilationContext<string_type, string_adaptor>& context) :
baseT(context),
@ -42,12 +43,11 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::match, false, 0, 0 },
{ SC::mode, false, 0, 0 },
{ SC::name, false, 0, 0 },
{ SC::priority, false, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
std::map<string_type, string_type> attributes = gatherAttributes(qName, atts, rules);
static const AV rules = AV::rule(SC::match, false)
.rule(SC::mode, false)
.rule(SC::name, false)
.rule(SC::priority, false);
std::map<string_type, string_type> attributes = rules.gather(qName, atts);
const string_type& match = attributes[SC::match];
if((match == string_adaptor::empty_string()) && (attributes[SC::name] == string_adaptor::empty_string()))

View file

@ -12,7 +12,7 @@ template<class string_type, class string_adaptor>
class TextHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
TextHandler(CompilationContext<string_type, string_adaptor>& context) :
context_(context),
@ -27,9 +27,8 @@ public:
{
if(text_ == 0)
{
static const ValueRule<string_type> rules[] = { { SC::disable_output_escaping, false, SC::no, SC::AllowedYesNo },
{ string_adaptor::empty_string(), false, 0, 0 } };
text_ = new Text<string_type, string_adaptor>(gatherAttributes(qName, atts, rules)[SC::disable_output_escaping] == SC::yes);
static const AV rules = AV::rule(SC::disable_output_escaping, false, SC::no, AllowedValues<string_type>(SC::yes, SC::no));
text_ = new Text<string_type, string_adaptor>(rules.gather(qName, atts)[SC::disable_output_escaping] == SC::yes);
return;
} // if(text_ == 0)

View file

@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
class ValueOfHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
ValueOfHandler(CompilationContext<string_type, string_adaptor>& context) :
context_(context),
@ -27,11 +28,10 @@ public:
{
if(valueOf_ == 0)
{
static const ValueRule<string_type> rules[] = { { SC::select, true, 0, 0 },
{ SC::disable_output_escaping, false, SC::no, SC::AllowedYesNo },
{ 0, false, 0, 0 } };
static const AV rules = AV::rule(SC::select, true)
.rule(SC::disable_output_escaping, false, SC::no, AllowedValues<string_type>(SC::yes, SC::no));
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
valueOf_ = new ValueOf<string_type, string_adaptor>(context_.xpath_expression(attrs[SC::select]),
attrs[SC::disable_output_escaping] == SC::yes);
return;

View file

@ -23,6 +23,13 @@ public:
allowed_.insert(v2);
} // AllowedValues
AllowedValues(const string_type& v1, const string_type& v2, const string_type& v3)
{
allowed_.insert(v1);
allowed_.insert(v2);
allowed_.insert(v3);
} // AllowedValues
AllowedValues(const AllowedValues& rhs) :
allowed_(rhs.allowed_)
{
@ -45,46 +52,70 @@ private:
std::set<string_type> allowed_;
}; // AllowedValues
template<class string_type>
AllowedValues<string_type> makeAllowedValues(const string_type& a1, const string_type& a2)
{
return AllowedValues<string_type>(a1, a2);
} // makeAllowedValues
template<class string_type>
AllowedValues<string_type> makeAllowedValues(const string_type& a1, const string_type& a2, const string_type& a3)
{
return AllowedValues<string_type>(a1, a2, a3);
} // makeAllowedValues
template<class string_type, class string_adaptor>
class AttributeValidator
{
public:
AttributeValidator() :
required_(false)
required_(false),
has_def_(false)
{
} // AttributeValidator
bool mandatory() const { return required_; }
bool has_default() const { return !def_.empty(); }
bool has_default() const { return has_def_; }
const string_type& default_value() const { return def_; }
bool is_allowed(const string_type& v) const { return allowed_.is_allowed(v); }
private:
explicit AttributeValidator(bool required) :
required_(required)
required_(required),
has_def_(false)
{
} // AttributeValidator
AttributeValidator(bool required, const string_type& def) :
required_(required),
def_(def),
has_def_(true)
{
} // AttributeValidator
AttributeValidator(bool required, const string_type& def, const AllowedValues<string_type> allowed) :
required_(required),
def_(def),
has_def_(true),
allowed_(allowed)
{
} // AttributeValidator
bool required_;
bool has_def_;
string_type def_;
AllowedValues<string_type> allowed_;
AttributeValidator& operator=(const AttributeValidator& rhs)
{
required_ = rhs.required_;
has_def_ = rhs.has_def_;
def_ = rhs.def_;
allowed_ = rhs.allowed_;
return *this;
} // operator=
friend class AttributeValidators<string_type, string_adaptor>;
friend class AttributeValidatorsBuilder<string_type, string_adaptor>;
}; // class AttributeValidator
template<class string_type, class string_adaptor>
@ -94,6 +125,13 @@ class AttributeValidators
public:
static AttributeValidatorsBuilder<string_type, string_adaptor> rule(const string_type& name, bool required);
static AttributeValidatorsBuilder<string_type, string_adaptor> rule(const string_type& name,
bool required,
const string_type& def);
static AttributeValidatorsBuilder<string_type, string_adaptor> rule(const string_type& name,
bool required,
const string_type& def,
const AllowedValues<string_type>& allowed);
std::map<string_type, string_type> gather(const string_type& parentElement,
const SAX::Attributes<string_type, string_adaptor>& atts) const
@ -164,13 +202,13 @@ private:
throw SAX::SAXException(string_adaptor::asStdString(value) +
" is not an allowed value for " +
string_adaptor::asStdString(parentElement) +
"/@ " +
"/@" +
string_adaptor::asStdString(name));
} // validateValues
void put(const string_type& name, bool required)
void put(const string_type& name, const AttributeValidator<string_type, string_adaptor>& av)
{
rules_[name] = AttributeValidator<string_type, string_adaptor>(required);
rules_[name] = av;
} // put
AttributeValidators() { }
@ -200,7 +238,17 @@ public:
AttributeValidatorsBuilder& rule(const string_type& name, bool required)
{
validators_.put(name, required);
validators_.put(name, AttributeValidator<string_type, string_adaptor>(required));
return *this;
} // rule
AttributeValidatorsBuilder& rule(const string_type& name, bool required, const string_type& def)
{
validators_.put(name, AttributeValidator<string_type, string_adaptor>(required, def));
return *this;
} // rule
AttributeValidatorsBuilder& rule(const string_type& name, bool required, const string_type& def, const AllowedValues<string_type>& av)
{
validators_.put(name, AttributeValidator<string_type, string_adaptor>(required, def, av));
return *this;
} // rule
@ -225,99 +273,28 @@ AttributeValidatorsBuilder<string_type, string_adaptor>
return builder;
} // AttributeValidator::rule
////
template<class string_type>
struct ValueRule
template<class string_type, class string_adaptor>
AttributeValidatorsBuilder<string_type, string_adaptor>
AttributeValidators<string_type, string_adaptor>::rule(const string_type& name,
bool required,
const string_type& def)
{
const string_type name;
bool mandatory;
const string_type default_value;
const string_type* allowed;
}; // struct ValueRule
AttributeValidatorsBuilder<string_type, string_adaptor> builder;
builder.rule(name, required, def);
return builder;
} // AttributeValidator::rule
template<class string_type, class string_adaptor>
void validateValues(const string_type& parentElement,
const string_type& name,
const string_type& value,
const string_type allowed[])
AttributeValidatorsBuilder<string_type, string_adaptor>
AttributeValidators<string_type, string_adaptor>::rule(const string_type& name,
bool required,
const string_type& def,
const AllowedValues<string_type>& allowed)
{
for(const string_type* a = allowed; *a != string_adaptor::empty_string(); ++a)
if(value == *a)
return;
std::ostringstream os;
os << string_adaptor::asStdString(parentElement) + ": " + string_adaptor::asStdString(name) + " may be one of ";
while(*allowed != string_adaptor::empty_string())
os << '\'' << string_adaptor::asStdString(*allowed++) << "' ";
throw SAX::SAXException(os.str());
} // validateValues
template<class string_type, class string_adaptor>
void validateXmlAttribute(const string_type& parentElement,
const string_type& name,
const string_type& value,
std::map<string_type, string_type>& results)
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
results[name] = value;
if(name == SC::space)
validateValues<string_type, string_adaptor>(parentElement, name, value, SC::DefaultPreserve);
} // validateXmlAttribute
template<class string_type, class string_adaptor>
void validateAttribute(const string_type& parentElement,
const string_type& name,
const string_type& value,
const ValueRule<string_type>* rules,
std::map<string_type, string_type>& results)
{
while((rules->name != string_adaptor::empty_string()) && (name != rules->name))
++rules;
if(rules->name == string_adaptor::empty_string())
throw SAX::SAXException(string_adaptor::asStdString(parentElement) + ": Illegal attribute " + string_adaptor::asStdString(name));
results[name] = value;
if(rules->allowed != 0)
validateValues<string_type, string_adaptor>(parentElement, name, value, rules->allowed);
} // validateAttribute
template<class string_type, class string_adaptor>
std::map<string_type, string_type> gatherAttributes(const string_type& parentElement,
const SAX::Attributes<string_type, string_adaptor>& atts,
const ValueRule<string_type>* rules)
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
std::map<string_type, string_type> results;
for(const ValueRule<string_type>* r = rules ; r->name != string_adaptor::empty_string(); ++r)
{
if((r->mandatory) && (atts.getValue(r->name).empty()))
throw SAX::SAXException(string_adaptor::asStdString(parentElement) + ": Attribute " + string_adaptor::asStdString(r->name) + " must be specified");
if(r->default_value != string_adaptor::empty_string())
results[r->name] = r->default_value;
} //
for(int a = 0; a < atts.getLength(); ++a)
{
if(atts.getLocalName(a) == string_adaptor::empty_string())
continue; // namespace decl
if(atts.getURI(a) == SC::xml_uri)
{
validateXmlAttribute<string_type, string_adaptor>(parentElement, atts.getLocalName(a), atts.getValue(a), results); // special xml: attributes
continue;
}
if(atts.getURI(a) == string_adaptor::empty_string())
validateAttribute<string_type, string_adaptor>(parentElement, atts.getLocalName(a), atts.getValue(a), rules, results);
}
return results;
} // validateAttributes
AttributeValidatorsBuilder<string_type, string_adaptor> builder;
builder.rule(name, required, def, allowed);
return builder;
} // AttributeValidator::rule
template<class string_type, class string_adaptor>
void verifyNoCharacterData(const string_type& ch,

View file

@ -14,6 +14,7 @@ template<class VType>
class VariableHandler : public ItemContainerHandler<VType>
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
typedef AttributeValidators<string_type, string_adaptor> AV;
public:
typedef typename VType::string_type string_type;
typedef typename VType::string_adaptor string_adaptor;
@ -39,12 +40,10 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
{ SC::select, false, 0, 0 },
{ string_adaptor::empty_string(), false, 0, 0 } };
static const AV rules = AV::rule(SC::name, true)
.rule(SC::select, false);
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = rules.gather(qName, atts);
const string_type& select = atts.getValue(SC::select);
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> xpath;

View file

@ -42,12 +42,12 @@ public:
const string_type order = order_->evaluateAsString(node, context_->xpathContext());
const string_type caseorder = caseorder_->evaluateAsString(node, context_->xpathContext());
static string_type allowed_datatypes[] = { SC::text, SC::number, string_adaptor::empty_string() };
static string_type allowed_orders[] = { SC::ascending, SC::descending, string_adaptor::empty_string() };
static string_type allowed_case_orders[] = { SC::upper_first, SC::lower_first, string_adaptor::empty_string() };
validateValues<string_type, string_adaptor>(SC::sort, SC::data_type, datatype, allowed_datatypes);
validateValues<string_type, string_adaptor>(SC::sort, SC::order, order, allowed_orders);
validateValues<string_type, string_adaptor>(SC::sort, SC::case_order, caseorder, allowed_case_orders);
static AllowedValues<string_type> allowed_datatypes = makeAllowedValues(SC::text, SC::number);
static AllowedValues<string_type> allowed_orders = makeAllowedValues(SC::ascending, SC::descending);
static AllowedValues<string_type> allowed_case_orders = makeAllowedValues(SC::upper_first, SC::lower_first);
validate(SC::data_type, allowed_datatypes, datatype);
validate(SC::order, allowed_orders, order);
validate(SC::case_order, allowed_case_orders, caseorder);
if(datatype == SC::number)
if(order == SC::ascending)
@ -78,6 +78,17 @@ public:
} // add_sub_sort
private:
void validate(const string_type& name, const AllowedValues<string_type>& allowed, const string_type& value)
{
if(allowed.is_allowed(value))
return;
throw SAX::SAXException(string_adaptor::asStdString(value) +
" is not an allowed value for xsl:sort/@" +
string_adaptor::asStdString(name));
} // validate
typedef bool(Sort::*sortFn)(const DOMNode& n1, const DOMNode& n2) const;
bool numberAscending(const DOMNode& n1, const DOMNode& n2) const
{

View file

@ -51,8 +51,8 @@ int main(int argc, const char* argv[])
Loader loader;
//add_tests(runner, loader, tests_to_run, xalan_tests);
//add_tests(runner, loader, tests_to_run, msft_tests);
add_tests(runner, loader, tests_to_run, xalan_tests);
add_tests(runner, loader, tests_to_run, msft_tests);
add_arabica_tests(runner, loader, tests_to_run, arabica_tests);
runner.run(argc, argv);