2

我在 PC 上的 VS2012 中使用 rapidXML 和 C++。我已经解析了 XML 文件,但现在我想单独打印出属性值。我通常可以使用下面的代码来做到这一点。但是,此方法需要知道节点名称和属性名称。这是一个问题,因为我有多个具有相同名称的节点和多个具有相同名称的属性。我的问题是,当节点名称和属性名称都不唯一时,如何获得单个属性值?

当我有唯一的节点名称和属性名称时使用的代码:

xml_node<> *node0 = doc.first_node("NodeName"); //define the individual node you want to access
xml_attribute<> *attr = node0->first_attribute("price"); //define the individual attribute that you want to access
cout << "Node NodeName has attribute " << attr->name() << " ";
cout << "with value " << attr->value() << "\n";

我的 XML 测试文件:

<catalog>
  <book>
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <price>44.95</price>
  </book>
  <book>
  <author>Ralls, Kim</author>
  <title>Midnight Rain</title>
  <price>5.95</price>
  </book>
</catalog>

对于这个具体的例子,我怎样才能得到第二本书的价格属性的值?我可以输入标题属性值“午夜雨”并以某种方式使用它来获取下一个值吗?

4

2 回答 2

1

您可以使用next_sibling(const char *)成员函数遍历兄弟节点,直到找到具有正确属性值的节点。我尚未测试以下代码,但它应该可以让您了解您需要做什么:

typedef rapidxml::xml_node<>      node_type;
typedef rapidxml::xml_attribute<> attribute_type;

/// find a child of a specific type for which the given attribute has 
/// the given value...
node_type *find_child( 
    node_type *parent, 
    const std::string &type, 
    const std::string &attribute, 
    const std::string &value)
{
    node_type *node = parent->first_node( type.c_str());
    while (node)
    {
        attribute_type *attr = node->first_attribute( attribute.c_str());
        if ( attr && value == attr->value()) return node;
        node = node->next_sibling( type.c_str());
    }
    return node;
}

然后,您可以通过以下方式找到第二本书:

node_type *midnight = find_child( doc, "book", "title", "Midnight Rain");

得到那本书的价格应该很容易。

一般来说,在处理rapidxml 时,我倾向于创建许多这样的小辅助函数。我发现它们使我的代码在没有 xpath 函数的情况下更易于阅读......

于 2013-07-16T18:33:30.190 回答
0

当您说具有相同名称的多个节点和具有相同名称的多个属性时,您的意思是;多个节点和多个 , , 属性?如果是这种情况,那么我认为您正在尝试传递多个 xml 消息。但是,您应该能够先传递第一条 xml 消息,然后再成功传递第二条消息。您没有包含整个代码,我将首先检查 doc.first_node 方法是否实际创建了一个 xml_node。

于 2013-07-16T19:13:06.850 回答