#ifndef ARABICA_XSLT_VALUE_VALIDATION_HPP #define ARABICA_XSLT_VALUE_VALIDATION_HPP namespace Arabica { namespace XSLT { template struct ValueRule { const string_type name; bool mandatory; const string_type default_value; const string_type* allowed; }; // struct ValueRule template 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 void validateXmlAttribute(const string_type& parentElement, const string_type& name, const string_type& value, std::map& results) { typedef StylesheetConstant SC; results[name] = value; if(name == SC::space) validateValues(parentElement, name, value, SC::DefaultPreserve); } // validateXmlAttribute template void validateAttribute(const string_type& parentElement, const string_type& name, const string_type& value, const ValueRule* rules, std::map& 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(parentElement, name, value, rules->allowed); } // validateAttribute template std::map gatherAttributes(const string_type& parentElement, const SAX::Attributes& atts, const ValueRule* rules) { typedef StylesheetConstant SC; std::map results; for(const ValueRule* 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(parentElement, atts.getLocalName(a), atts.getValue(a), results); // special xml: attributes continue; } if(atts.getURI(a) == string_adaptor::empty_string()) validateAttribute(parentElement, atts.getLocalName(a), atts.getValue(a), rules, results); } return results; } // validateAttributes template 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