#include #include #include #include #include #include #include "xmlshallowvalidator.h" XmlShallowValidator::XmlShallowValidator( std::map > &elementMap, std::map > > &attributeMap, std::map > &requiredAttributeMap, std::set &entitySet, int maxLine, bool segmentOnly) : vd(new XmlShallowValidatorData()) { vd->elementMap = elementMap; vd->attributeMap = attributeMap; vd->requiredAttributeMap = requiredAttributeMap; vd->entitySet = entitySet; vd->isValid = true; vd->p = p; vd->depth = 0; vd->maxLine = maxLine; vd->segmentOnly = segmentOnly; vd->overrideFailure = false; XML_SetUserData(p, vd.get()); XML_SetElementHandler(p, start, end); XML_SetSkippedEntityHandler(p, skippedentity); } XmlShallowValidator::~XmlShallowValidator() { } void XMLCALL XmlShallowValidator::start(void *data, const XML_Char *el, const XML_Char **attr) { XmlShallowValidatorData *vd; vd = (XmlShallowValidatorData *)data; #ifdef __WXMSW__ if (XML_GetCurrentLineNumber(vd->p) > (unsigned)(vd->maxLine + 1)) #else if (XML_GetCurrentLineNumber(vd->p) > (vd->maxLine + 1)) #endif { XML_StopParser(vd->p, true); } vd->push(el); ++(vd->depth); //check element ok std::string parent = vd->getParent(); if (parent.empty()) return; if (vd->elementMap.empty()) return; if (!vd->elementMap[parent].count(vd->getElement())) { vd->isValid = false; vd->positionVector.push_back( make_pair(XML_GetCurrentLineNumber(vd->p), XML_GetCurrentColumnNumber(vd->p))); } std::map > attributeMap; size_t requiredAttributeCount = vd->requiredAttributeMap[el].size(); std::string currentAttribute; while (*attr) { attributeMap = vd->attributeMap[el]; // check for existence if (!attributeMap.count(*attr)) { vd->isValid = false; vd->positionVector.push_back(make_pair( XML_GetCurrentLineNumber(vd->p), XML_GetCurrentColumnNumber(vd->p))); } // check for requirement currentAttribute = (const char *)*attr; if (vd->requiredAttributeMap[el].find(currentAttribute) != vd->requiredAttributeMap[el].end()) --requiredAttributeCount; attr += 2; } if (requiredAttributeCount != 0) { vd->isValid = false; vd->positionVector.push_back(make_pair( XML_GetCurrentLineNumber(vd->p), XML_GetCurrentColumnNumber(vd->p))); } } void XMLCALL XmlShallowValidator::end(void *data, const XML_Char *el) { XmlShallowValidatorData *vd; vd = (XmlShallowValidatorData *)data; vd->pop(); --(vd->depth); // segments: stop at end tag of first element if (vd->segmentOnly && vd->depth == 0) { XML_StopParser(vd->p, true); if (vd->isValid) vd->overrideFailure = true; } } void XMLCALL XmlShallowValidator::skippedentity( void *data, const XML_Char *entityName, int is_parameter_entity) { if (is_parameter_entity) return; XmlShallowValidatorData *vd; vd = (XmlShallowValidatorData *)data; if (vd->entitySet.find(entityName) != vd->entitySet.end()) return; vd->isValid = false; vd->positionVector.push_back( make_pair(XML_GetCurrentLineNumber(vd->p), XML_GetCurrentColumnNumber(vd->p))); } bool XmlShallowValidator::isValid() { return vd->isValid; } std::vector > XmlShallowValidator::getPositionVector() { return vd->positionVector; } bool XmlShallowValidator::getOverrideFailure() { return vd->overrideFailure; }