我正在使用PugiXML 1.5
,并试图在一个巨大的XML中找到一个具有特定属性的特定子级。具体而言,此XML是一个Collada DAE文件。
我知道如何通过这样做找到一个直接的孩子,即通过属性:
collada.child("library_visual_scenes").child("visual_scene").
child("node").find_child_by_attribute("instance_geometry", "url", "#myurl");
问题是library_visual_scenes
完全可以有这样的东西:
<library_visual_scenes>
<visual_scene>
<node>
...
<node>
..
<node>
<instance_geometry url="this_is_what_i_want">
...
那么,与编写明显的来解析节点内的所有节点不同,find_child_by_attribute
是否还有另一种风格,可以搜索嵌套节点来检索具有特定属性的子节点?
更新
我尝试了@zeuxcg Xpath的建议,但仍然没有为我获取节点。HTML片段如下。我真的不习惯XPath(主要习惯CSS查询)
...
<library_visual_scenes>
<visual_scene id="xyzscene">
<node name="EnvironmentAmbientLight">
<instance_light url="#EnvironmentAmbientLight"/>
</node>
<node id="node-foo" name="foo">
<instance_geometry url="#foo-url">
...
我尝试了以下Xpath url,但没有成功:
/library_visual_scenes/visual_scene//node/instance_geometry[@url='#foo-url']
但这奏效了:
//library_visual_scenes/visual_scene//node/instance_geometry[@url='#foo-url']
我了解到//
的意思是搜索所有节点,但library_visual_scenes
是存在的单个节点。有什么解释我为什么需要//
吗?
您可以使用XPath:
doc.select_node("/library_geometries//geometry[@id='value']")
注意,这会导致在整个子树中查找该节点;对于COLLADA来说,构建一次从字符串到节点的映射,然后将其用于所有查找,通常效率更高。IIRC ID必须是全局唯一的,这样您就可以使用以下代码为整个树构建一次映射:
unordered_map<string, xml_node> map;
for (xpath_node item: doc.select_nodes("//@id"))
map[item.attribute().value()] = item.parent();