1

I am trying to decode one soap xml packet which is given below

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope>
<SOAP-ENV:Header><cwmp:ID SOAP-ENV:mustUnderstand="230">105</cwmp:ID>
</SOAP-ENV:Header>
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<cwmp:Request>
<Id>100</Id>
<RequestEvent SOAP-ENC:arrayType="cwmp:RequestStruct[3]">
    <RequestStruct>
        <Code>0 ZERO</Code>
        <Key></Key>
    </RequestStruct>
    <RequestStruct>
        <Code>1 ONE</Code>
        <Key></Key>
    </RequestStruct>
    <RequestStruct>
        <Code>2 TRAP</Code>
        <Key></Key>
    </RequestStruct>
</RequestEvent>
</cwmp:Request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

When I am trying to decode the packet using code

    BOOST_FOREACH(boost::property_tree::ptree::value_type &SL_vTemp, pt.get_child("SOAP-ENV:Envelope.SOAP-ENV:Body.cwmp:Request.RequestEvent")) 
{
    struct param obj;
    obj._Name.assign(SL_vTemp.second.get<std::string>("Code"));
    obj._Value.assign(SL_vTemp.second.get<std::string>("Key"))
}

I am getting exception that no node named EventCode. But if I am removing the attribute part "SOAP-ENC:arrayType="cwmp:RequestStruct[3]" from soap xml packet then the code is working fine. Thanks in advance.

van neilsen
  • 547
  • 8
  • 21
  • Boost.Property-tree is *not* a [general XML parser](http://stackoverflow.com/questions/14780665/14782136). Please stop treating it as such. – Nicol Bolas Jan 12 '16 at 21:57
  • @NicolBolas Here I am getting the request from CPE which is in soap xml format. So to get the parameters present in the soap xml, I have to decode the packet. For that decoding part I am using boost. Sample soap xml packet I have provided in the question. If you know any library which is better than the boost, please let me know. Thanks – van neilsen Jan 13 '16 at 06:06
  • 1
    @vanneilsen Nicol said "Don't use boost". Of course we know a better library. So do you: [use the force](http://stackoverflow.com/a/9387612/85371). I use Pugi. It's good and header only. – sehe Jan 13 '16 at 07:50
  • Thanks for sharing the link. – van neilsen Jan 13 '16 at 08:36

1 Answers1

1

You should surround the block with a condition to check that it's the RequestStruct element:

    if (SL_vTemp.first == "RequestStruct") 
    {
        auto code = SL_vTemp.second.get<std::string>("Code");
        auto key = SL_vTemp.second.get<std::string>("Key");

        std::cout << "code:" << code << " key:" << key << "\n";
    }

Because attributes are under the <xmlattr> prefix there.

Live On Coliru

#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>

extern std::string const sample;

int main() {
    boost::property_tree::ptree pt;

    {
        std::istringstream iss(sample);
        read_xml(iss, pt);
    }

    BOOST_FOREACH (boost::property_tree::ptree::value_type &SL_vTemp,
                   pt.get_child("SOAP-ENV:Envelope.SOAP-ENV:Body.cwmp:Request.RequestEvent")) 
    {
        if (SL_vTemp.first == "RequestStruct") 
        {
            auto code = SL_vTemp.second.get<std::string>("Code");
            auto key = SL_vTemp.second.get<std::string>("Key");

            std::cout << "code:" << code << " key:" << key << "\n";
        } else
        {
            std::cout << "skipped: '" << SL_vTemp.first << "'\n";
        }
    }
}

std::string const sample = R"(
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope>
    <SOAP-ENV:Header><cwmp:ID SOAP-ENV:mustUnderstand="230">105</cwmp:ID>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <cwmp:Request>
            <Id>100</Id>
            <RequestEvent SOAP-ENC:arrayType="cwmp:RequestStruct[3]">
                <RequestStruct>
                    <Code>0 ZERO</Code>
                    <Key>key0</Key>
                </RequestStruct>
                <RequestStruct>
                    <Code>1 ONE</Code>
                    <Key>key1</Key>
                </RequestStruct>
                <RequestStruct>
                    <Code>2 TRAP</Code>
                    <Key>key2</Key>
                </RequestStruct>
            </RequestEvent>
        </cwmp:Request>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
)";

Prints

skipped: '<xmlattr>'
code:0 ZERO key:key0
code:1 ONE key:key1
code:2 TRAP key:key2
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Thanks for the great info. After making the changes code is working fine. But can you please tell me that, why the code was showing exception previously? – van neilsen Jan 13 '16 at 06:36
  • That's in the answer. First sentence explains what to do. Second sentence explains _why_. If you didn't get it, look at the output where it says [``](http://www.boost.org/doc/libs/1_60_0/doc/html/property_tree/parsers.html#property_tree.parsers.xml_parser). Does the `` node have a child named `"Code"`? – sehe Jan 13 '16 at 07:48
  • That's the reason you got the exception :) – sehe Jan 13 '16 at 08:30