Enabled XML Schema-based insertion helpers and validation-as-you-type.
This commit is contained in:
parent
55d20854af
commit
4c4536cdb4
|
@ -25,6 +25,6 @@ std::string CatalogResolver::lookupPublicId (
|
||||||
const std::string& publicId,
|
const std::string& publicId,
|
||||||
const std::string& catalogPath )
|
const std::string& catalogPath )
|
||||||
{
|
{
|
||||||
std::auto_ptr<WrapLibxml> libxml ( new WrapLibxml ( false, catalogPath ) );
|
std::auto_ptr<WrapLibxml> libxml ( new WrapLibxml ( false, catalogPath ) );
|
||||||
return libxml->lookupPublicId ( publicId );
|
return libxml->lookupPublicId ( publicId );
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,30 +29,45 @@
|
||||||
#include "catalogresolver.h"
|
#include "catalogresolver.h"
|
||||||
#include "xmlschemaparser.h"
|
#include "xmlschemaparser.h"
|
||||||
|
|
||||||
|
// Xerces-C req'd for Schema parsing
|
||||||
|
#define XERCES_TMPLSINC
|
||||||
|
|
||||||
|
#include <xercesc/util/NameIdPool.hpp>
|
||||||
|
#include <xercesc/util/PlatformUtils.hpp>
|
||||||
|
#include <xercesc/framework/XMLValidator.hpp>
|
||||||
|
#include <xercesc/parsers/SAXParser.hpp>
|
||||||
|
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||||
|
#include <xercesc/validators/schema/SchemaValidator.hpp>
|
||||||
|
#include <xercesc/validators/common/ContentSpecNode.hpp>
|
||||||
|
#include <xercesc/validators/schema/SchemaSymbols.hpp>
|
||||||
|
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
XmlPromptGenerator::XmlPromptGenerator (
|
XmlPromptGenerator::XmlPromptGenerator (
|
||||||
const std::string& catalogPath,
|
const std::string& catalogPath,
|
||||||
const std::string& basePath,
|
const std::string& basePath,
|
||||||
const std::string& auxPath ) : d ( new PromptGeneratorData() )
|
const std::string& auxPath ) : d ( new PromptGeneratorData() )
|
||||||
{
|
{
|
||||||
XML_SetUserData ( p, d.get() );
|
XML_SetUserData ( p, d.get() );
|
||||||
d->p = p;
|
d->p = p;
|
||||||
d->catalogPath = catalogPath;
|
d->catalogPath = catalogPath;
|
||||||
d->auxPath = auxPath;
|
d->auxPath = auxPath;
|
||||||
d->elementDeclRecurseLevel = 0;
|
d->elementDeclRecurseLevel = 0;
|
||||||
d->rootElement = true;
|
d->isRootElement = true;
|
||||||
d->dtdFound = false;
|
d->grammarFound = false;
|
||||||
XML_SetParamEntityParsing ( p, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE );
|
d->attributeValueCutoff = 12; // this prevents enums being stored in their thousands
|
||||||
XML_SetElementHandler ( p, starthandler, endhandler );
|
XML_SetParamEntityParsing ( p, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE );
|
||||||
XML_SetDoctypeDeclHandler ( p, doctypedeclstarthandler, doctypedeclendhandler );
|
XML_SetElementHandler ( p, starthandler, endhandler );
|
||||||
XML_SetElementDeclHandler ( p, elementdeclhandler );
|
XML_SetDoctypeDeclHandler ( p, doctypedeclstarthandler, doctypedeclendhandler );
|
||||||
XML_SetAttlistDeclHandler ( p, attlistdeclhandler );
|
XML_SetElementDeclHandler ( p, elementdeclhandler );
|
||||||
XML_SetEntityDeclHandler ( p, entitydeclhandler );
|
XML_SetAttlistDeclHandler ( p, attlistdeclhandler );
|
||||||
XML_SetExternalEntityRefHandlerArg ( p, d.get() );
|
XML_SetEntityDeclHandler ( p, entitydeclhandler );
|
||||||
XML_SetExternalEntityRefHandler ( p, externalentityrefhandler );
|
XML_SetExternalEntityRefHandlerArg ( p, d.get() );
|
||||||
XML_SetBase ( p, basePath.c_str() );
|
XML_SetExternalEntityRefHandler ( p, externalentityrefhandler );
|
||||||
|
XML_SetBase ( p, basePath.c_str() );
|
||||||
|
|
||||||
if ( !auxPath.empty() )
|
if ( !auxPath.empty() )
|
||||||
XML_UseForeignDTD ( p, true );
|
XML_UseForeignDTD ( p, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlPromptGenerator::~XmlPromptGenerator()
|
XmlPromptGenerator::~XmlPromptGenerator()
|
||||||
|
@ -63,96 +78,93 @@ void XMLCALL XmlPromptGenerator::starthandler (
|
||||||
const XML_Char *el,
|
const XML_Char *el,
|
||||||
const XML_Char **attr )
|
const XML_Char **attr )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data;
|
d = ( PromptGeneratorData * ) data;
|
||||||
|
|
||||||
d->push ( el );
|
if (d->isRootElement)
|
||||||
|
{
|
||||||
|
d->rootElement = el;
|
||||||
|
handleSchema ( d, el, attr );
|
||||||
|
d->isRootElement = false;
|
||||||
|
if ( ! (d->elementMap.empty() ) )//if ( d->elementMap.size() == 1) // must be 1 for success
|
||||||
|
{
|
||||||
|
d->grammarFound = true;
|
||||||
|
XML_StopParser ( d->p, false );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string parent, element;
|
d->push ( el );
|
||||||
parent = d->getParent();
|
|
||||||
element = el;
|
|
||||||
|
|
||||||
// update elementMap
|
std::string parent, element;
|
||||||
if ( d->elementMap.find ( parent ) == d->elementMap.end() )
|
parent = d->getParent();
|
||||||
{
|
element = el;
|
||||||
std::set<std::string> childSet;
|
|
||||||
childSet.insert ( element );
|
|
||||||
d->elementMap.insert ( make_pair ( parent, childSet ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d->elementMap[parent].insert ( element );
|
|
||||||
|
|
||||||
std::string attributeName, attributeValue;
|
// update elementMap
|
||||||
|
if ( d->elementMap.find ( parent ) == d->elementMap.end() )
|
||||||
|
{
|
||||||
|
std::set<std::string> childSet;
|
||||||
|
childSet.insert ( element );
|
||||||
|
d->elementMap.insert ( make_pair ( parent, childSet ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d->elementMap[parent].insert ( element );
|
||||||
|
|
||||||
// update attributeMap
|
std::string attributeName, attributeValue;
|
||||||
// case 1: element unknown, no attributes
|
|
||||||
if ( ! ( *attr ) && d->attributeMap.find ( element ) == d->attributeMap.end() )
|
|
||||||
{
|
|
||||||
std::map<std::string, std::set<std::string> > currentAttributeMap;
|
|
||||||
d->attributeMap.insert ( make_pair ( element, currentAttributeMap ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( ; *attr; attr += 2 )
|
// update attributeMap
|
||||||
{
|
// case 1: element unknown, no attributes
|
||||||
attributeName = *attr;
|
if ( ! ( *attr ) && d->attributeMap.find ( element ) == d->attributeMap.end() )
|
||||||
attributeValue = * ( attr + 1 );
|
{
|
||||||
|
std::map<std::string, std::set<std::string> > currentAttributeMap;
|
||||||
|
d->attributeMap.insert ( make_pair ( element, currentAttributeMap ) );
|
||||||
|
}
|
||||||
|
|
||||||
d->attributeMap[element][attributeName].insert ( attributeValue );
|
for ( ; *attr; attr += 2 )
|
||||||
|
{
|
||||||
|
attributeName = *attr;
|
||||||
|
attributeValue = * ( attr + 1 );
|
||||||
|
|
||||||
/*
|
if (d->attributeMap[element][attributeName].size() < d->attributeValueCutoff)
|
||||||
// TBD: may not be xsi: check for http://www.w3.org/2001/XMLSchema-instance
|
d->attributeMap[element][attributeName].insert ( attributeValue );
|
||||||
while (d->rootElement && strstr((const char *)attr, "xsi:noNamespaceSchemaLocation"))
|
}
|
||||||
{
|
|
||||||
std::string schemaPath = PathResolver::run(attributeValue, d->auxPath);
|
|
||||||
std::string buffer;
|
|
||||||
if (!ReadFile::run(schemaPath, buffer))
|
|
||||||
break;
|
|
||||||
XmlSchemaParser xsp(d, true);
|
|
||||||
if (!xsp.parse(buffer))
|
|
||||||
break;
|
|
||||||
XML_StopParser(d->p, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
d->rootElement = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLCALL XmlPromptGenerator::endhandler ( void *data, const XML_Char *el )
|
void XMLCALL XmlPromptGenerator::endhandler ( void *data, const XML_Char *el )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data;
|
d = ( PromptGeneratorData * ) data;
|
||||||
d->pop();
|
d->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XmlPromptGenerator::getDtdFound()
|
bool XmlPromptGenerator::getGrammarFound()
|
||||||
{
|
{
|
||||||
return d->dtdFound;
|
return d->grammarFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlPromptGenerator::getAttributeMap (
|
void XmlPromptGenerator::getAttributeMap (
|
||||||
std::map<std::string, std::map<std::string, std::set<std::string> > >
|
std::map<std::string, std::map<std::string, std::set<std::string> > >
|
||||||
&attributeMap )
|
&attributeMap )
|
||||||
{
|
{
|
||||||
attributeMap = d->attributeMap;
|
attributeMap = d->attributeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlPromptGenerator::getRequiredAttributeMap (
|
void XmlPromptGenerator::getRequiredAttributeMap (
|
||||||
std::map<std::string, std::set<std::string> >& requiredAttributeMap )
|
std::map<std::string, std::set<std::string> >& requiredAttributeMap )
|
||||||
{
|
{
|
||||||
requiredAttributeMap = d->requiredAttributeMap;
|
requiredAttributeMap = d->requiredAttributeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlPromptGenerator::getElementMap (
|
void XmlPromptGenerator::getElementMap (
|
||||||
std::map<std::string, std::set<std::string> > &elementMap )
|
std::map<std::string, std::set<std::string> > &elementMap )
|
||||||
{
|
{
|
||||||
elementMap = d->elementMap;
|
elementMap = d->elementMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmlPromptGenerator::getEntitySet (
|
void XmlPromptGenerator::getEntitySet (
|
||||||
std::set<std::string> &entitySet )
|
std::set<std::string> &entitySet )
|
||||||
{
|
{
|
||||||
entitySet = d->entitySet;
|
entitySet = d->entitySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlers for DOCTYPE handling
|
// handlers for DOCTYPE handling
|
||||||
|
@ -164,19 +176,19 @@ void XMLCALL XmlPromptGenerator::doctypedeclstarthandler (
|
||||||
const XML_Char *pubid,
|
const XML_Char *pubid,
|
||||||
int has_internal_subset )
|
int has_internal_subset )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data;
|
d = ( PromptGeneratorData * ) data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLCALL XmlPromptGenerator::doctypedeclendhandler ( void *data )
|
void XMLCALL XmlPromptGenerator::doctypedeclendhandler ( void *data )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data;
|
d = ( PromptGeneratorData * ) data;
|
||||||
if ( !d->elementMap.empty() )
|
if ( !d->elementMap.empty() )
|
||||||
{
|
{
|
||||||
d->dtdFound = true;
|
d->grammarFound = true;
|
||||||
XML_StopParser ( d->p, false );
|
XML_StopParser ( d->p, false ); // experimental
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLCALL XmlPromptGenerator::elementdeclhandler (
|
void XMLCALL XmlPromptGenerator::elementdeclhandler (
|
||||||
|
@ -184,33 +196,33 @@ void XMLCALL XmlPromptGenerator::elementdeclhandler (
|
||||||
const XML_Char *name,
|
const XML_Char *name,
|
||||||
XML_Content *model )
|
XML_Content *model )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data;
|
d = ( PromptGeneratorData * ) data;
|
||||||
|
|
||||||
d->elementDeclRecurseLevel += 1;
|
d->elementDeclRecurseLevel += 1;
|
||||||
|
|
||||||
std::string myElement = name;
|
std::string myElement = name;
|
||||||
unsigned num = model->numchildren;
|
unsigned num = model->numchildren;
|
||||||
|
|
||||||
for ( unsigned i = 0; i < num; i++ )
|
for ( unsigned i = 0; i < num; i++ )
|
||||||
{
|
{
|
||||||
XML_Content myContent = model->children[i];
|
XML_Content myContent = model->children[i];
|
||||||
XML_Char *myName = myContent.name;
|
XML_Char *myName = myContent.name;
|
||||||
if ( myName )
|
if ( myName )
|
||||||
d->elementMap[myElement].insert ( ( const char * ) myName );
|
d->elementMap[myElement].insert ( ( const char * ) myName );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// recurse
|
// recurse
|
||||||
XmlPromptGenerator::elementdeclhandler ( ( void * ) d, name, &myContent );
|
XmlPromptGenerator::elementdeclhandler ( ( void * ) d, name, &myContent );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d->elementDeclRecurseLevel -= 1;
|
d->elementDeclRecurseLevel -= 1;
|
||||||
|
|
||||||
// only one call to XML_FreeContentModel per content tree
|
// only one call to XML_FreeContentModel per content tree
|
||||||
if ( d->elementDeclRecurseLevel == 0 )
|
if ( d->elementDeclRecurseLevel == 0 )
|
||||||
{
|
{
|
||||||
XML_FreeContentModel ( d->p, model );
|
XML_FreeContentModel ( d->p, model );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLCALL XmlPromptGenerator::attlistdeclhandler (
|
void XMLCALL XmlPromptGenerator::attlistdeclhandler (
|
||||||
|
@ -221,36 +233,36 @@ void XMLCALL XmlPromptGenerator::attlistdeclhandler (
|
||||||
const XML_Char *dflt,
|
const XML_Char *dflt,
|
||||||
int isrequired )
|
int isrequired )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data;
|
d = ( PromptGeneratorData * ) data;
|
||||||
|
|
||||||
std::set<std::string> attributeValues;
|
std::set<std::string> attributeValues;
|
||||||
if ( *att_type == '(' ) // change to exclude _known_ identifiers?
|
if ( *att_type == '(' ) // change to exclude _known_ identifiers?
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
char *s, *word;
|
char *s, *word;
|
||||||
s = ( char * ) att_type;
|
s = ( char * ) att_type;
|
||||||
|
|
||||||
while ( ( word = GetWord::run ( &s, &len ) ) != NULL )
|
while ( ( word = GetWord::run ( &s, &len ) ) != NULL )
|
||||||
{
|
{
|
||||||
std::string currentValue ( word, len );
|
std::string currentValue ( word, len );
|
||||||
attributeValues.insert ( currentValue );
|
attributeValues.insert ( currentValue );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attributeValues.empty() )
|
if ( attributeValues.empty() )
|
||||||
{
|
{
|
||||||
d->attributeMap[elname][attname].insert ( "" );
|
d->attributeMap[elname][attname].insert ( "" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::set<std::string>::iterator it;
|
std::set<std::string>::iterator it;
|
||||||
for ( it = attributeValues.begin(); it != attributeValues.end(); it++ )
|
for ( it = attributeValues.begin(); it != attributeValues.end(); it++ )
|
||||||
d->attributeMap[elname][attname].insert ( *it );
|
d->attributeMap[elname][attname].insert ( *it );
|
||||||
|
|
||||||
if ( isrequired )
|
if ( isrequired )
|
||||||
{
|
{
|
||||||
d->requiredAttributeMap[elname].insert ( attname );
|
d->requiredAttributeMap[elname].insert ( attname );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
||||||
|
@ -260,65 +272,70 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
||||||
const XML_Char *systemId,
|
const XML_Char *systemId,
|
||||||
const XML_Char *publicId )
|
const XML_Char *publicId )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) p; // arg is set to user data in c'tor
|
d = ( PromptGeneratorData * ) p; // arg is set to user data in c'tor
|
||||||
|
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|
||||||
// auxPath req'd?
|
// auxPath req'd?
|
||||||
if ( !systemId && !publicId )
|
if ( !systemId && !publicId )
|
||||||
{
|
{
|
||||||
ReadFile::run ( d->auxPath, buffer );
|
ReadFile::run ( d->auxPath, buffer );
|
||||||
if ( buffer.empty() )
|
if ( buffer.empty() )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encoding = XmlEncodingHandler::get ( buffer );
|
std::string encoding = XmlEncodingHandler::get ( buffer );
|
||||||
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );
|
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );
|
||||||
if ( !dtdParser )
|
if ( !dtdParser )
|
||||||
return false;
|
return false;
|
||||||
XML_SetBase ( dtdParser, d->auxPath.c_str() );
|
XML_SetBase ( dtdParser, d->auxPath.c_str() );
|
||||||
return XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
|
return XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string stdPublicId;
|
std::string stdPublicId;
|
||||||
if ( publicId )
|
if ( publicId )
|
||||||
stdPublicId = publicId;
|
stdPublicId = publicId;
|
||||||
|
|
||||||
std::string stdSystemId = CatalogResolver::lookupPublicId ( stdPublicId, d->catalogPath );
|
std::string stdSystemId = CatalogResolver::lookupPublicId ( stdPublicId, d->catalogPath );
|
||||||
if ( stdSystemId.empty() && systemId )
|
|
||||||
stdSystemId = systemId;
|
|
||||||
|
|
||||||
Replace::run ( stdSystemId, "file:///", "", false );
|
if ( !stdSystemId.empty() )
|
||||||
Replace::run ( stdSystemId, "%20", " ", false );
|
{
|
||||||
|
Replace::run ( stdSystemId, "file://", "", false );
|
||||||
|
Replace::run ( stdSystemId, "%20", " ", false );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (systemId )
|
||||||
|
stdSystemId = systemId;
|
||||||
|
if ( base )
|
||||||
|
{
|
||||||
|
std::string test = PathResolver::run ( stdSystemId, base );
|
||||||
|
if ( !test.empty() )
|
||||||
|
{
|
||||||
|
stdSystemId = test;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( base )
|
if ( !stdSystemId.empty() )
|
||||||
{
|
{
|
||||||
std::string test = PathResolver::run ( stdSystemId, base );
|
ReadFile::run ( stdSystemId, buffer );
|
||||||
if ( !test.empty() )
|
}
|
||||||
{
|
|
||||||
stdSystemId = test;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !stdSystemId.empty() )
|
std::string encoding = XmlEncodingHandler::get ( buffer );
|
||||||
{
|
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );
|
||||||
ReadFile::run ( stdSystemId, buffer );
|
if ( !dtdParser )
|
||||||
}
|
return false;
|
||||||
|
|
||||||
std::string encoding = XmlEncodingHandler::get ( buffer );
|
wxString wideName, wideDir;
|
||||||
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );//"UTF-8");
|
wideName = wxString ( stdSystemId.c_str(), wxConvUTF8, stdSystemId.size() );
|
||||||
if ( !dtdParser )
|
wxFileName fn ( wideName );
|
||||||
return false;
|
wideDir = fn.GetPath();
|
||||||
|
XML_SetBase ( dtdParser, wideName.mb_str ( wxConvUTF8 ) );
|
||||||
|
|
||||||
wxString wideName, wideDir;
|
return XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
|
||||||
wideName = wxString ( stdSystemId.c_str(), wxConvUTF8, stdSystemId.size() );
|
|
||||||
wxFileName fn ( wideName );
|
|
||||||
wideDir = fn.GetPath();
|
|
||||||
XML_SetBase ( dtdParser, wideName.mb_str ( wxConvUTF8 ) );
|
|
||||||
|
|
||||||
return XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLCALL XmlPromptGenerator::entitydeclhandler (
|
void XMLCALL XmlPromptGenerator::entitydeclhandler (
|
||||||
|
@ -332,16 +349,158 @@ void XMLCALL XmlPromptGenerator::entitydeclhandler (
|
||||||
const XML_Char *publicId,
|
const XML_Char *publicId,
|
||||||
const XML_Char *notationName )
|
const XML_Char *notationName )
|
||||||
{
|
{
|
||||||
PromptGeneratorData *d;
|
PromptGeneratorData *d;
|
||||||
d = ( PromptGeneratorData * ) data; // arg is set to user data in c'tor
|
d = ( PromptGeneratorData * ) data; // arg is set to user data in c'tor
|
||||||
|
|
||||||
if (
|
if (
|
||||||
entityName &&
|
entityName &&
|
||||||
!is_parameter_entity &&
|
!is_parameter_entity &&
|
||||||
!systemId &&
|
!systemId &&
|
||||||
!publicId &&
|
!publicId &&
|
||||||
!notationName )
|
!notationName )
|
||||||
{
|
{
|
||||||
d->entitySet.insert ( entityName );
|
d->entitySet.insert ( entityName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XmlPromptGenerator::handleSchema (
|
||||||
|
PromptGeneratorData *d,
|
||||||
|
const XML_Char *el,
|
||||||
|
const XML_Char **attr )
|
||||||
|
{
|
||||||
|
// first check for XML Schema association
|
||||||
|
XML_Char **schemaAttr = ( XML_Char ** ) attr; // now redundant; could use attr
|
||||||
|
std::string path;
|
||||||
|
for ( ; d->isRootElement && *schemaAttr; schemaAttr += 2 )
|
||||||
|
{
|
||||||
|
// no namespace
|
||||||
|
if ( !strcmp ( ( const char * ) *schemaAttr, "xsi:noNamespaceSchemaLocation" ) )
|
||||||
|
{
|
||||||
|
path = ( const char * ) * ( schemaAttr + 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// with namespace -- check if this works
|
||||||
|
else if ( !strcmp ( ( const char * ) *schemaAttr, "xsi:schemaLocation" ) )
|
||||||
|
{
|
||||||
|
char *searchIterator;
|
||||||
|
for ( searchIterator = ( char * ) * ( schemaAttr + 1 ); *searchIterator && *searchIterator != ' ' && *searchIterator != '\t' && *searchIterator != '\n'; searchIterator++ )
|
||||||
|
;
|
||||||
|
if ( *searchIterator )
|
||||||
|
{
|
||||||
|
path = ( const char * ) ( searchIterator + 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( path.empty() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string schemaPath = PathResolver::run ( path, d->auxPath );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
XMLPlatformUtils::Initialize();
|
||||||
|
}
|
||||||
|
catch ( const XMLException& toCatch )
|
||||||
|
{
|
||||||
|
XMLPlatformUtils::Terminate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XercesDOMParser *parser = new XercesDOMParser();
|
||||||
|
parser->setDoNamespaces ( true );
|
||||||
|
parser->setDoSchema ( true );
|
||||||
|
parser->setValidationSchemaFullChecking ( true );
|
||||||
|
|
||||||
|
Grammar *rootGrammar = parser->loadGrammar ( schemaPath.c_str(), Grammar::SchemaGrammarType );
|
||||||
|
if ( !rootGrammar )
|
||||||
|
{
|
||||||
|
delete parser;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SchemaGrammar* grammar = ( SchemaGrammar* ) rootGrammar;
|
||||||
|
RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
|
||||||
|
|
||||||
|
if ( !elemEnum.hasMoreElements() )
|
||||||
|
{
|
||||||
|
delete grammar;
|
||||||
|
delete parser;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( elemEnum.hasMoreElements() )
|
||||||
|
{
|
||||||
|
const SchemaElementDecl& curElem = elemEnum.nextElement();
|
||||||
|
|
||||||
|
std::string element;
|
||||||
|
std::set<std::string> children;
|
||||||
|
|
||||||
|
const QName *qnm = curElem.getElementName();
|
||||||
|
if ( qnm )
|
||||||
|
{
|
||||||
|
element = XMLString::transcode ( qnm->getRawName() ); // this includes any prefix:localname combinations
|
||||||
|
}
|
||||||
|
if ( element.empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const XMLCh* fmtCntModel = curElem.getFormattedContentModel();
|
||||||
|
if ( fmtCntModel != NULL ) // tbd: this does not yet pick up prefix:localname combinations
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
char *s, *word;
|
||||||
|
s = ( char * ) XMLString::transcode ( fmtCntModel );
|
||||||
|
|
||||||
|
while ( ( word = GetWord::run ( &s, &len ) ) != NULL )
|
||||||
|
{
|
||||||
|
std::string currentValue ( word, len );
|
||||||
|
if ( currentValue.size() )
|
||||||
|
children.insert ( currentValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !children.empty() )
|
||||||
|
d->elementMap.insert ( make_pair ( element, children ) );
|
||||||
|
|
||||||
|
// fetch attributes
|
||||||
|
if ( curElem.hasAttDefs() && ! ( curElem.getAttDefList().isEmpty() ) )
|
||||||
|
{
|
||||||
|
std::map<std::string, std::set<std::string> > attributeMap;
|
||||||
|
|
||||||
|
XMLAttDefList& attIter = curElem.getAttDefList();
|
||||||
|
for ( unsigned int i = 0; i < attIter.getAttDefCount(); i++ )
|
||||||
|
{
|
||||||
|
std::string attribute, attributeValue;
|
||||||
|
std::set<std::string> attributeValueSet;
|
||||||
|
|
||||||
|
XMLAttDef& attr = attIter.getAttDef ( i );
|
||||||
|
XMLAttDef::DefAttTypes ty = attr.getDefaultType();
|
||||||
|
if ( ty == XMLAttDef::Prohibited )
|
||||||
|
continue;
|
||||||
|
SchemaAttDef *pAttr = ( SchemaAttDef * ) &attr;
|
||||||
|
|
||||||
|
const QName *qnm = pAttr->getAttName();
|
||||||
|
if ( qnm )
|
||||||
|
{
|
||||||
|
attribute = XMLString::transcode ( qnm->getRawName() );
|
||||||
|
}
|
||||||
|
if ( attribute.empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Value
|
||||||
|
if ( pAttr->getValue() )
|
||||||
|
{
|
||||||
|
attributeValue = XMLString::transcode ( pAttr->getValue() );
|
||||||
|
attributeValueSet.insert ( attributeValue );
|
||||||
|
attributeMap.insert ( make_pair ( attribute, attributeValueSet ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !attributeMap.empty() )
|
||||||
|
d->attributeMap.insert( make_pair ( element, attributeMap ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,78 +28,83 @@
|
||||||
|
|
||||||
struct PromptGeneratorData : public ParserData
|
struct PromptGeneratorData : public ParserData
|
||||||
{
|
{
|
||||||
std::map<std::string, std::map<std::string, std::set<std::string> > >
|
std::map<std::string, std::map<std::string, std::set<std::string> > >
|
||||||
attributeMap;
|
attributeMap;
|
||||||
std::map<std::string, std::set<std::string> > elementMap;
|
std::map<std::string, std::set<std::string> > elementMap;
|
||||||
std::map<std::string, std::set<std::string> > requiredAttributeMap;
|
std::map<std::string, std::set<std::string> > requiredAttributeMap;
|
||||||
std::set<std::string> entitySet;
|
std::set<std::string> entitySet;
|
||||||
std::string catalogPath, auxPath;
|
std::string catalogPath, auxPath, rootElement;
|
||||||
int elementDeclRecurseLevel;
|
int elementDeclRecurseLevel;
|
||||||
bool rootElement, dtdFound;
|
bool isRootElement, grammarFound;
|
||||||
XML_Parser p;
|
unsigned attributeValueCutoff;
|
||||||
|
XML_Parser p;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XmlPromptGenerator : public WrapExpat
|
class XmlPromptGenerator : public WrapExpat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XmlPromptGenerator (
|
XmlPromptGenerator (
|
||||||
const std::string& catalogPath = "",
|
const std::string& catalogPath = "",
|
||||||
const std::string& basePath = "",
|
const std::string& basePath = "",
|
||||||
const std::string& auxPath = "" );
|
const std::string& auxPath = "" );
|
||||||
virtual ~XmlPromptGenerator();
|
virtual ~XmlPromptGenerator();
|
||||||
void getAttributeMap (
|
void getAttributeMap (
|
||||||
std::map<std::string, std::map<std::string, std::set<std::string> > >
|
std::map<std::string, std::map<std::string, std::set<std::string> > >
|
||||||
&attributeMap );
|
&attributeMap );
|
||||||
void getRequiredAttributeMap (
|
void getRequiredAttributeMap (
|
||||||
std::map<std::string, std::set<std::string> > &requiredAttributeMap );
|
std::map<std::string, std::set<std::string> > &requiredAttributeMap );
|
||||||
void getElementMap (
|
void getElementMap (
|
||||||
std::map<std::string, std::set<std::string> > &elementMap );
|
std::map<std::string, std::set<std::string> > &elementMap );
|
||||||
void getEntitySet (
|
void getEntitySet (
|
||||||
std::set<std::string> &entitySet );
|
std::set<std::string> &entitySet );
|
||||||
bool getDtdFound();
|
bool getGrammarFound();
|
||||||
private:
|
private:
|
||||||
std::auto_ptr<PromptGeneratorData> d;
|
std::auto_ptr<PromptGeneratorData> d;
|
||||||
static void XMLCALL starthandler (
|
static void XMLCALL starthandler (
|
||||||
void *data,
|
void *data,
|
||||||
const XML_Char *el,
|
const XML_Char *el,
|
||||||
const XML_Char **attr );
|
const XML_Char **attr );
|
||||||
static void XMLCALL endhandler (
|
static void XMLCALL endhandler (
|
||||||
void *data,
|
void *data,
|
||||||
const XML_Char *el );
|
const XML_Char *el );
|
||||||
static void XMLCALL doctypedeclstarthandler (
|
static void XMLCALL doctypedeclstarthandler (
|
||||||
void *userData,
|
void *userData,
|
||||||
const XML_Char *doctypeName,
|
const XML_Char *doctypeName,
|
||||||
const XML_Char *sysid,
|
const XML_Char *sysid,
|
||||||
const XML_Char *pubid,
|
const XML_Char *pubid,
|
||||||
int has_internal_subset );
|
int has_internal_subset );
|
||||||
static void XMLCALL doctypedeclendhandler ( void *userData );
|
static void XMLCALL doctypedeclendhandler ( void *userData );
|
||||||
static void XMLCALL elementdeclhandler (
|
static void XMLCALL elementdeclhandler (
|
||||||
void *userData,
|
void *userData,
|
||||||
const XML_Char *name,
|
const XML_Char *name,
|
||||||
XML_Content *model );
|
XML_Content *model );
|
||||||
static void XMLCALL attlistdeclhandler (
|
static void XMLCALL attlistdeclhandler (
|
||||||
void *userData,
|
void *userData,
|
||||||
const XML_Char *elname,
|
const XML_Char *elname,
|
||||||
const XML_Char *attname,
|
const XML_Char *attname,
|
||||||
const XML_Char *att_type,
|
const XML_Char *att_type,
|
||||||
const XML_Char *dflt,
|
const XML_Char *dflt,
|
||||||
int isrequired );
|
int isrequired );
|
||||||
static int XMLCALL externalentityrefhandler (
|
static int XMLCALL externalentityrefhandler (
|
||||||
XML_Parser p,
|
XML_Parser p,
|
||||||
const XML_Char *context,
|
const XML_Char *context,
|
||||||
const XML_Char *base,
|
const XML_Char *base,
|
||||||
const XML_Char *systemId,
|
const XML_Char *systemId,
|
||||||
const XML_Char *publicId );
|
const XML_Char *publicId );
|
||||||
static void XMLCALL entitydeclhandler (
|
static void XMLCALL entitydeclhandler (
|
||||||
void *userData,
|
void *userData,
|
||||||
const XML_Char *entityName,
|
const XML_Char *entityName,
|
||||||
int is_parameter_entity,
|
int is_parameter_entity,
|
||||||
const XML_Char *value,
|
const XML_Char *value,
|
||||||
int value_length,
|
int value_length,
|
||||||
const XML_Char *base,
|
const XML_Char *base,
|
||||||
const XML_Char *systemId,
|
const XML_Char *systemId,
|
||||||
const XML_Char *publicId,
|
const XML_Char *publicId,
|
||||||
const XML_Char *notationName );
|
const XML_Char *notationName );
|
||||||
|
static void handleSchema (
|
||||||
|
PromptGeneratorData *d,
|
||||||
|
const XML_Char *el,
|
||||||
|
const XML_Char **attr );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue