【问题标题】:rapidxml weird parsing for one specific noderapidxml 对一个特定节点的奇怪解析
【发布时间】:2021-09-01 04:45:53
【问题描述】:

我一直在寻找几个小时来解决我的(简单?)问题,但我找不到遇到这个问题的人。我正在使用最新版本的 rapidxml(1.13)。 我目前正在尝试创建一个基于图块的引擎,我需要读取 tmx 文件。 我使用 rapidxml 有一段时间了,到目前为止一切都很好。它能够以预期的行为完美地读取每个节点。但是我遇到了一个有问题的节点。 这是我的 tmx 文件:

<?xml version="1.0" encoding="UTF-8"?>
<map version="1.5" tiledversion="1.6.0" orientation="orthogonal" renderorder="right-down" width="100" height="100" tilewidth="32" tileheight="32" infinite="0" nextlayerid="12" nextobjectid="1">
 <tileset firstgid="1" source="../../../Tile_engine/Tile_engine/sprite/[Base]BaseChip_pipo.tsx"/>
 <tileset firstgid="1065" source="../../../Tile_engine/Tile_engine/sprite/collision.tsx"/>
 <layer id="4" name="background" width="100" height="100">
  <properties>
   <property name="bg" type="bool" value="false"/>
  </properties>
  <data encoding="csv">
//I've removed the data for clearer view
</data>
 </layer>
 <layer id="6" name="object" width="100" height="100">
  <properties>
   <property name="isSolid" type="bool" value="true"/>
  </properties>
  <data encoding="csv">
//I've removed the data for clearer view
</data>
 </layer>
 <layer id="9" name="front" width="100" height="100">
  <properties>
   <property name="isSolid" type="bool" value="false"/>
  </properties>
  <data encoding="csv">
//I've removed the data for clearer view
</data>
 </layer>
 <layer id="11" name="collision" width="100" height="100">
  <data encoding="csv">
//I've removed the data for clearer view
</data>
 </layer>
</map>

为了调试,我使用 rapidxml 进行基本读取:

 xml_document<> doc;
    xml_node<> * root_node;
    // Read the xml file into a vector
    ifstream theFile ("sprites/map_wtf.tmx");
    vector<char> buffer((istreambuf_iterator<char>(theFile)), istreambuf_iterator<char>());
    buffer.push_back('\0');
    // Parse the buffer using the xml file parsing library into doc
    doc.parse<0>(&buffer[0]);
    // Find our root node
    root_node = doc.first_node("map");

当我尝试读取(并计算)layer 节点时:

int count_node(0);
    for(xml_node<> * child = root_node->first_node("layer"); child != nullptr; child = child->next_sibling())
        count_node++;
    cout    <<  count_node;

输出是正确的,给了我 4。 但是当我尝试读取 tileset 节点时,输出结果为 6。

所以我假设行为是链接到 tileset 节点末尾的 /> (&lt;tileset firstgid="1" source="../../../Tile_engine/Tile_engine/sprite/[Base]BaseChip_pipo.tsx"/&gt;)。

由于嵌套的 property 节点具有相同的模式 (&lt;property name="bg" type="bool" value="false"/&gt;),因此我尝试了以下代码:

int count_node(0);
    for(xml_node<> * child = root_node->first_node("layer")->first_node("properties")->first_node("property"); child != nullptr; child = child->next_sibling())
        count_node++;
    cout    <<  count_node;

谁给了我正确的输出又名:1。

我为doc.parse&lt;0&gt;(&amp;buffer[0]) 行尝试了不同的解析选项,但没有任何效果。在这些测试期间,我还阅读了缓冲区的内容,这是正确的。 我必须有错误的方式来读取文件,但我不明白为什么这个脚本可以很好地读取 layer 节点和 property 节点,而不是 tileset那些。

谁能帮帮我? 谢谢!

【问题讨论】:

  • 看起来差不多...在根级别上,从第一个 tileset 节点开始,并计算紧随其后的同一级别上的所有节点,我看到总共有 6 个节点。对于 label,我看到 4 个节点,因为 2 个 tileset 节点位于标签之前。由于每个 layer/properties/property 都是一个嵌套节点,因此答案是 1。如果我是对的,您可以尝试添加另一个名称不同的节点作为 map 的最后一个子节点,看看您的答案是否从 6 变为 7瓦片集,从 4 到 5 用于标签,而不是用于嵌套属性。
  • @grek40 我觉得很愚蠢.. 我以为 next_sibling() 会寻找模拟节点(同名)!非常感谢您的快速回答!!

标签: c++ xml parsing rapidxml tmx


【解决方案1】:

这个问题是基于对结果的误解

xml_node<> * child = root_node->first_node("layer");
child = child->next_sibling();

child = child-&gt;next_sibling() 返回同一级别的下一个节点,而不管节点名称或在 root_node-&gt;first_node("layer") 选择期间应用的任何其他约束。

但是,next_sibling 签名与first_node 签名基本相同,因此可用于将条件应用于要查找的下一个兄弟节点。

所以(未经测试的)方法就像

int count_node(0);
for(xml_node<> * child = root_node->first_node("tileset"); child != nullptr; child = child->next_sibling("tileset"))
    count_node++;
cout << count_node;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    相关资源
    最近更新 更多