C++ sax2 parser problem

假装没事ソ 提交于 2019-12-24 14:26:27

问题


I want to parse an XML file. My XML looks like this:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overrides in this file. -->

<configuration>
<property>
  <name>tracker</name>
  <value>localhost:58303</value>
  <description>The host and port that the MapReduce job tracker runs
  at.  If "local", then jobs are run in-process as a single map
  and reduce task.
  </description>
</property>

</configuration>

I use the sxx 2 parser to parse this file. I want to chain the value of an element<value> from localhost to 192.168.0.5. I wrote some C++ code which looks like this:

#include <SAX2XMLReader.hpp>
#include <XMLReaderFactory.hpp>
#include <DefaultHandler.hpp>
#include <XMLString.hpp>"
#include <iostream>

using namespace std;
using namespace xercesc;

int main (int argc, char* args[]) {

    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 = "/home/project/conf/mapred.xml";
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
    parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);   // optional

    DefaultHandler* defaultHandler = new DefaultHandler();
    parser->setContentHandler(defaultHandler);
    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;
    }

    delete parser;
    delete defaultHandler;
    return 0;
}

The code compiles. What I want to know is how do I change the value in the XML file? How do I go about writing a handler for this and use it in my code? Can anybody explain what I need to do to successfully change a value in the XML file?


回答1:


You can't change the value with the SAX handler AFAIK. Generally I define both a sax handler to convert from xml to some c++ object, as well as a document builder to convert from object to xml.

A general approach is as follows: use the sax handler with an xml parser to get an object, modify the object, and then use the document builder to save the xml file. Have a look at the DomWriter class. There was also an example that shows you how to build an XML document with xerces.

Maybe you could also just search for the tag you want to chain to the value, and do a string replace if you want to avoid the whole XML conversion process (dependent on your document structure, etc).

Edit: There are two aspects to XML: parsing and building. When it comes to parsing, you have two options: using sax or dom. Sax parsing involves you writing a handler. The XML doc is scanned and the handler gets called as an element in your XML doc is encountered.

E.G. "Saw the Foo opening tag"

And then later "Saw the Foo closing tag"

When your handler is called, you get the opportunity to act. Typically you would have some object as a member of your handler, and you would call setters with the value obtained from the xml document. Once the parsing is complete, you could then e.g. call a getter on the handler to retrieve the object that now has set values. Using sax, you cannot modify the document with the sax handler.

A DOM handler works with the whole xml document in memory. I haven't used a xerces DOM parser before, but I'm sure there must be an example for that. Since DOM has the whole document in memory, you might even be able to change the document on the fly without going through the sax parsing and rebuilding I outlined above. I would definitely investigate the DOM parser examples before using SAX.



来源:https://stackoverflow.com/questions/5428498/c-sax2-parser-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!