那么我在这个开源游戏中再次工作,无论如何我为xml文件创建了这个解析器但是我不确定如何解析职业的子节点,这里是代码和函数的xml ,我希望能够遍历它的子节点,我假设我需要创建另一个for循环,但是我不太确定我应该如何引用vocation的子节点,我不关心它们的属性atm。
bool Game::loadCreatureAdditionalAttributes()
{
pugi::xml_document data;
pugi::xml_parse_result result = data.load_file("data/XML/attributes.xml");
if (!result) {
printXMLError("Error - Game::loadCreatureAdditionalAttributes", "data/XML/attributes.xml", result);
return false;
}
bool attributesEnabled = false;
for (auto attributeNode : data.child("attributes").children()) {
if (strcasecmp(attributeNode.name(), "additionalAttributes") == 0) {
if (attributeNode.attribute("enabled").as_bool()) {
if (strcasecmp(attributeNode.name(), "vocation") == 0) {
pugi::xml_attribute vocation = attributeNode.attribute("id");
uint32_t aNode;
pugi::xml_attribute attr = attributeNode.attribute(attributeNode.name());
if (attr) {
aNode = pugi::cast<uint32_t>(attr.value());
}
else {
aNode = 0;
}
CreatureAttributes[pugi::cast<uint32_t>(vocation.value())][attributeNode.name()] = aNode;
}
}
}
}
return true;
}
现在是xml
<?xml version="1.0" encoding="UTF-8"?>
<attributes>
<additionalAttributes enabled = "0" />
<vocation id = "1">
<attribute stamina = "1" />
<attribute strength = "1" />
<attribute intelligence = "1" />
<attribute dexterity = "1" />
<attribute wisdom = "1" />
<attribute luck = "1" />
<attribute critical = "1" />
<attribute block = "1" />
<attribute experienceGain = "1" />
<attribute power = "1" />
<attribute precision = "1" />
</vocation>
<vocation id = "2">
<attribute stamina = "1" />
<attribute strength = "1" />
<attribute intelligence = "1" />
<attribute dexterity = "1" />
<attribute wisdom = "1" />
<attribute luck = "1" />
<attribute critical = "1" />
<attribute block = "1" />
<attribute experienceGain = "1" />
<attribute power = "1" />
<attribute precision = "1" />
</vocation>
</attributes>
编辑1:
Haven尚未对此进行测试,但我认为我会根据给出的答案显示更新。
bool Game::loadCreatureAdditionalAttributes()
{
pugi::xml_document data;
pugi::xml_parse_result result = data.load_file("data/XML/attributes.xml");
if (!result) {
printXMLError("Error - Game::loadCreatureAdditionalAttributes", "data/XML/attributes.xml", result);
return false;
}
auto attr = data.child("attributes").child("additionalAttributes");
bool attributesEnabled = attr.attribute("enabled").as_bool();
if (attributesEnabled) {
for (auto vocation : data.child("attributes").children("vocation")) {
uint32_t id = pugi::cast<uint32_t>(vocation.attribute("id").value());
for (auto attribute : vocation.children("attribute")) {
for (auto& a : attribute.attributes()) {
CreatureAttributes[id][a.name()] = pugi::cast<uint32_t>(a.value());
}
}
}
}
return true;
}
不完全确定孩子对孩子是否合法......但只是将它丢弃在那里lol
编辑2:
尚未对它进行测试,只是在它没有按预期工作的情况下更新它。
bool Game::loadCreatureAdditionalAttributes()
{
pugi::xml_document data;
pugi::xml_parse_result result = data.load_file("data/XML/attributes.xml");
if (!result) {
printXMLError("Error - Game::loadCreatureAdditionalAttributes", "data/XML/attributes.xml", result);
return false;
}
auto attr = data.child("attributes").child("additionalAttributes");
if (attr) {
bool attributesEnabled = attr.attribute("enabled").as_bool();
if (attributesEnabled) {
for (auto vocation : data.child("attributes").children("vocation")) {
uint32_t id = pugi::cast<uint32_t>(vocation.attribute("id").value());
for (auto attribute : vocation.children("attribute")) {
for (auto& a : attribute.attributes()) {
CreatureAttributes[id][a.name()] = pugi::cast<uint32_t>(a.value());
}
}
}
return true;
}
}
return false;
}
只是想为那些有类似问题的人提供更新,代码效果很好!
vocation id = 1 attributes = stamina value = 1
vocation id = 1 attributes = strength value = 45
vocation id = 1 attributes = intelligence value = 1
vocation id = 1 attributes = dexterity value = 1
vocation id = 1 attributes = wisdom value = 63
vocation id = 1 attributes = luck value = 1
vocation id = 1 attributes = critical value = 1
vocation id = 1 attributes = block value = 1
vocation id = 1 attributes = experienceGain value = 1
vocation id = 1 attributes = power value = 81
vocation id = 1 attributes = precision value = 1
vocation id = 2 attributes = stamina value = 100
vocation id = 2 attributes = strength value = 1
vocation id = 2 attributes = intelligence value = 20
vocation id = 2 attributes = farfenugen value = 1
vocation id = 2 attributes = stackoverflow value = 1000
当然我更改了代码以使其与我正在处理的其他代码一起使用,但Edit 2
中的示例代码可以在结构上类似的xml文件中正常工作。
答案 0 :(得分:1)
我非常喜欢pugixml
,这使解析变得非常简单。不过,您的XML
格式有点棘手,我会考虑以不同方式存储您的<attributes>
。
目前,您可以像这样遍历 vocations 和属性:
#include <iostream>
#define PUGIXML_HEADER_ONLY
#include "pugixml.hpp"
auto xml = R"(
<?xml version="1.0" encoding="UTF-8"?>
<attributes>
<additionalAttributes enabled = "0" />
<vocation id = "1">
<attribute stamina = "1" />
<attribute strength = "1" />
<attribute intelligence = "1" />
</vocation>
<vocation id = "2">
<attribute stamina = "1" />
<attribute strength = "1" />
<attribute intelligence = "1" />
</vocation>
</attributes>
)";
int main()
{
pugi::xml_document doc;
doc.load(xml);
for(auto vocation: doc.child("attributes").children("vocation"))
{
std::cout << "vocation id:" << vocation.attribute("id").as_string() << '\n';
for(auto attribute: vocation.children("attribute"))
{
for(auto& a: attribute.attributes())
{
std::cout << " attribute: " << a.name() << '\n';
std::cout << " : " << a.value() << '\n';
}
}
}
}
我可能会更像XML
这样组织:
#include <iostream>
#define PUGIXML_HEADER_ONLY
#include "pugixml.hpp"
auto xml = R"(
<?xml version="1.0" encoding="UTF-8"?>
<attributes>
<additionalAttributes enabled = "0" />
<vocation id = "1">
<stamina>1</stamina>
<strength>1</strength>
<intelligence>1</intelligence>
</vocation>
<vocation id = "2">
<stamina>1</stamina>
<strength>1</strength>
<intelligence>1</intelligence>
</vocation>
</attributes>
)";
int main()
{
pugi::xml_document doc;
doc.load(xml);
for(auto vocation: doc.child("attributes").children("vocation"))
{
std::cout << "vocation id:" << vocation.attribute("id").as_string() << '\n';
std::cout << " : stamina = " << vocation.child("stamina").text().as_string() << '\n';
std::cout << " : strength = " << vocation.child("strength").text().as_string() << '\n';
std::cout << " : intelligence = " << vocation.child("intelligence").text().as_string() << '\n';
std::cout << '\n';
}
}