如何在boost中解析属性?Soap xml解析

How are attributes parsed in boost? Soap xml parsing?

本文关键字:属性 Soap xml 解析 boost      更新时间:2023-10-16

我正在尝试解码下面给出的一个soap xml数据包

<?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>

当我试图使用代码解码数据包时

    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"))
}

我得到的异常是没有名为EventCode的节点。但是,如果我正在从SOAP xml数据包中删除属性部分"SOAP-ENC:arrayType="cwmp:RequestStruct[3]",那么代码工作正常。提前谢谢。

您应该用一个条件包围块,以检查它是否是RequestStruct元素:

    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";
    }

因为属性在<xmlattr>前缀下。

在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>
)";

打印

skipped: '<xmlattr>'
code:0 ZERO key:key0
code:1 ONE key:key1
code:2 TRAP key:key2