Boost read_xml 问题解析字符串?

Posted

技术标签:

【中文标题】Boost read_xml 问题解析字符串?【英文标题】:Boost read_xml issue parsing string? 【发布时间】:2015-05-08 20:50:07 【问题描述】:

我正在尝试解析此字符串并检索“sid”和“Type”。我有以下代码。它在get_child 行崩溃,我不完全确定为什么......

const boost::property_tree::ptree& empty_ptree()
static boost::property_tree::ptree t;
return t;


int _tmain(int argc, _TCHAR* argv[])

struct SXMLElements

    std::string strSessionId;
    unsigned int uiTypeOfNotification;
;

std::string strXMLText = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n" 
"<NotificationSet vers=\"1.0\" svcid=\"session\" notid=\"42\">\r\n" "<Notification><![CDATA[<SessionNotification vers=\"1.0\" notid=\"42\">\r\n"
"<Session sid=\"sdfkljdsfkjjsf\">\r\n" "<Property name=\"CharSet\" value=\"UTF-8\"></Property>\r\n" 
"</Session>\r\n" "<Type>5</Type>\r\n" 
"<Time>324242</Time>\r\n" 
"</SessionNotification>]]></Notification>\r\n" 
"</NotificationSet>";

//// Parse the HTTP header Status line.
std::stringstream ss( strXMLText );

boost::property_tree::ptree xmlResponse;
//if (strXMLText.size() > 0)
//
std::istringstream isResponse (strXMLText);
boost::property_tree::read_xml(isResponse, xmlResponse);
SXMLElements sXmlElem;
//const boost::property_tree::ptree & formats = xmlResponse.get_child("NotificationSet.Notification.Session", empty_ptree());
BOOST_FOREACH( boost::property_tree::ptree::value_type const& v, xmlResponse.get_child("NotificationSet.Notification.SessionNotification.Session") )

    sXmlElem.strSessionId = xmlResponse.get<std::string>("<xmlattr>.sid", "");
    sXmlElem.uiTypeOfNotification = xmlResponse.get<unsigned int>("Type", 0);
    //  

//

return 0;

谁能发现我做错了什么?

【问题讨论】:

呵呵。对于编辑,我还提供了答案:) 【参考方案1】:

Session 属性 cd=""\"o=rrs,o=ces,maxtime=""\"64""\" 解码为

cd="o=rrs,o=ces,maxtime="64" 

这会留下无效的 XML。

无论如何,所有的""\" 都可以只替换为\"

除此之外,一个简单的测试表明 Boost Property Tree 不喜欢 &lt;![CDATA[]]&gt; 部分,这是正确的:What does <![CDATA[]]> in XML mean?

在 XML 文档或外部解析实体中,CDATA 部分是元素内容的一部分,被标记为解析器仅将其解释为字符数据,而不是标记。 wikipedia

摘要

Boost Property Tree 不是 XML 解析库 (xml parsing using boost) CDATA 段是不是 XML(因此即使使用 XML 库,您也不应该期望直接解析它)

Live On Coliru

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

int main()

    std::string const strXMLText = R"(<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <NotificationSet vers="1.0" svcid="session" notid="42">
        <Notification><SessionNotification vers="1.0" notid="42">
                <Session sid="sdfkljdsfkjjsf" stype="user" cid="uid=1,u=People,dc=r,dc=c" cd="o=rrs,o=ces,maxtime=64" maxidle="24">
                    <Property name="CharSet" value="UTF-8"></Property>
                    <Property name="ed" value="xxx"></Property>
                    <Property name="Sdle" value="sdl:asdadsad"></Property>
                </Session>
                <Type>5</Type>
                <Time>324242</Time>
        </SessionNotification></Notification>
    </NotificationSet>
    )";

    //// Parse the HTTP header Status line.
    std::stringstream ss(strXMLText);

    boost::property_tree::ptree xmlResponse;

    std::istringstream isResponse (strXMLText);
    boost::property_tree::read_xml(isResponse, xmlResponse);

    if (auto SessionNotification = xmlResponse.get_child_optional("NotificationSet.Notification.SessionNotification"))
    
        struct SessionElement 
            std::string id;
            unsigned int uiTypeOfNotification;
        ;

        if (auto Session = SessionNotification->get_child_optional("Session")) 
            SessionElement elem 
                Session->get("<xmlattr>.sid", ""),
                SessionNotification->get("Type", 0u)
            ;

            std::cout << "id: " << elem.id << ", type: " << elem.uiTypeOfNotification << "\n";
        
    

打印

id: sdfkljdsfkjjsf, type: 5

【讨论】:

std::string strXMLText = "\r\n" "\r\n" "\r\n" "\r\n" "属性>\ r\n" "\r\n" "5\r\n" "\r\n" "]]> \r\n" ""; 这就是我现在所拥有的,但我仍然在“xmlResponse.get_child("NotificationSet.Notification.SessionNotification.Session")”部分抛出异常..... 由于 CDATA,这是否意味着我不能使用 Boost 属性树?我还能用什么? 请@suzan 更新您的问题。评论对此不起作用 - 根本没有。我已经更新了答案 谢谢@sehe,我已经更新了我的代码。我最初使用 CDATA 的 xml 来自一个演示 HTTP POST 请求,内容设置为 xml。你是说当我收到带有 xml 内容的 POST 请求时,CDATA 不会在那里?

以上是关于Boost read_xml 问题解析字符串?的主要内容,如果未能解决你的问题,请参考以下文章

boost库中读取xml的函数 read_xml的第一个参数不支持中文路径?

如何使用 pd.read_xml 正确解析 SEC cal.xml 文件?

AttributeError:模块“pandas”没有属性“read_xml”或“to_xml”

提升读/写 XML 文件:如何更改字符编码?

Boost Spirit解析字符串以前缀开头

boost::spirit 解析器的编译错误