Supported auto complete list for DTDs that are on the internet

This commit is contained in:
Zane U. Ji 2014-04-22 22:33:21 +08:00
parent 13aedf637c
commit 00d8e7783f
3 changed files with 98 additions and 48 deletions

View File

@ -2,6 +2,7 @@
+ Feature #25 Fast commenting + Feature #25 Fast commenting
+ x64 installation package + x64 installation package
+ Supported HTTPS on validation + Supported HTTPS on validation
* Auto complete list for DTDs that are on the internet
* Fixed tab order * Fixed tab order
* Fixed encoding problems * Fixed encoding problems
* Fixed invisible captions in high contrast mode (Windows only, http://trac.wxwidgets.org/ticket/16186) * Fixed invisible captions in high contrast mode (Windows only, http://trac.wxwidgets.org/ticket/16186)

View File

@ -40,6 +40,8 @@
#include <xercesc/validators/schema/SchemaValidator.hpp> #include <xercesc/validators/schema/SchemaValidator.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp> #include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp> #include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/framework/URLInputSource.hpp>
#include <xercesc/validators/DTD/DTDGrammar.hpp>
using namespace xercesc; using namespace xercesc;
@ -88,10 +90,8 @@ void XMLCALL XmlPromptGenerator::starthandler (
d->rootElement = el; d->rootElement = el;
handleSchema ( d, el, attr ); // experimental: schema has been pre-parsed handleSchema ( d, el, attr ); // experimental: schema has been pre-parsed
d->isRootElement = false; d->isRootElement = false;
if ( ! (d->elementMap.empty() ) )//if ( d->elementMap.size() == 1) // must be 1 for success if ( d->grammarFound )//if ( d->elementMap.size() == 1) // must be 1 for success
{ {
d->grammarFound = true;
XML_StopParser ( d->p, false );
return; return;
} }
} }
@ -301,6 +301,43 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
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
// Either EXPAT or Xerces-C++ is capable of parsing DTDs. The advantage
// of Xerces-C++ is that it can access DTDs that are on the internet.
#if !PREFER_EXPAT_TO_XERCES_C
XercesDOMParser parser;
parser.setDoNamespaces ( true );
parser.setDoSchema ( true );
parser.setValidationSchemaFullChecking ( true );
XercesCatalogResolver catalogResolver;
parser.setEntityResolver ( &catalogResolver );
wxString wideSystemId ( systemId, wxConvUTF8 ); // TODO: Apply encoding
wxString widePublicId ( publicId, wxConvUTF8 );
URLInputSource source
( ( const XMLCh * ) WrapXerces::toString ( d->basePath ).GetData()
, ( const XMLCh * ) WrapXerces::toString ( wideSystemId ).GetData()
, ( const XMLCh * ) WrapXerces::toString ( widePublicId ).GetData()
);
Grammar *rootGrammar = parser.loadGrammar ( source, Grammar::DTDGrammarType );
if ( !rootGrammar )
return XML_STATUS_ERROR;
DTDGrammar* grammar = ( DTDGrammar* ) rootGrammar;
NameIdPoolEnumerator<DTDElementDecl> elemEnum = grammar->getElemEnumerator();
SubstitutionMap substitutions;
while ( elemEnum.hasMoreElements() )
{
const DTDElementDecl& curElem = elemEnum.nextElement();
buildElementPrompt ( d, &curElem, substitutions );
}
return XML_STATUS_OK;
#else // !PREFER_EXPAT_TO_XERCES_C
int ret; int ret;
std::string buffer; std::string buffer;
@ -360,6 +397,8 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true ); ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
XML_ParserFree ( dtdParser ); XML_ParserFree ( dtdParser );
return ret; return ret;
#endif // PREFER_EXPAT_TO_XERCES_C
} }
void XMLCALL XmlPromptGenerator::entitydeclhandler ( void XMLCALL XmlPromptGenerator::entitydeclhandler (
@ -455,57 +494,63 @@ void XmlPromptGenerator::handleSchema (
while ( elemEnum.hasMoreElements() ) while ( elemEnum.hasMoreElements() )
{ {
const SchemaElementDecl& curElem = elemEnum.nextElement(); const SchemaElementDecl& curElem = elemEnum.nextElement();
buildElementPrompt ( d, &curElem, substitutions );
}
wxString element; d->grammarFound = true;
XML_StopParser ( d->p, false );
}
const QName *qnm = curElem.getElementName(); void XmlPromptGenerator::buildElementPrompt (
if ( qnm == NULL ) PromptGeneratorData *d,
const XMLElementDecl *element,
SubstitutionMap &substitutions )
{
wxString name;
const QName *qnm = element->getElementName();
if ( qnm == NULL )
return;
name = WrapXerces::toString ( qnm->getRawName() ); // this includes any prefix:localname combinations
if ( name.empty() )
return;
const XMLCh* fmtCntModel = element->getFormattedContentModel();
if ( fmtCntModel != NULL ) // tbd: this does not yet pick up prefix:localname combinations
{
wxString structure = WrapXerces::toString ( fmtCntModel );
d->elementStructureMap[name] = structure;
}
const ContentSpecNode *spec = element->getContentSpec();
if ( spec != NULL )
{
getContent ( d->elementMap[name], spec, substitutions );
}
// fetch attributes
if ( !element->hasAttDefs() )
return;
XMLAttDefList& attIter = element->getAttDefList();
for ( unsigned int i = 0; i < attIter.getAttDefCount(); i++ )
{
wxString attribute, attributeValue;
XMLAttDef& attr = attIter.getAttDef ( i );
XMLAttDef::DefAttTypes ty = attr.getDefaultType();
if ( ty == XMLAttDef::Prohibited )
continue; continue;
element = WrapXerces::toString ( qnm->getRawName() ); // this includes any prefix:localname combinations attribute = WrapXerces::toString ( attr.getFullName() );
if ( element.empty() ) if ( attribute.empty() )
continue; continue;
const XMLCh* fmtCntModel = curElem.getFormattedContentModel(); // Value
if ( fmtCntModel != NULL ) // tbd: this does not yet pick up prefix:localname combinations attributeValue = WrapXerces::toString ( attr.getValue() );
{ d->attributeMap[name][attribute].insert( attributeValue );
wxString structure = WrapXerces::toString ( fmtCntModel );
d->elementStructureMap[element] = structure;
}
const ContentSpecNode *spec = curElem.getContentSpec();
if ( spec != NULL )
{
getContent ( d->elementMap[element], spec, substitutions );
}
// fetch attributes if ( ty == XMLAttDef::Required || ty == XMLAttDef::Required_And_Fixed)
if ( !curElem.hasAttDefs() ) d->requiredAttributeMap[name].insert ( attribute );
continue;
XMLAttDefList& attIter = curElem.getAttDefList();
for ( unsigned int i = 0; i < attIter.getAttDefCount(); i++ )
{
wxString attribute, attributeValue;
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 == NULL )
continue;
attribute = WrapXerces::toString ( qnm->getRawName() );
if ( attribute.empty() )
continue;
// Value
attributeValue = WrapXerces::toString ( pAttr->getValue() );
d->attributeMap[element][attribute].insert( attributeValue );
if ( ty == XMLAttDef::Required || ty == XMLAttDef::Required_And_Fixed)
d->requiredAttributeMap[element].insert ( attribute );
}
} }
} }

View File

@ -122,6 +122,10 @@ class XmlPromptGenerator : public WrapExpat
static void buildSubstitutionMap ( static void buildSubstitutionMap (
SubstitutionMap &substitutions, SubstitutionMap &substitutions,
const xercesc::SchemaGrammar &grammar ); const xercesc::SchemaGrammar &grammar );
static void buildElementPrompt (
PromptGeneratorData *d,
const xercesc::XMLElementDecl *element,
SubstitutionMap &substitutions );
static void getContent ( static void getContent (
std::set<wxString> &list, std::set<wxString> &list,
const xercesc::ContentSpecNode *spec, const xercesc::ContentSpecNode *spec,