Xerces C++:不存在文件时没有错误

4

我正在使用Xerces C++ DOM解析器来读取一些XML文件,这些文件在Visual C++项目中。我有一个带有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 异常。然而,我可以使用任意字符串调用此方法,并且执行到最后时没有引发任何异常。我做错了什么吗?

此外,XercesDOMParser::parse() 的文档中说,它可以抛出 SAXException 异常之一。我觉得这很令人困惑,因为据我所知,DOM 和 SAX 解析器是两种不同的工具,那么为什么 DOM 解析器会抛出 SAX 异常呢?

4个回答

4
请查看ErrorHandler文档。
您需要声明和定义一个继承自ErrorHandler并实现其虚拟方法的类(或者您可以扩展HandlerBase类)。
然后,您必须在解析器实例上调用setErrorHandler,并传递您的错误处理程序的实例,即pDOMParser_->setErrorHandler(your_handler_instance)
示例用法来自Xerces-C ++ trunk samples: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);
        }
};

我会尝试一下。有趣的是,到目前为止我还没有遇到任何关于Xerces的教程说需要这样做。所有的教程都很高兴地在XercesDOMParser :: parse()周围放置try ... catch来捕获错误。 - Praetorian
@praetorian20: 我刚刚编辑了我的帖子,并附上了一个自定义错误类实现的示例。 - Vanni Totaro
太好了!非常感谢您提供的示例和SAXPrint示例链接。 - Praetorian

0

我认为文档并没有说出你所想的,它说会抛出:

XMLException 如果路径是相对的且无法正确解析到文件。

如果您选择接受此任务,您的任务就是找出“相对”是什么意思。恐怕我已经多年没有使用Xerces了(尽管它非常有能力)-我更喜欢使用小型、简单的SAX解析器来构建自己的模型,而不是使用DOM,并且不记得文件名的工作原理。

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


玩一下答案快照? - Greg Domjan
正如我回复Greg的评论所说,我已经尝试过相对路径和绝对路径。在相对路径的情况下,Xerces正确地将其解析为绝对路径(从观察窗口中查看srcFile变量的内容),但是当然,指定路径中的文件是否存在并不重要。 - Praetorian

0

2.8文档(你提供的链接)中说:

XMLException 如果路径是相对路径并且无法正确解析到文件,则会出现异常

你是否真的在使用相对路径?也许这曾经是某些特定平台的情况,但我无法看出在Xercese 2.7中引发了什么异常(我刚好有这个代码)。

查看LocalFileFormatTarget,它可能会因'CouldNotOpenFile'而抛出异常,但它没有记录为引发异常。

你正在使用哪个版本的Xerces?

打开文件进行读取/解析似乎可能会因缺少文件而引发'CoudNotReadFromFile'类型的异常。但可以通过Vanni所谈论的错误处理来捕获该异常。


我尝试了相对路径和绝对路径,但都没有抛出错误。 - Praetorian

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接