Boost logo

Boost :

Subject: [boost] XML Digester
From: Themis Vassiliadis (tvassiliadis_at_[hidden])
Date: 2009-01-05 14:43:33


Hi All,

I'm finishing a preliminary version of a class with similar behavior
like Java Digester.

In this class the developer defines triggers witch will be fired when
specific tags are found from XML file.

Let me explain better with an example:

A simple approach will be to use the following Digester in the
following way to set up the parsing rules, and then process an input
file containing this document:

        
        
        digester = new boost::xml_digester::xml_digester((std::istream*)&st);

        digester->setValidating( false );

        digester->addObjectCreate<classFoo>("foo");
        digester->addObjectCreate<classBar>("foo/bar");

        digester->addCallMethod<classBar>("foo/bar/prop1", &classBar::setProp1);
        digester->addSetProperty<classBar>("foo/bar/prop2", &classBar::prop2);

        digester->addSetNext<classFoo>("foo/bar", &classFoo::addBar);

        digester->parse();

        ....

       class classBar {
           std::string prop1;
       public:
           std::string prop2;

           void setProp1(std::string value) {
               prop1 = value;
           }
       };

       class classFoo {
           std::vector<classBar*>obj_bars;
       public:
           void addBar(void *instance) {
                obj_bars.push_back((classBar*)instance);
           }
       };

XML:

<?xml version='1.0' encoding='UTF-8'?>
<foo>
        <bar>
                <prop1>xxxxxx</prop1>
                <prop2>yyyyyy</prop2>
        </bar>
        <bar>
                <prop1>zzzzzz</prop1>
                <prop2>kkkkkk</prop2>
        </bar>
</foo>

In order, these rules do the following tasks:

1. When a nested <foo> element is encountered, create a new instance
of "classFoo" and push it on to the object stack. At the end of the
<foo> element, this object will be popped off of the stack.
2. When a nested <bar> element is encountered, create a new instance
of "classBar" and push it on to the object stack. At the end of the
<bar> element, this object will be popped off of the stack (i.e. after
the remaining rules matching foo/bar are processed).
3. Cause method setProp1 of class "classBar" to be called each time
"prop1" is loaded. A std::string type parameter is passed as the
value.
4. Cause property "prop2" of class "classBar" to be set each time
"prop2" is loaded. The property must have public scope and its type
must be std::string.
5. Cause the "addBar" method of class "classFoo" to be called, passing
the instance of "classBar" created in the step 2. This rule allow to
establish a parent/child relationship between "classFoo" and
"classBar".

I think that with these features the developer might do everything
that he need to parse XML files to objects in 90% of cases. Of course
the Java Digester is more powerful and complex and for next releases
we can improve it.

Regards,

-- 
Themis Vassiliadis

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk