2016-10-06 9 views
1

私はかなり大きなXMLファイルを解析するためにlibxml ++を使用しているため、DOMを使用することはできません。libxml ++ TextReader;ノードをスキップする

<?xml version="1.0"?> 

<root> 

    <book name="book1"> 
    <chapter name="chapter1"> 
     #Pages 
    </chapter> 
    <chapter name="chapter2"> 
     #Pages 
    </chapter> 
    </book> 

    <book name="book2"> 
    <chapter name="chapter1"> 
     #Pages 
    </chapter> 
    <chapter name="chapter2"> 
     #Pages 
    </chapter> 
    </book> 

    <book name="book3"> 
    <chapter name="chapter1"> 
    </chapter> 
     #Pages 
    <chapter name="chapter2"> 
     #Pages 
    </chapter> 
    </book> 

</root> 

たTextReaderを使用して、ネストされたノードに対処することなくすべての書籍をループする方法はあります:

は、私のようなXMLファイルを持っていると言いますか? SAXパーサーでは一般的に可能ですか?

編集: 解決済みの解決策がありました。

+1

はい、それはあなたが探している 'next()'メソッドです。答えとしてあなたのソリューションを投稿できますか? StackOverflowで[あなた自身の質問に答えてください](http://stackoverflow.com/help/self-answer)することができます。 – nwellnhof

+0

こんにちは@nwellnhof、 私は自分の質問を編集し、可能な解決策を回答に移しました。 ただし、ユーザーによっては、両方のソリューションが適合しない場合があります。 私は、提案されたソリューションが大部分の人々を助けるかもしれないので、大きな部分(〜600MB)のXMLファイルを解析する必要がありますが、残念ながら私のニーズに合っていません。 私の質問には部分的にしか答えていないが、表示する最善の方法は何ですか? –

+1

あなたは既にあなたの答えに言いました、それは誰のニーズにも合わないかもしれないと言いました。 IMO、あなたの答えは間違いなく十分です。また、48時間以内に[自分の回答を受け入れる](http://blog.stackoverflow.com/2009/01/accept-your-own-answers/)もできます。しかし、あなたがより良い答えを得ることを望むなら、そうしないことを選ぶかもしれません。 – nwellnhof

答えて

1

(部分)解決策が見つかりました。

read()は非常に次のノードを読み込んでいるため、「より深い」レイヤーに移動すると、next()は現在の深さの次のノードにジャンプします。 read()を2回呼び出すと、リーダーが最初のブックの開始タグ(深さ1)に移動します。 next()を呼び出すと、深さが1の次のノード(この場合は終了タグ)にジャンプします。 next()を呼び出すと、すべてのブックをループすることができます。深さ1のノードがなくなるとfalseを返します。

残念ながら、読者をツリーの上に移動するオプションはありません。ループ内でread()を呼び出してより深いレイヤーに移動すると、next()はこのレイヤー上の次のノードにジャンプするため、ほとんどの場合、これは満足のいく答えではありません。


もう一つの方法は、直接の子ノードのリストを取得するために)(リーダー)(get_current_nodeを呼び出し、get_childrenを使用することです。 この例では、read()を呼び出してリーダをルートノードに移動した後、それぞれget_current_node()およびget_childrenを呼び出して、結果として得られる 'book'ノードのリストを反復することができます。

get_children()を呼び出すと、子ノードが多いノードではリストが短くなり、すべての子ノードの一部しか表示されないため、小さなファイルではうまくいくように見えます。


Iが発見可能な回避策は、(上記のように)所望の深さに移動することで、(次の呼び出しによって、この深さのノードをループ)と各ループの後、呼び出して新しいノードオブジェクトを初期化します現在のノードとそのすべてのサブツリーを展開するTextReaderでexpand()を実行します。 この方法で、TextReader-Objectを変更せずに、新しいノードにアクセスしてサブツリーを操作できます。

ただし、注意してください。 free_wrapper()を呼び出さない限り、新しいノードのC++ - ラッパーは削除されません。

C++ラッパーが削除されていません。ドキュメントから

。このメソッド(expand())を使用すると、 のxmlpp :: Node :: free_wrappers()を呼び出さない限り、メモリによって がリークします。 は、アプリケーションによって呼び出されることを意図していません。


機能-ドキュメンテーションは非常にまばらなまたは不完全であるとして、これは、私自身の観測からであることに注意してください。

関連する問題