1

私の C++ クラスのプロジェクトでは、xml ファイルを解析して、そこからバイナリ ツリーを構築することになっています。ファイルはこれよりもはるかに高密度ですが、レイアウトは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<MyJournal>
    <species>
        <name>Sea Creature</name>
        <species>
            <name>Fish</name>
            <species>
                <name>swordfish</name>
            </species>
            <species>
                <name>grouper</name>
            </species>
        </species>
        <species>
            <name>Mammal</name>
            <species>
                <name>dolphin</name>
            </species>
            <species>
                <name>whale</name>
            </species>
        </species>
    </species>
    <species>
        <name>Land animal</name>
        <species>
            <name>Mammal</name>
            <species>
                <name>dog</name>
            </species>
            <species>
                <name>cat</name>
            </species>
        </species>
        <species>
            <name>Bird</name>
            <species>
                <name>blue jay</name>
            </species>
            <species>
                <name>robin</name>
            </species>
        </species>
    </species>
</MyJournal>

ツリーを構築できるように、このデータを解析する方法を理解するのに苦労しています。ブランチごとに再帰を使用できると思っていましたが、子を1つしか取得できません。データをツリー構造に入れるためにキューを使用することを誰かがほのめかしましたが、キューを使用してツリーのすべてのレベルを通過する方法がよくわかりません。再帰は各ブランチのデータを解析する最も簡単な方法だと思いますが、再帰メソッドを適切に実装する方法がわかりません。使ってみた方法はこちら。最初にルート ノードを渡しました。

void loop(xml_node<> *species)
{
    Node t1 = *new Node();
    xml_node<> * name_node = species->first_node("name");
    if(name_node != 0)
    {
        t1.setName(name_node->value());
        cout << name_node->value() << endl;
    }


    xml_node<> * child = species->first_node("species");
    if(child != 0)
    {
        cout << child->first_node("name")->value() << endl;
        if(child->first_node()->next_sibling() != 0)
        {
            loop(child->first_node()->next_sibling());
            xml_node<> * child2 = child->next_sibling();
            cout << child2->first_node()->value() << endl;
            loop(child2->first_node()->next_sibling());
        }
    }

}

各ノードの最初の子のみを通過し、海の生き物、魚、メカジキ、陸の動物、哺乳類、犬を返します。

正しい方向への指針を本当に感謝します。ありがとう!

4

2 に答える 2

2

このファイル内のすべてのノードをカバーするには、各ノードのとその兄弟を調べる必要があります。あなたはそれを理解しているようです。

あなたの再帰アプローチは、子供たちに到達するための実行可能な選択です。それは働いているようです。への各再帰呼び出しloopは、子プロセスの 1 レベル深くまで進みます。(「キュー」を使用するように言った人は誰でも、おそらく「スタック」を意味していました...そして再帰は暗黙的にスタックを使用します。コールスタック。)

寂しいのは兄弟です。また、再帰は XML ツリーをさらに深く掘り下げるために使用されているため、再帰を増やしてもおそらく解決されません。

コードのこのコード部分を見てください。

xml_node<> * child = species->first_node("species");
if(child != 0)
{
    cout << child->first_node("name")->value() << endl;

これは、 などの最初の兄弟を見つける場所です"swordfish"

そのステートメントをループに変更してif、含まれているロジックが最初の兄弟だけでなくすべての兄弟で実行されるようにしてください。

于 2013-03-07T17:09:52.603 に答える
0

この質問はすでに回答されていることは知っていますが、役立つヒントを提供したいだけです。

再帰を使用する代わりに、スタック/キューを使用してこの XML ファイルを解析し、「ツリー」構造を構築できます。

再帰に固執したい場合は、すべての子が同じ親を指していることを確認してください。そうしないと、ツリー構造が正しくなくなります。

于 2013-03-13T19:10:45.393 に答える