mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-09 05:24:58 +01:00
113 lines
4.2 KiB
C++
113 lines
4.2 KiB
C++
#ifndef ARABICA_XSLT_VALUE_VALIDATION_HPP
|
|
#define ARABICA_XSLT_VALUE_VALIDATION_HPP
|
|
|
|
namespace Arabica
|
|
{
|
|
namespace XSLT
|
|
{
|
|
|
|
template<class string_type>
|
|
struct ValueRule
|
|
{
|
|
const string_type name;
|
|
bool mandatory;
|
|
const string_type default_value;
|
|
const string_type* allowed;
|
|
}; // struct ValueRule
|
|
|
|
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[])
|
|
{
|
|
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
|
|
|
|
template<class string_type, class string_adaptor>
|
|
void verifyNoCharacterData(const string_type& ch,
|
|
const string_type& name)
|
|
{
|
|
for(typename string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
|
|
if(!Arabica::XML::is_space(*i))
|
|
throw SAX::SAXException(string_adaptor::asStdString(name) + " element can not contain character data.");
|
|
} // verifyNoCharacterContent
|
|
|
|
} // namespace XSLT
|
|
} // namespace Arabica
|
|
#endif
|
|
|