我有一个需要解析的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>
使用以下代码,我可以获得两个“Panel”对象中每个对象的属性。
#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”对象中每个对象的属性,但不是每个对象的元素。文件中的每个“Panel”对象都有不同的元素,因此我无法遍历树中查找特定元素或属性。
问题是:如何修改代码,以便我可以遍历所有“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;
}
编辑:上述工作正常,但我不禁想到有更好的方法涉及单个循环。