2010-12-07 53 views
1

我正在使用Xerces-C++(版本2.6.1)SAX2分析器來驗證XML,如下面的文檔。 (這是MSML - 媒體服務器標記語言爲RFC 5707定義。)使用Xerces驗證未定義模式的XML

<?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> 

的RFC提供XML schemas for validating MSML,我試圖使用它們在一個Xerces SAX2解析器一起驗證和解析MSML。解析工作正常,但我沒有得到任何驗證。我懷疑我的問題可能是因爲我試圖驗證的MSML不包括schemaLocation屬性,但我無法控制我收到的XML - 我想強制使用msml.xsd進行驗證是否schemaLocationnoNamespaceSchemaLocation(或者什麼也不是)在XML中提供。

我的代碼類似於以下內容。

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); 

回答

2

而且隨着許多徘徊和試錯,我最終發現了問題。將驗證錯誤報告給傳遞給解析器的ErrorHandler上的error回調。 schemaLocation屬性沒有問題。

隨着這個問題的解決,並且增加了XML語法的緩存以提高性能,現在代碼如下所示。

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);