使用c ++中的xerces的XML SAX解析器

时间:2013-01-29 14:29:40

标签: c++ xml xml-parsing xerces xerces-c

    #include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/util/XMLString.hpp>
#include <conio.h>
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/XMLString.hpp>
#include <iostream>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
using namespace std;
using namespace xercesc;


class ErnstSax2Handler : public DefaultHandler 
{
public:
ErnstSax2Handler(void);
virtual ~ErnstSax2Handler(void);

void startElement(
    const   XMLCh* const    uri,
    const   XMLCh* const    localname,
    const   XMLCh* const    qname,
    const   Attributes&     attrs
);
void endElement(
    const   XMLCh* const    uri,
    const   XMLCh* const    localname,
    const   XMLCh* const    qname
);
void characters(
    const   XMLCh* const    chars,
    const   XMLSize_t       length
);

void fatalError(const SAXParseException&);

protected:
// define variables to save the state
};

void ErnstSax2Handler::startElement(const   XMLCh* const    uri,
                        const   XMLCh* const    localname,
                        const   XMLCh* const    qname,
                        const   Attributes&     attrs)
{
char* name = XMLString::transcode(localname);
cout<<name;
// ...
XMLString::release(&name);
}
void ErnstSax2Handler::endElement(
                const   XMLCh* const    uri,
                const   XMLCh* const    localname,
                const   XMLCh* const    qname)
{
char* name = XMLString::transcode(localname);

//...
XMLString::release(&name);
}
void ErnstSax2Handler::fatalError(const SAXParseException& exception)
{
char* message = XMLString::transcode(exception.getMessage());
cout << "Fatal Error: " << message
     << " at line: " << exception.getLineNumber()
     << endl;
XMLString::release(&message);
}
void ErnstSax2Handler::characters(
const   XMLCh* const    chars,
const   XMLSize_t       length
)
{
 // This is called when the parser is reading text.
 // You will need to save what state you are in via
 // startElement / endElement.
 }


int main () {

    try {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Error during initialization! :\n";
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return 1;
    }

    char* xmlFile = "test.xml";
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
    parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);   // optional

    DefaultHandler* defaultHandler = new DefaultHandler();
    xercesc::ContentHandler* h  = new DefaultHandler();

    parser->setContentHandler(h);
    parser->setErrorHandler(defaultHandler);

    try {
        parser->parse(xmlFile);
    }
    catch (const XMLException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return -1;
    }
    catch (const SAXParseException& toCatch) {
        char* message = XMLString::transcode(toCatch.getMessage());
        cout << "Exception message is: \n"
             << message << "\n";
        XMLString::release(&message);
        return -1;
    }
    catch (...) {
        cout << "Unexpected Exception \n" ;
        return -1;
    }


    getch();
    delete parser;
    delete defaultHandler;
    return 0;
}

当我在visual studio 2010中运行上面的代码时,它不会在屏幕上打印任何元素名称及其内容。任何人都可以帮助我如何调用任何处理程序以及如何从元素(节点)获取内容? 提前完成。

2 个答案:

答案 0 :(得分:2)

你正在创建默认处理程序并将它们传递给解析器,而这不是你想要做的,因为我猜:

DefaultHandler* defaultHandler = new DefaultHandler();
xercesc::ContentHandler* h  = new DefaultHandler();

parser->setContentHandler(h);
parser->setErrorHandler(defaultHandler);

相反,您需要创建自己的类:

DefaultHandler* defaultHandler = new ErnstSax2Handler();
xercesc::ContentHandler* h  = new ErnstSax2Handler();

希望这有帮助。

答案 1 :(得分:0)

如果有人想编译此代码:您必须从类中删除默认构造函数的声明,或者您必须提供实现。

例如

public:
//ErnstSax2Handler(void);
//virtual ~ErnstSax2Handler(void);