提高对孩子的认识

boost recognize a child

本文关键字:孩子      更新时间:2023-10-16

我的问题与:提升有关

一些boost代码可以正确地查找一个节点是否有子节点,但如果一个节点有两个其他节点,它就无法识别子节点。

这是一个递归调用,可以读取所有树节点,然后将值的副本应用到谷歌协议缓冲区

void ReadXML(iptree& tree, string doc)
{
    const GPF* gpf= pMessage->GetGPF();
    for(int i = 0 ; i < gpf->field_count(); ++i)
    { 
          string fieldName = GetName(i);
          boost::optional< iptree & > chl =  pt.get_child_optional(fieldName); 
          if(chl) { 
          for( auto a : *chl ){
             boost::property_tree::iptree subtree = (boost::property_tree::iptree) a.second ;
             assignDoc(doc);
                 ReadXML(subtree, doc);
             }
           }
      }     
}

XML文件

<?xml version="1.0" encoding="utf-8"?>
<nodeA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <nodeA.1>This is the Adresse</nodeA.1>
    <nodeA.2>
    <node1>
      <node1.1>
        <node1.1.1>Female</node1.1.1>
        <node1.1.2>23</node1.1.2>
        <node1.1.3>Engineer</node1.1.3>
      </node1.1>
      <node1.1>
        <node1.2.1>Female</node1.2.1>
        <node1.2.2>35</node1.2.2>
        <node1.2.3>Doctors</node1.2.3>
      </node1.1>
    </node1>
</nodeA.2>
<nodeA.3>Car 1</nodeA.3>
</nodeA>

我的问题是node1没有被认为有孩子。我不知道是不是因为有两个子节点同名。

请注意,XML文件可能会从一个客户端更改为另一个客户端。我可能有不同的节点。

我必须使用a.second还是a.first

此处为

boost::optional< iptree & > chl =  pt.get_child_optional(fieldName);

显式搜索具有给定名称的子项。在递归过程中,这个名称似乎从未改变过。在各个层面上,你似乎都在寻找同名的孩子。

我认为您可以/应该从更高的层次来看待这个问题。

Boost属性树在后台使用RapidXML。PugiXML是一个类似但更现代的库,也可以在纯头模式下使用。使用PugiXML,您可以编写:

pugi::xml_document doc;
doc.load(iss);
for (auto& node : doc.select_nodes("*/descendant::*[count(*)=3]/*[count(*)=0]/.."))
{
    auto values = node.node().select_nodes("*/text()");
    std::cout << "Gender    " << values[0].node().value() << "n";
    std::cout << "Age       " << values[1].node().value() << "n";
    std::cout << "Job Title " << values[2].node().value() << "n";
}

它选择根节点(nodeA)的三个子节点,并将它们解释为GenderAgeJob Title。它打印:

Gender    Female
Age       23
Job Title Engineer
Gender    Female
Age       35
Job Title Doctors

我希望你会觉得这很有建设性。


完整演示

在我的系统上构建,简单地说:

sudo apt-get install libpugixml-dev
g++ -std=c++11 demo.cpp -lpugixml -o demo
./demo

demo.cpp:

#include <pugiconfig.hpp>
#define PUGIXML_HEADER_ONLY
#include <pugixml.hpp>
#include <iostream>
#include <sstream>
int main()
{
    std::istringstream iss("<?xml version="1.0" encoding="utf-8"?>n"
            "<nodeA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">"
                "<nodeA.1>This is the Adresse</nodeA.1>"
                "<nodeA.2>"
                    "<node1>"
                        "<node1.1>"
                            "<node1.1.1>Female</node1.1.1>"
                            "<node1.1.2>23</node1.1.2>"
                            "<node1.1.3>Engineer</node1.1.3>"
                        "</node1.1>"
                        "<node1.2>"
                            "<node1.2.1>Female</node1.2.1>"
                            "<node1.2.2>35</node1.2.2>"
                            "<node1.2.3>Doctors</node1.2.3>"
                        "</node1.2>"
                    "</node1>"
                "</nodeA.2>"
            "<nodeA.3>Car 1</nodeA.3>"
        "</nodeA>");
    pugi::xml_document doc;
    doc.load(iss);
    for (auto& node : doc.select_nodes("*/descendant::*[count(*)=3]/*[count(*)=0]/.."))
    {
        auto values = node.node().select_nodes("*/text()");
        std::cout << "Gender    " << values[0].node().value() << "n";
        std::cout << "Age       " << values[1].node().value() << "n";
        std::cout << "Job Title " << values[2].node().value() << "n";
    }
    //doc.save(std::cout);
}