У меня есть XML-файл, который мне нужно проанализировать, и я борюсь с использованием PugiXML
разобрать все элементы и атрибуты.
У меня есть следующий файл XML:
<?xml version = '1.0' encoding = 'UTF-8'?>
<PanelList DefaultTheme="konami" >
<Panel xpos="0" ypos="0" width="800" height="600" imagepath="./%THEME%/background_uga_large.png" name="AttractMode0" >
<GameViewport xpos="0" ypos="0" width="630" height="526" name="gameviewport"/>
<ValueLabel xpos="120" ypos="550" width="448" height="30" fontsize="18" color="white" text="Please, insert your card" name="StatusAttract" errorimagepath="./%THEME%/panel_top_error.png" pageattpendingpath="./%THEME%/panel_top_att.png" drinkpendingpath="./%THEME%/panel_top_drink.png" onclick="ShowPanel(special_panel999)" />
<StreamingImage xpos="637" ypos="3" width="160" height="120" volume="0" text="udp:@:9001" name="attract1" />
<Image xpos="637" ypos="130" width="160" height="390" imagepath="http://n2web/images/attract-uga.gif" />
<FunctionButton xpos="6" ypos="534" width="68" height="60" imagepath="./%THEME%/button_shrink.png" clickimagepath="./%THEME%/button_shrink_down.png" name="window" onclick="ShowPanel(AttractModeSmall)"/>
<FunctionButton xpos="650" ypos="534" width="68" height="60" imagepath="./%THEME%/button_attendantstart_up.png" clickimagepath="./%THEME%/button_attendantstart_down.png" name="pageattstart" onclick="PageAttendantRequest" enable="MW_ONLINE == TRUE"/>
<FunctionButton xpos="725" ypos="534" width="68" height="60" imagepath="./%THEME%/button_drinkstart_up.png" clickimagepath="./%THEME%/button_drinkstart_down.png" name="drinkstart" onclick="DrinkRequest" enable="MW_ONLINE == TRUE"/>
</Panel>
<Panel xpos="0" ypos="0" width="800" height="600" imagepath="./%THEME%/background_uga_large.png" name="AttractMode1" >
<GameViewport xpos="0" ypos="0" width="630" height="526" name="gameviewport"/>
<ValueLabel xpos="120" ypos="550" width="448" height="30" fontsize="18" color="white" text="Please, insert your card" name="StatusAttract" errorimagepath="./%THEME%/panel_top_error.png" pageattpendingpath="./%THEME%/panel_top_att.png" drinkpendingpath="./%THEME%/panel_top_drink.png" onclick="ShowPanel(special_panel999)" />
<StreamingImage xpos="637" ypos="3" width="160" height="120" volume="0" text="udp:@:9001" name="attract1" />
<Image xpos="637" ypos="130" width="160" height="390" imagepath="http://n2web/images/attract-uga.gif" />
<FunctionButton xpos="6" ypos="534" width="68" height="60" imagepath="./%THEME%/button_shrink.png" clickimagepath="./%THEME%/button_shrink_down.png" name="window" onclick="ShowPanel(AttractModeSmall)"/>
<FunctionButton xpos="650" ypos="534" width="68" height="60" imagepath="./%THEME%/button_attendantstart_up.png" clickimagepath="./%THEME%/button_attendantstart_down.png" name="pageattstart" onclick="PageAttendantRequest" enable="MW_ONLINE == TRUE"/>
<FunctionButton xpos="725" ypos="534" width="68" height="60" imagepath="./%THEME%/button_drinkstart_up.png" clickimagepath="./%THEME%/button_drinkstart_down.png" name="drinkstart" onclick="DrinkRequest" enable="MW_ONLINE == TRUE"/>
</Panel>
</PanelList>
С помощью следующего кода я могу получить атрибуты каждого из двух объектов «Панели».
#include "pugixml.hpp"#include <iostream>
int main()
{
pugi::xml_document doc;
if (!doc.load_file("allpanels.xml")) return -1;pugi::xml_node panels = doc.child("PanelList");
std::cout << panels.name() << std::endl;
for (pugi::xml_node panel = panels.first_child(); panel; panel = panel.next_sibling())
{
std::cout << panel.name() << std::endl;
for (pugi::xml_attribute attr = panel.first_attribute(); attr; attr = attr.next_attribute())
{
std::cout << " " << attr.name() << "=" << attr.value() << std::endl;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
Вывод следующий:
jrnVM gtkSign $ ./gtkSign
PanelList
Panel
xpos=0
ypos=0
width=800
height=600
imagepath=./%THEME%/background_uga_large.png
name=AttractMode0
Panel
xpos=0
ypos=0
width=800
height=600
imagepath=./%THEME%/background_uga_large.png
name=AttractMode1
Я вижу, что я получаю атрибуты для каждого из двух объектов «Панели», но не элементы для каждого. Каждый объект «Панель» в файле будет иметь разные элементы, поэтому я не могу пройтись по дереву в поисках определенных элементов или атрибутов.
Вопрос в том: Как мне изменить код, чтобы я мог перебирать все объекты «Panel» и получать всю информацию для каждого из них?
Любая помощь будет принята с благодарностью.
РЕДАКТИРОВАТЬ:
С помощью «Джона» я смог придумать это решение. Спасибо Джон.
#include "pugixml.hpp"#include <iostream>
#include <sstream>
int main()
{
pugi::xml_document doc;
std::string namePanel;
if (!doc.load_file("allpanels.xml")) return -1;pugi::xml_node panels = doc.child("PanelList");
std::cout << panels.name() << std::endl;
for (pugi::xml_node panel = panels.first_child(); panel; panel = panel.next_sibling())
{
//We found a "Panel" -- print it's attributes
for (pugi::xml_attribute attr = panel.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 << "Panel: " << namePanel << std::endl;
//Now print all elements and attributes of current "Panel"for (pugi::xml_node child = panel.first_child(); child; child = child.next_sibling())
{
std::cout << child.name() << std::endl; // get element name
// iterate through all attributes
for (pugi::xml_attribute attr = child.first_attribute(); attr; attr = attr.next_attribute())
{
std::cout << " " << attr.name() << "=" << attr.value() << std::endl;
}
std::cout << std::endl;
}
}
std::cout << std::endl;
}
РЕДАКТИРОВАТЬ: Вышеуказанное работает, но я не могу не думать, что есть лучший способ, который включает в себя один цикл.
Задача ещё не решена.
Других решений пока нет …