Click here to Skip to main content
15,887,746 members
Articles / Programming Languages / C++
Tip/Trick

Hints for Using Poco Project XML Configuration

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
8 Sep 2014CPOL1 min read 12.6K   5   1
The Poco XML Configuration has thrown up a number of (unanswered) questions across the inter-webs. This tip is intended to answer the commonest of them all, how to read multiple tags within an XML container tag

Introduction

When using Poco's XML Configuration, some things are obvious and we don't see questions asked because the documentation is adequate. However, going to the next logical step is not often obvious resulting in many unanswered FAQs around web forums. In this post, we explore that next step and provide workable solutions as a template going forward.

Background

The Poco documentation provides an obvious solution to the following problem.

Given this XML in file hello.xml:

XML
<root>
  <headers>
    <header>Hello World</header>
  </headers>
</root>

Then the Poco XML Configuration can be used thus:

C++
#include <string>
#include <Poco/AutoPtr.h>
#include <Poco/Util/XMLConfiguration.h>

using namespace std;
using namespace Poco;
using namespace Poco::Util

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

    AutoPtr apXmlConf(new XMLConfiuration("hello.xml"));
    string header = apXmlConf->getString("headers.header");
    cout << header << endl;
    return 0;
}

So far so good. The Poco documentation explains this well. However, the problem arises when the XML looks like this:

XML
<root>
    <headers>
        <header>Hello</header>
        <header>World</header>
    </headers>
</root>

Iterating over multiple rows of data using XMLConfiguration is generally the FAQ seen most often.

One solution is as follows:

C++
#include <string>
#include <sstream>
#include <Poco/Exception.h>
#include <Poco/AutoPtr.h>
#include <Poco/Util/XMLConfiguration.h>

using namespace std;
using namespace Poco;
using namespace Poco::Util

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

    int counter = 0;
    AutoPtr apXmlConf(new XMLConfiuration("hello.xml"));
    try {
        while(1) { // Loop breaks by Poco exception
            stringstream tag;
            tag << "headers.header[" << counter++ << "]";
            string header = apXmlConf->getString(tag.str());
            cout << header << " ";
        }
    } catch(NotFoundException& e) { (void)e; }
    cout << endl;
    return 0;
}

Points of Interest

Essentially the XMLConfiguration::get* functions require a string and most devs use a string literal. However, when iterating multiple contained tags, you need to provide an index so one needs to construct it as it loops over the data. On this occasion, I used a std::stringstream.

Note, in the example, the while loop goes forever and is broken by a Poco::NotFoundException so you will need to actually wrap the loop in a try/catch and expect that to break the while loop.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Solarwinds MSP, Stellar Technologies Ltd
United Kingdom United Kingdom
Hardware, Software Engineer and Systems Architect for more than 25 years cover topics from C/C++, OS (Linux and FreeBSD drivers), MySQL, Apache, PHP and embedded systems using C/C++ and Assembler.

Comments and Discussions

 
QuestionSome mistakes in the code Pin
David Belle14-Oct-15 14:53
David Belle14-Oct-15 14:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.