boost中的属性是如何解析的?肥皂xml解析?

Posted

技术标签:

【中文标题】boost中的属性是如何解析的?肥皂xml解析?【英文标题】:How are attributes parsed in boost? Soap xml parsing? 【发布时间】:2016-01-12 15:33:17 【问题描述】:

我正在尝试解码下面给出的一个肥皂 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]”,那么代码工作正常。 提前致谢。

【问题讨论】:

Boost.Property-tree 不是 general XML parser。请停止这样对待它。 @NicolBolas 在这里,我收到了来自 CPE 的请求,该请求采用的是 soap xml 格式。因此,要获取soap xml 中存在的参数,我必须对数据包进行解码。对于那个解码部分,我正在使用 boost。我在问题中提供的示例肥皂 xml 数据包。如果您知道任何比 boost 更好的库,请告诉我。谢谢 @vanneilsen Nicol 说“不要使用 boost”。当然,我们知道一个更好的库。你也是:use the force。我用普吉。很好,只有标题。 感谢分享链接。 【参考方案1】:

你应该在块周围加上一个条件来检查它是否是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";
    

因为属性在&lt;xmlattr&gt; 前缀下。

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

打印

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

【讨论】:

感谢您提供的重要信息。进行更改后,代码工作正常。但是你能告诉我,为什么之前的代码会显示异常吗? 答案就在于此。第一句话解释了要做什么。第二句解释了为什么。如果您没有得到它,请查看显示&lt;xmlattr&gt; 的输出。 &lt;xmlattr&gt; 节点是否有一个名为 "Code" 的子节点? 这就是你得到异常的原因:)

以上是关于boost中的属性是如何解析的?肥皂xml解析?的主要内容,如果未能解决你的问题,请参考以下文章

使用 boost 属性树解析 XML

Boost属性树xml解析No such node()

使用属性树在 boost 中解析 xml

如何手动创建具有 XML 属性的 boost ptree?

JAXM 肥皂消息解析

如何使 boost ptree 以相同的方式解析 xml 和 json?