4

我正在使用 Xerces C++ DOM 解析器来读取 Visual C++ 项目中的一些 XML 文件。我有一个类,它的parse()方法应该读取和验证我的 XML 源文件。这是该方法的样子:

#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;
}

文档说,如果路径没有解析为文件,LocalFileInputSource构造函数将抛出一个。XMLException但是,我可以使用任意字符串调用此方法,并且它会执行到最后而不会引发任何异常。我究竟做错了什么?

此外,says a的文档是它可以抛出的异常类型之一。我觉得这很令人困惑,因为据我了解 DOM 和 SAX 解析器是两种不同的动物,那么为什么 DOM 解析器会抛出 SAX 异常呢?XercesDOMParser::parse()SAXException

4

4 回答 4

4

请参阅ErrorHandler文档。

您必须声明和定义一个继承ErrorHandler并实现其虚拟方法的类(或者您可以扩展HandlerBase该类)。

然后,您必须调用setErrorHandler您的解析器实例,并传递您的错误处理程序的实例,即pDOMParser_->setErrorHandler(your_handler_instance).

Xerces-C++ 主干示例的用法示例:SAXPrint.cpp 的第 231-233 行

更新:下面的自定义错误处理程序示例。

#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);
        }
};
于 2010-07-12T22:54:25.123 回答
0

我不认为文档说明了您认为它会做什么,而是说它会;扔:

XMLException 如果路径是相对的并且没有正确解析为文件。

如果您选择接受它,您的任务是找出“相对”的含义。恐怕我已经很多年没有使用 Xerces(尽管它非常称职)——我更喜欢使用小型、简单的 SAX 解析器来构建我自己的模型而不是使用 DOM,并且不记得文件名是如何工作的.

而且我认为您可能会遇到 SAX 异常的原因是 Xerces 使用 SAX 来构建其 DOM。

于 2010-07-12T23:00:56.603 回答
0

2.8 Doc(您已链接)说,

XMLException如果路径是相对的并且没有正确解析为文件

你真的在使用相对路径吗? 也许这曾经是某些平台特定情况的情况,但我看不出在 Xercese 2.7 中出现这种情况(我碰巧有代码)。

查看 LocalFileFormatTarget 它可以为“CouldNotOpenFile”抛出异常,但它没有记录为引发异常。

您使用的是哪个版本的 xerces?

打开文件进行读取/解析看起来可能会引发类型为“CouldNotReadFromFile”的丢失文件的异常。但这可能与 Vanni 所说的错误处理有关。

于 2010-07-12T23:05:38.887 回答
0

我知道这是旧的,但是确实我发现如果找不到文件就会XercesDOMParser抛出一个SAXParseException。不需要自定义错误处理程序,只需捕获该异常。

于 2018-01-17T21:09:29.063 回答