【问题标题】:boost property tree add_child specifying the path提升属性树 add_child 指定路径
【发布时间】:2016-12-25 12:11:01
【问题描述】:

我正在使用 boost::property_tree 来操作一些 XML。我必须在 xml 文档中添加一个子节点

xml 文档如下所示:

<MPD>
    <Period>
        <AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1">
            <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
            <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95">
                <!-- value already exists here //-->
                <!-- need to insert new entry here //-->
            </ContentProtection>
        </AdaptationSet>

        <AdaptationSet>
            <ContentProtection ... />
            <ContentProtection ... />
            <ContentProtection ... />
        </AdaptationSet>
    </Period>
</MPD>

所以我有以下代码在上面 XML 中标记的位置插入新条目:

typedef boost::property_tree::iptree        property_tree_t;
typedef boost::shared_ptr<property_tree_t>  shared_ptree_t;
typedef boost::optional<property_tree_t &>  optional_ptree_t;

string sSearchSchemeIdUri = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95";
string sChildName;

optional_ptree_t spPeriod = spPTree->get_child_optional("MPD.Period");
if (spPeriod)
{
    for (auto & adaptSetNextChild : spPeriod->get_child("AdaptationSet"))
    {
        sChildName = adaptSetNextChild.first;

        if (sChildName.compare("ContentProtection") == 0)
        {
            property_tree_t &   ptContentProtection = adaptSetNextChild.second;
            string              sSchemeIdUri        = ptContentProtection.get<string>("<xmlattr>.schemeIdUri", "");

            if (sSchemeIdUri.compare(sSearchSchemeIdUri) == 0)
            {
                property_tree_t ptPssh;
                ptPssh.clear();
                ptPssh.add("cenc:PSSH", sPssh);
                ptContentProtection.add_child("./", ptPssh);
            }
        }
    }
}

上面的代码将添加的数据包装在下面:

<></>
<//></>

我想避免。

我推测这个错误标记来自我的 add_child 调用,它将插入路径指定为“./”

不指定任何内容会导致异常,这是我发现唯一有效的方法。

读过the header file for ptree.hpp,它声明参数是

/** Add the node at the given path. Create any missing parents. If there
* already is a node at the path, add another one with the same key.
* @param path Path to the child. The last fragment must not have an
*             index.
* @return A reference to the inserted subtree.
* @note Because of the way paths work, it is not generally guaranteed
*       that a node newly created can be accessed using the same path.
*/
self_type &add_child(const path_type &path, const self_type &value);

有没有办法指定当前路径,例如。 ptContentProtection 的路径?

【问题讨论】:

    标签: c++ xml boost ptree


    【解决方案1】:

    您可能希望拥有put 成员而不是add 成员。

    这是一个将OLD VALUE 替换为NEW VALUE 的示例:

    Live On Coliru

    #include <boost/property_tree/xml_parser.hpp>
    #include <iostream>
    
    static std::string const sample = R"(<MPD>
        <Period>
            <AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1">
                <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
                <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95">OLD VALUE</ContentProtection>
            </AdaptationSet>
    
            <AdaptationSet>
            </AdaptationSet>
        </Period>
    </MPD>)";
    
    static std::string sSearchSchemeIdUri = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95";
    
    int main() {
        using boost::property_tree::iptree;
        iptree pt;
        {
            std::istringstream iss(sample);
            read_xml(iss, pt);
        }
    
        for (auto& as : pt.get_child("MPD.Period")) {
            if (as.first == "AdaptationSet") {
                for (auto& cp : as.second) {
                    if (cp.first == "ContentProtection" && cp.second.get("<xmlattr>.schemeIdUri", "") == sSearchSchemeIdUri)
                    {
                        cp.second.put_value("NEW VALUE");
                    }
                }
            }
        }
    
        auto xws = boost::property_tree::xml_writer_make_settings<std::string>(' ', 4);
        write_xml(std::cout, pt, xws);
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多