2010-07-12 24 views
3

我正在使用Xerces C++ DOM解析器讀取Visual C++項目中的一些XML文件。我有一個parse()方法,應該讀取和驗證我的XML源文件。這是該方法的樣子:Xerces C++:對於不存在的文件沒有錯誤

#include <xercesc/util/PlatformUtils.hpp> 
#include <xercesc/dom/DOM.hpp>   
#include <xercesc/parsers/XercesDOMParser.hpp> 
#include <xercesc/framework/LocalFileInputSource.hpp> 

using namespace std; 
XERCES_CPP_NAMESPACE_USE 

unsigned long RulesParser::parse(const wstring &xmlFile) 
{ 
    if(parserInitialized_ == false) { 
    try { 
     XMLPlatformUtils::Initialize(); /* initialize xerces */ 
    } catch(XMLException const &e) { 
     return Status::PARSER_INIT_FAIL; 
    } 
    } 
    parserInitialized_ = true;   /* indicate xerces has been 
              successfully initialized */ 

    if(pDOMParser_ != NULL) { 
    delete pDOMParser_; 
    } 
    pDOMParser_ = new XercesDOMParser; /* create a DOM parser instance */ 
    /* set xerces options */ 
    pDOMParser_->setDoNamespaces(true); /* enable namespace processing */ 
    pDOMParser_->setDoSchema(true);  /* enable schema processing */ 
    pDOMParser_->setValidationScheme(XercesDOMParser::Val_Always); /* parser always validates */ 
    pDOMParser_->setValidationSchemaFullChecking(true); /* enable full schema checking */ 

    auto_ptr<LocalFileInputSource> srcFile; /* XML source file loader */ 

    try { 
    srcFile.reset(new LocalFileInputSource(xmlFile.c_str())); 

    } catch(const XMLException &e) { 
    return Status::XML_SOURCE_LOAD_ERROR; 
    } 

    /* parse the file */ 
    try { 
    pDOMParser_->parse(*srcFile); 

    } catch(const XMLException &e) {  
    return Status::XML_SOURCE_PARSE_ERROR; 

    } catch(const DOMException &e) { 
    return Status::XML_SOURCE_PARSE_DOM_ERROR; 
    } 

    return Status::OK; 
} 

documentationLocalFileInputSource說,構造函數將拋出一個XMLException如果路徑沒有解決到一個文件中。但是,我可以用任何任意字符串調用此方法,並且在不引發任何異常的情況下執行到最後。我究竟做錯了什麼?

另外,documentationXercesDOMParser::parse()表示SAXException是它可以拋出的異常類型之一。我覺得這很令人困惑,因爲從我所瞭解的DOM和SAX解析器是2種不同的動物,那麼爲什麼DOM解析器會拋出一個SAX異常?

回答

4

請參閱ErrorHandler文檔。

您必須聲明並定義一個繼承自ErrorHandler並實現其虛擬方法的類(或者您可以擴展HandlerBase類)。

然後,您必須在您的解析器實例上調用setErrorHandler來傳遞錯誤處理程序的實例,即pDOMParser_->setErrorHandler(your_handler_instance)

來自Xerces-C++主幹樣本的示例用法:rows 231-233 of SAXPrint.cpp

更新:下面的自定義錯誤處理程序的示例。

#include <iostream> 
#include <xercesc/sax/HandlerBase.hpp> 
XERCES_CPP_NAMESPACE_USE 

class CustomErrorHandler : public HandlerBase 
{ 

    public: 

     CustomErrorHandler() {} 

     void error(const SAXParseException& e) 
     { 
      handler(e); 
     } 

     void fatalError(const SAXParseException& e) 
     { 
      handler(e); 
     } 

     void warning(const SAXParseException& e) 
     { 
      handler(e); 
     } 

    private: 

     void handler(const SAXParseException& e) 
     { 
      char* message = XMLString::transcode(e.getMessage()); 

      cerr << "line " << e.getLineNumber() 
       << ", column " << e.getColumnNumber() 
       << " -> " << message << "\n\n"; 

      XMLString::release(&message); 
     } 
}; 
+0

我會試試這個。有趣的是,我還沒有遇到任何Xerces教程,說這需要完成。他們都樂於把'try ... catch'放在'XercesDOMParser :: parse()'附近來捕獲錯誤。 – Praetorian 2010-07-12 23:17:54

+0

@''praetorian20':我剛剛編輯了一篇自定義錯誤類實現示例。 – 2010-07-12 23:31:16

+0

工作!非常感謝您的示例,並將鏈接發佈到'SAXPrint'示例。 – Praetorian 2010-07-13 00:08:29

0

我不認爲文檔說明了你的看法,它說它會;拋出:

XMLException如果路徑是相對 而不能正常解析爲 文件。

如果您選擇接受它,您的任務是找出「相對」的含義。恐怕我沒有多年使用過Xerces(儘管它非常勝任) - 我更喜歡使用小而簡單的SAX解析器來構建我自己的模型,而不是使用DOM,並且不記得文件名是如何工作的。

我認爲你可能會得到SAX異常的原因是Xerces使用SAX來構建它的DOM。

+0

答案快照有點有趣嗎? – 2010-07-12 23:06:37

+0

當我回復Greg的評論時,我嘗試過相對和絕對的路徑。在相對路徑的情況下,Xerces正確地將其解析爲絕對路徑(通過查看監視窗口中的'srcFile'變量內容),但當然,路徑中指定的文件是沒有區別的是否存在。 – Praetorian 2010-07-12 23:16:03

0

2.8文件(已連接)表示,

XMLException如果路徑是相對沒有正確解析到一個文件

你實際使用相對路徑? 也許這是一些特定於平臺的情況,但我無法看到Xercese 2.7中出現這種情況(我碰巧遇到了這種情況)。

看着LocalFileFormatTarget,它可以爲'CouldNotOpenFile'拋出異常,但它沒有記錄爲引發異常。

您使用的是什麼版本的xerces?

打開文件以進行讀取/解析看起來好像可能會爲類型爲'CouldNotReadFromFile'的缺失文件引發異常。但是,這可能會被Vanni談論的錯誤處理所困擾。

+0

我已經嘗試過相對和絕對,他們都沒有發生錯誤。 – Praetorian 2010-07-12 23:13:25

0

我知道這是舊的,但是的確的,我發現XercesDOMParser拋出一個SAXParseException如果找不到文件。不需要自定義錯誤處理程序,只需捕獲該異常。

相關問題