【发布时间】:2016-12-28 06:47:18
【问题描述】:
好吧,我又在做这个开源游戏了,无论如何我为一个 xml 文件制作了这个解析器,但是我不确定如何解析这个职业的子节点,这里是函数的代码和 xml,我想能够遍历它的子节点,我假设我需要创建另一个 for 循环,但是我不太确定我应该如何引用职业的子节点,我不关心它们的属性 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:
尚未对此进行测试,但我想我会根据给出的答案显示一些更新。
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;
}
不完全确定孩子对孩子是否合法......但只是把它扔在那里哈哈
编辑 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 文件一起正常工作。
【问题讨论】:
-
我想我可以运行一些测试,看看输出是什么:p
-
不必运行任何测试 :) 我想我有解决方案,我会在编译和测试时发布它。
-
当每个
<attribute>节点attributes 有不同的属性名称时,这不是一个很容易解析的格式。 -
就我个人而言,我可能会将这些
<attribute>节点设为<vocation>节点的实际属性,例如<vocation id="1" stamina="1" strength="1"... etc>,或者让每个属性都有自己的标签<stamina>1</stamina>。 -
好吧,这并没有按预期工作,为了让它工作,我必须编辑随附的 SDK,尽管我可以重载现有功能,但我不知道该怎么做我仍然是 C++ 的初学者:p