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>

この特定の例では、2 冊目の書籍の価格属性の値を取得するにはどうすればよいでしょうか? title 属性値「Midnight Rain」を入力して、それを使用して次の値を取得することはできますか?

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;
}

次に、次のように呼び出して 2 番目の本を見つけることができます。

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

その本の価格を取得するのは簡単です。

一般に、rapidxml を扱うときは、このような小さなヘルパー関数を多数作成する傾向があります。xpath関数がなくてもコードが読みやすくなることがわかりました...

于 2013-07-16T18:33:30.190 に答える