Fixed a problem when dealing with "xsi:schemaLocation"
This commit is contained in:
parent
c61ceec6d0
commit
3993927d66
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "xmlpromptgenerator.h"
|
#include "xmlpromptgenerator.h"
|
||||||
#include "xmlencodinghandler.h"
|
#include "xmlencodinghandler.h"
|
||||||
|
@ -285,21 +286,14 @@ void XMLCALL XmlPromptGenerator::attlistdeclhandler (
|
||||||
XML_StopParser ( d->p, false );
|
XML_StopParser ( d->p, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
int XmlPromptGenerator::parseGrammar
|
||||||
XML_Parser p,
|
( PromptGeneratorData *d
|
||||||
const XML_Char *context,
|
, const wxString &publicId
|
||||||
const XML_Char *base,
|
, const wxString &systemId
|
||||||
const XML_Char *systemId,
|
, const wxString &baseFileName
|
||||||
const XML_Char *publicId )
|
, Grammar::GrammarType type
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// arg is set to user data in c'tor
|
|
||||||
XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) p;
|
|
||||||
PromptGeneratorData *d = pThis->d.get();
|
|
||||||
|
|
||||||
// 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;
|
XercesDOMParser parser;
|
||||||
parser.setDoNamespaces ( true );
|
parser.setDoNamespaces ( true );
|
||||||
parser.setDoSchema ( true );
|
parser.setDoSchema ( true );
|
||||||
|
@ -310,23 +304,20 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
||||||
parser.setErrorHandler ( &handler );
|
parser.setErrorHandler ( &handler );
|
||||||
parser.setEntityResolver ( &catalogResolver );
|
parser.setEntityResolver ( &catalogResolver );
|
||||||
|
|
||||||
wxString widePublicId = wxString::FromUTF8 ( publicId );
|
|
||||||
wxString wideSystemId = wxString::FromUTF8 ( systemId );
|
|
||||||
|
|
||||||
Grammar *rootGrammar;
|
Grammar *rootGrammar;
|
||||||
try {
|
try {
|
||||||
std::auto_ptr<InputSource> source ( WrapXerces::resolveEntity
|
std::auto_ptr<InputSource> source ( WrapXerces::resolveEntity
|
||||||
( widePublicId , wideSystemId , d->basePath ) );
|
( publicId , systemId , baseFileName ) );
|
||||||
if ( !source.get() )
|
if ( !source.get() )
|
||||||
{
|
{
|
||||||
wxLogError ( _T("Cann't open '%s'"), wideSystemId.c_str() );
|
wxLogError ( _T("Cann't open '%s'"), systemId.c_str() );
|
||||||
return XML_STATUS_ERROR;
|
return XML_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pThis->TestDestroy() )
|
if ( TestDestroy() )
|
||||||
return XML_STATUS_ERROR;
|
return XML_STATUS_ERROR;
|
||||||
|
|
||||||
rootGrammar = parser.loadGrammar ( *source, Grammar::DTDGrammarType );
|
rootGrammar = parser.loadGrammar ( *source, type );
|
||||||
if ( !rootGrammar )
|
if ( !rootGrammar )
|
||||||
return XML_STATUS_ERROR;
|
return XML_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -349,30 +340,81 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
wxLogError ( _T ( "Failed to load: %s %s"), widePublicId.c_str()
|
wxLogError ( _T ( "Failed to load: %s %s"), publicId.c_str()
|
||||||
, wideSystemId.c_str() );
|
, systemId.c_str() );
|
||||||
return XML_STATUS_ERROR;
|
return XML_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DTDGrammar* grammar = ( DTDGrammar* ) rootGrammar;
|
wxASSERT ( rootGrammar->getGrammarType() == type );
|
||||||
NameIdPoolEnumerator<DTDElementDecl> elemEnum = grammar->getElemEnumerator();
|
|
||||||
|
|
||||||
SubstitutionMap substitutions;
|
if ( type == Grammar::DTDGrammarType )
|
||||||
while ( elemEnum.hasMoreElements() && !pThis->TestDestroy() )
|
|
||||||
{
|
{
|
||||||
const DTDElementDecl& curElem = elemEnum.nextElement();
|
DTDGrammar* grammar = ( DTDGrammar* ) rootGrammar;
|
||||||
pThis->buildElementPrompt ( d, &curElem, substitutions );
|
NameIdPoolEnumerator<DTDElementDecl> elemEnum
|
||||||
|
= grammar->getElemEnumerator();
|
||||||
|
|
||||||
|
SubstitutionMap substitutions;
|
||||||
|
while ( elemEnum.hasMoreElements() && !TestDestroy() )
|
||||||
|
{
|
||||||
|
const DTDElementDecl& curElem = elemEnum.nextElement();
|
||||||
|
buildElementPrompt ( d, &curElem, substitutions );
|
||||||
|
}
|
||||||
|
|
||||||
|
NameIdPoolEnumerator<DTDEntityDecl>
|
||||||
|
entityEnum = grammar->getEntityEnumerator();
|
||||||
|
while ( entityEnum.hasMoreElements() && !TestDestroy() )
|
||||||
|
{
|
||||||
|
const DTDEntityDecl &entity = entityEnum.nextElement();
|
||||||
|
d->entitySet.insert ( WrapXerces::toString ( entity.getName() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxASSERT ( type == Grammar::SchemaGrammarType );
|
||||||
|
|
||||||
|
SchemaGrammar* grammar = ( SchemaGrammar* ) rootGrammar;
|
||||||
|
RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
|
||||||
|
|
||||||
|
if ( !elemEnum.hasMoreElements() )
|
||||||
|
{
|
||||||
|
return XML_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SubstitutionMap substitutions;
|
||||||
|
buildSubstitutionMap ( substitutions, *grammar );
|
||||||
|
|
||||||
|
while ( elemEnum.hasMoreElements() && !TestDestroy() )
|
||||||
|
{
|
||||||
|
const SchemaElementDecl& curElem = elemEnum.nextElement();
|
||||||
|
buildElementPrompt ( d, &curElem, substitutions );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NameIdPoolEnumerator<DTDEntityDecl>
|
return TestDestroy() ? XML_STATUS_ERROR : XML_STATUS_OK;
|
||||||
entityEnum = grammar->getEntityEnumerator();
|
}
|
||||||
while ( entityEnum.hasMoreElements() && !pThis->TestDestroy() )
|
|
||||||
{
|
|
||||||
const DTDEntityDecl &entity = entityEnum.nextElement();
|
|
||||||
d->entitySet.insert ( WrapXerces::toString ( entity.getName() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return pThis->TestDestroy() ? XML_STATUS_ERROR : XML_STATUS_OK;
|
int XMLCALL XmlPromptGenerator::externalentityrefhandler (
|
||||||
|
XML_Parser p,
|
||||||
|
const XML_Char *context,
|
||||||
|
const XML_Char *base,
|
||||||
|
const XML_Char *systemId,
|
||||||
|
const XML_Char *publicId )
|
||||||
|
{
|
||||||
|
// arg is set to user data in c'tor
|
||||||
|
XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) p;
|
||||||
|
PromptGeneratorData *d = pThis->d.get();
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
return pThis->parseGrammar
|
||||||
|
( d
|
||||||
|
, wxString::FromUTF8 ( publicId )
|
||||||
|
, wxString::FromUTF8 ( systemId )
|
||||||
|
, d->basePath
|
||||||
|
, Grammar::DTDGrammarType
|
||||||
|
);
|
||||||
|
|
||||||
#else // !PREFER_EXPAT_TO_XERCES_C
|
#else // !PREFER_EXPAT_TO_XERCES_C
|
||||||
|
|
||||||
|
@ -476,75 +518,36 @@ void XmlPromptGenerator::handleSchema (
|
||||||
{
|
{
|
||||||
if ( !d->isRootElement )
|
if ( !d->isRootElement )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wxString publicId, systemId;
|
||||||
|
|
||||||
// first check for XML Schema association
|
// first check for XML Schema association
|
||||||
const char **schemaAttr = ( const char ** ) attr; // now redundant; could use attr
|
const char **schemaAttr = ( const char ** ) attr; // now redundant; could use attr
|
||||||
wxString path;
|
|
||||||
for ( ; *schemaAttr; schemaAttr += 2 )
|
for ( ; *schemaAttr; schemaAttr += 2 )
|
||||||
{
|
{
|
||||||
// no namespace
|
// no namespace
|
||||||
if ( !strcmp ( *schemaAttr, "xsi:noNamespaceSchemaLocation" ) )
|
if ( !strcmp ( *schemaAttr, "xsi:noNamespaceSchemaLocation" ) )
|
||||||
{
|
{
|
||||||
path = wxString ( schemaAttr[1], wxConvUTF8 );
|
systemId = wxString ( schemaAttr[1], wxConvUTF8 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// with namespace -- check if this works
|
// with namespace -- check if this works
|
||||||
else if ( !strcmp ( *schemaAttr, "xsi:schemaLocation" ) )
|
else if ( !strcmp ( *schemaAttr, "xsi:schemaLocation" ) )
|
||||||
{
|
{
|
||||||
const char *searchIterator = * ( schemaAttr + 1 );
|
wxStringTokenizer tokens ( wxString ( schemaAttr[1], wxConvUTF8 ) );
|
||||||
while ( *searchIterator && *searchIterator != ' ' && *searchIterator != '\t' && *searchIterator != '\n' )
|
size_t count = tokens.CountTokens();
|
||||||
searchIterator++;
|
if ( count < 2 )
|
||||||
if ( *searchIterator )
|
return;
|
||||||
{
|
// TODO: Support multiple schemas
|
||||||
path = wxString ( searchIterator + 1, wxConvUTF8 );
|
publicId = tokens.GetNextToken();
|
||||||
break;
|
systemId = tokens.GetNextToken();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( path.empty() )
|
int ret = parseGrammar ( d, publicId, systemId, d->basePath
|
||||||
{
|
, Grammar::SchemaGrammarType );
|
||||||
|
if ( ret != XML_STATUS_OK )
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wxString schemaPath = PathResolver::run ( path, ( d->auxPath.empty() ) ? d->basePath : d->auxPath);
|
|
||||||
|
|
||||||
std::auto_ptr<XercesDOMParser> parser ( new XercesDOMParser() );
|
|
||||||
parser->setDoNamespaces ( true );
|
|
||||||
parser->setDoSchema ( true );
|
|
||||||
parser->setValidationSchemaFullChecking ( true );
|
|
||||||
|
|
||||||
if ( TestDestroy() )
|
|
||||||
{
|
|
||||||
XML_StopParser ( d->p, false );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Grammar *rootGrammar = parser->loadGrammar
|
|
||||||
( ( const XMLCh * ) WrapXerces::toString ( schemaPath ).GetData()
|
|
||||||
, Grammar::SchemaGrammarType
|
|
||||||
);
|
|
||||||
if ( !rootGrammar )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SchemaGrammar* grammar = ( SchemaGrammar* ) rootGrammar;
|
|
||||||
RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();
|
|
||||||
|
|
||||||
if ( !elemEnum.hasMoreElements() )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SubstitutionMap substitutions;
|
|
||||||
buildSubstitutionMap ( substitutions, *grammar );
|
|
||||||
|
|
||||||
while ( elemEnum.hasMoreElements() && !TestDestroy() )
|
|
||||||
{
|
|
||||||
const SchemaElementDecl& curElem = elemEnum.nextElement();
|
|
||||||
buildElementPrompt ( d, &curElem, substitutions );
|
|
||||||
}
|
|
||||||
|
|
||||||
d->grammarFound = true;
|
d->grammarFound = true;
|
||||||
XML_StopParser ( d->p, false );
|
XML_StopParser ( d->p, false );
|
||||||
|
|
|
@ -131,6 +131,12 @@ class XmlPromptGenerator : public WrapExpat, public wxThread
|
||||||
const XML_Char *att_type,
|
const XML_Char *att_type,
|
||||||
const XML_Char *dflt,
|
const XML_Char *dflt,
|
||||||
int isrequired );
|
int isrequired );
|
||||||
|
int parseGrammar (
|
||||||
|
PromptGeneratorData *d,
|
||||||
|
const wxString &publicId,
|
||||||
|
const wxString &systemId,
|
||||||
|
const wxString &baseFileName,
|
||||||
|
xercesc::Grammar::GrammarType type );
|
||||||
static int XMLCALL externalentityrefhandler (
|
static int XMLCALL externalentityrefhandler (
|
||||||
XML_Parser p,
|
XML_Parser p,
|
||||||
const XML_Char *context,
|
const XML_Char *context,
|
||||||
|
|
Loading…
Reference in New Issue