2010-12-07 36 views
1

J'utilise l'analyseur SAX2 de Xerces-C++ (version 2.6.1) pour valider du code XML tel que le document ci-dessous. (Ceci est MSML - Media Server Markup tel que défini dans RFC 5707.)Validation de XML ne définissant pas de schéma avec Xerces

<?xml version="1.0" encoding="UTF-8"?> 
<msml version="1.1"> 
    <createconference name="example"> 
     <audiomix> 
     <n-loudest n="3"/> 
     <asn ri="10s"/> 
     </audiomix> 
    </createconference> 
</msml> 

Le RFC fournit XML schemas for validating MSML, et je suis en train de les utiliser conjointement avec l'analyseur SAX2 Xerces pour valider et analyser MSML. L'analyse fonctionne correctement, mais je ne parviens pas à obtenir de validation. Je suspecte que mon problème est dû au fait que le MSML que j'essaie de valider n'inclut pas d'attribut schemaLocation, mais je ne peux pas contrôler le code XML que je reçois - je souhaite forcer la validation en utilisant le fichier msml.xsd, soit schemaLocation ou noNamespaceSchemaLocation (ou rien) est fourni dans le XML.

Mon code est similaire au suivant.

SAX2XMLReader* parser = XMLReaderFactory::createXMLReader(); 

// Enable the parser's schema support 
parser->setFeature(XMLUni::fgXercesSchema, true); 

// Schema validation requires namespace processing to be turned on. 
parser->setFeature(XMLUni::fgSAX2CoreValidation, true); 
parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true); 

// Define the location of the MSML schema. 
XMLCh* schemaLocation = XMLString::transcode("/directory/path/msml-core.xsd"); 
parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, 
        schemaLocation); 

// MSMLHandler is defined elsewhere and inherits from xercesc/sax2/DefaultHandler 
// It overrides startElement and fatalError. 
MxMSMLHandler* msmlHandler = new MSMLHandler(xiSessionID, xoMSMLResponse); 
parser->setContentHandler((ContentHandler*) msmlHandler); 
parser->setErrorHandler((ErrorHandler*) msmlHandler); 

// Do the parse 
parser->parse(*xmlInputSource); 

Répondre

2

Et avec beaucoup de flambage et d'essais et d'erreurs, j'ai finalement trouvé les problèmes. Les erreurs de validation sont signalées au rappel error sur le ErrorHandler transmis à l'analyseur. Il n'y avait aucun problème avec l'attribut schemaLocation.

Avec cela fixé, et en ajoutant la mise en cache de la grammaire XML pour améliorer les performances, le code est maintenant comme suit.

SAX2XMLReader* parser = XMLReaderFactory::createXMLReader(); 

// Enable the parser's schema support 
parser->setFeature(XMLUni::fgXercesSchema, true); 

// Schema validation requires namespace processing to be turned on. 
parser->setFeature(XMLUni::fgSAX2CoreValidation, true); 
parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true); 

// Cache the XML grammar and use it for subsequent parses. 
mParser->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true); 
mParser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); 

// Define the location of the MSML schema. 
XMLCh* schemaLocation = XMLString::transcode("/directory/path/msml-core.xsd"); 
parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, 
        schemaLocation); 

// MSMLHandler is defined elsewhere and inherits from xercesc/sax2/DefaultHandler 
// It overrides startElement, fatalError *and error*. 
MxMSMLHandler* msmlHandler = new MSMLHandler(xiSessionID, xoMSMLResponse); 
parser->setContentHandler((ContentHandler*) msmlHandler); 
parser->setErrorHandler((ErrorHandler*) msmlHandler); 

// Do the parse 
parser->parse(*xmlInputSource);