XML节点中单个整数与整数数组存储方式的一致性疑问
关于XML节点属性与子节点设计的疑惑解答
这是个非常常见的XML设计疑问,咱们先聊聊设计合理性,再解决子节点数组的读取问题~
一、属性vs子节点的设计是否一致?
完全没问题!这种用属性存储单个简单值、子节点存储集合/结构化内容的方式,是XML设计里的经典最佳实践:
- 属性天生适合存储元数据、独立的简单值(比如你的
a、b这种单个整数),写法简洁,读取效率也高; - 子节点则更适合处理重复元素(像数组这种集合)、需要扩展的内容——比如以后如果你的
c_value需要额外加属性(比如<c_value index="0">1</c_value>),用子节点的结构直接就能扩展,而属性根本做不到这种灵活度。
所以你的设计不仅不是“不一致”,反而是很规范的写法哦。
二、子节点数组的读取方法
从你给出的代码int a = myNode.attribute("a").as_int();来看,应该是用的C++系的XML解析库(比如pugixml、tinyxml2这类),我给你举两个常用库的实现例子:
例子1:用pugixml读取
// 先拿到c_array节点 pugi::xml_node c_array_node = myNode.child("c_array"); std::vector<int> c_values; // 遍历c_array下所有的c_value子节点 for (pugi::xml_node c_val_node : c_array_node.children("c_value")) { // 注意:建议把XML里的<c_value>"1"</c_value>改成<c_value>1</c_value>(去掉引号) // 这样可以直接用text().as_int()转成整数 int val = c_val_node.text().as_int(); c_values.push_back(val); }
例子2:用tinyxml2读取
// 先获取c_array元素 tinyxml2::XMLElement* c_array_elem = myNode.FirstChildElement("c_array"); std::vector<int> c_values; if (c_array_elem != nullptr) { // 遍历所有c_value子元素 tinyxml2::XMLElement* c_val_elem = c_array_elem->FirstChildElement("c_value"); while (c_val_elem != nullptr) { std::string val_text = c_val_elem->GetText(); // 如果XML里的c_value带引号,先去掉首尾的引号 if (!val_text.empty() && val_text.front() == '"' && val_text.back() == '"') { val_text = val_text.substr(1, val_text.size() - 2); } // 转成整数存入数组 int val = std::stoi(val_text); c_values.push_back(val); // 跳到下一个c_value元素 c_val_elem = c_val_elem->NextSiblingElement("c_value"); } }
小建议
你的XML里<c_value>"1"</c_value>的引号其实是多余的,直接写成<c_value>1</c_value>会更规范,解析时也不用额外处理引号,减少不必要的代码复杂度。
内容的提问来源于stack exchange,提问作者DavidA
相关产品推荐
相关产品推荐

