Получить все дочерние значения на основе родительского идентификатора в XML Pugixml - PullRequest
0 голосов
/ 02 апреля 2020

Так что я пытаюсь разобрать немного XML с Pugi xml. XML выглядит примерно так:

<Blah>
    <Child_1>
    </Child_1>
    <Child_2>
        <Grandchild_1 id="var">
            <Details>
                <Detail name="Detail_0" info="0"/>
                <Detail name="Detail_1" info="1"/>
                <Detail name="Detail_2" info="2"/>
            </Details>
            <Extras>
                <Extra name="Extra_0" info="3"/>
                <Extra name="Extra_1" info="4"/>
                <Extra name="Extra_2" info="5"/>
            </Extras>       
       <Grandchild_2 id="var">
            <Details>
                <Detail name="Detail_0" info="0"/>
                <Detail name="Detail_1" info="1"/>
                <Detail name="Detail_2" info="2"/>
            </Details>
            <Extras>
                <Extra name="Extra_0" info="3"/>
                <Extra name="Extra_1" info="4"/>
                <Extra name="Extra_2" info="5"/>
            </Extras>   
    </Child_2>
</Blah>

Мне нужно выполнить поиск по идентификатору внука (присутствует только в Child_2), а затем извлечь все детали / дополнения. Я сделал это в python, но у библиотеки нет версии на C ++, и она действительно утеряна. да, все детали в деталях и дополнительные элементы имеют одинаковое имя, но все имеют уникальную информацию

Чтобы получить правильного "внука", я пытаюсь использовать

pugi::xml_node message = doc.child("Blah").child("Child_2").find_child_by_attribute("Grandchild_1", "id", "var");

Но а) не уверен, если это даже работает, и б) не могу понять, как напечатать информацию с этой точки, если я даже получаю правильный узел?

В идеале я хотел бы установить какой-то тип для l oop

for (pugi::xml_node Details: message.children("Details"))
    {
        // Load as string into object
    }
for (pugi::xml_node Extras: message.children("Extra"))
    {
        // Load as string into object
    }

Это закончилось своего рода работой. Я уверен, что должен быть более элегантный способ сделать это:

    pugi::xml_document doc;
    if (!doc.load_file("Test.xml")) return -1;
    pugi::xml_node messages = doc.child("Blah").child("Child_2").find_child_by_attribute("Grandchild", "id", "var");
    std::string namePanel;
    for (pugi::xml_attribute attr = messages.first_attribute(); attr; attr = attr.next_attribute())
        {
            std::cout << " " << attr.name() << "==" << attr.value() << std::endl;

            std::string attrName = attr.name();
            if( !attrName.compare("name") )
            {
                namePanel = attr.value();
            }
        }
        std::cout << std::endl;
    for (auto message = messages.first_child(); message; message = message.next_sibling())
    {
         std::cout << " Message: "  << namePanel << std::endl;
        for (pugi::xml_node child = message.first_child(); child; child = child.next_sibling())
        {
            std::cout << "  " << child.name() << std::endl;     // get element name  
            for (pugi::xml_attribute attr = child.first_attribute(); attr; attr = attr.next_attribute())
            {
                std::cout << "   " << attr.name() << "=" << attr.value() << std::endl;
                std::string attrName = attr.name();
                if( !attrName.compare("name") )
                {
                    namePanel = attr.value();
                }
            }
            std::cout << std::endl;
        }
    }
    std::cout << std::endl;

Благодаря: Правильный способ разбора XML с использованием pugi xml для всего идея.

...