XMLパーサー非標準C ++の実装:まず、基本的なデータ構造設計の考え方

はじめに:

このプロジェクトは、ライブラリーの実用化に現在あるまで、私は私が合計を書いた、W3Cの基準に沿っように注意されている、最初のフルテキスト検索]タブから端まで、これまでの5年間の時間があり、ローカルのXMLデータ管理をシンプルとしてC ++プロジェクトを使用します三回パーサ、私はこれ以上、XMLのように、初期の要件のためのXMLは、顧客によって提起されていない、初めてで、数々のシーンがあり、後にXML設定ファイル、データ交換、GUIのレイアウトを使用今までは、新しいプロジェクトが、それは基本的に私はその代替JSONを達成したとしても、現在の状況では、必要な機能になってきたログと同じですが、私はまだ簡単な例を与える、それは十分に強い生命力を持っていると思います、ユーザーが見JSONは激しい感じ、読むことはできませんが、ユーザーは、XMLが、最初の顧客は非常に簡単です見て、我々はすべてを知っています。そのため、クロスプラットフォームのアプリケーション、およびそのステータスがまだ強いです。この記事を書いて、それは私が第四の書き込みXMLパーサだ意味します。

 

私は第三XML解析を書いて、基本的にはXML1.0規格と行にされており、文書型定義は、名前空間、すべてのW3Cの仕様に合わせて、非常に面白い話して、設計するものに加えて、XML宣言、これらの事、標準に準拠し、多くの時間を費やしたが、過去2年間で、かつて私がプロジェクトに適用されていません実現し、ロジックを実行するために必要な書類は、私はC ++で明らかにされているに対処してきた実用的なシナリオでは、ありません。

 

数年前、私は最初のhtmlへの参照をした、jsの中のようなgetElementByIdを、element.innerHTMLものは達成するために必要です。

element.innerHTMLの観点、そうでない場合は処理の詳細から、文書の深さが大きくなると、このようにメモリフットプリントは、制限がありません。

そのため、完全なXMLノードプログラムはそれをテキストのすべての子ノードを運ぶために、望ましいことではありません。

 

だから私は解決策を考えたとき:

一つだけの完全なドキュメントがあるDOM

分析データは、特定のノード、均一な長さの使用位置と格納されました、

、直接全長及びアウト文書内の位置からコピーされた文書データをフェッチする必要があります

 

このように、私だけがピットに考えを見つけるために、インデックス・ロジック、変更、最終的に削除書き込むまで、それは、良いときに書き始めました、ピットは、毒@#でうじ虫、うじ虫は翔、翔がありました¥%。

DOMを経由して、最悪の場合、変更された文書データなので、すべてのノードが新しい場所と変化の長さに文書全体を横断する必要がありますが、プロジェクトは急いでいたので、私は逆にするために十分な時間が、これだけ自分を硬化しましたそう、乾燥頭皮、幸いなことに、数年ではなく、大きな問題はなく、時間がない、近年の問題は、私の最大の心は、はい、私は強迫性障害を持ってきました。

 

さて、レッスンは私がやりたいし、同時に、宿題具体的な実装を行うためにここにコードを書き始める前に、人々はあなたが回り道を避けることができ、この心をやっている、十分に学びました。

私はそれについて考えるようになった:レッスンの組み合わせが、私は完全な文書の文字列リストに分割する予定今回はそれを行う方法を、シミュレートするためにいくつかの簡単な文書で、メモリに格納します。

今回は、このようなDTD、私は破棄予定の名前空間などの標準に需要のロジックによって運ばれた文書の内容の一部を実装する予定はありません。

< A > 
    < B > 1 </ B > 
</ A >

上記文書、分割文字列リスト:{ "<A>"、 "<B>"、 "1"、 "</ B>"、 "<A>"}、C ++では、使用のstd ::ストアにリスト<はstd :: string>に。

ノードデータ構造はするように設計する必要があります。

構造体xnode {

    std ::リスト<のstd ::文字列> ::イテレータタグ名; //ラベル名

    std ::リスト<のstd ::文字列> ::イテレータinner_begin、inner_end; //内部テキスト込み

    std ::リスト<xnode>チャイルズ; //子ノード

    xnode *親; //親ノード

    取得する - ++オペレータによってコピーした後、親ノードで//反復その位置、その前後のノード、;のstd ::リスト<xnode> ::イテレータ自己。

}。

-------------------------------------------------- -

xnodeルート;

文書を解析した後、

root.tag_name => "<A>"

root.inner_begin => "<B>"

root.inner_end => "</a>を"

root.childs.beginは()ラベル<B>ノードで、私はBと、一時的にそれを表現するためにここにいます。

b.tag_name => "<B>";

b.inner_begin => "1";

b.inner_end => "</ B>";

この方法は、私はちょうど、アクセスロジックのinnerTextを達成するために必要がある場合:

std ::文字列str;

以下のための(自動I = elem.inner_begin;!私= elem.inner_end; ++ I)

    STR + = * S;

最初のステップは、文書を見て少し複雑、ピットに思えるこれは正しい方向であると思いますし、次に使用されません。

< ATTR1 = '1' ATTR2 = "2" > < B ATTR1 = '1' ATTR2 = "2" > XXX </ B > </ A >
    

プロパティに関連するタグは、状況はより複雑になります

まず、プロパティは文字の多くがあるかもしれない、オフに分割するだけでなく、問題を保存するのstd ::文字列を作った場合、ラベル名を含んでいます。

次に、パーサの性能は、後続のinnerText文字列連結しながら、影響を受けるであろう、低減されます。

それに加えて、属性、タグ名を格納するために使用されるコンテナを誕生させる必要がありますか?

std :: <のstd ::文字列、のstd ::リスト<xnode * >>マップは、同時に、レコードラベル名を達成することができ、かつgetElementByTagNameは、ラベルインデックスの下でこの種のものを達成します。

std ::セット<はstd :: string>に:それはする必要がありますので、名前は定義に通常の属性、定数に等しい、再利用の確率は、素晴らしいことだろうか?

プロパティの値は、通常は可変であり、プロパティ名を持つ均一な方法を使用して、大きな変数の確率は、非常に適していないようですが、プロパティの値が真偽のように、例えば、発生する可能性があり、文字列の同じ数を繰り返しているようです。

したがって、属性値に設計する必要があります:のstd ::マップ<はstd ::文字列、unsigned int型>ヴァルデザイン参照カウントが0である、神経障害4000000000を解決することはほとんどありません何.. EMMをオフに消去ドキュメントノード、十分なので、unsigned int型。

 

だから、うちおよそ文書ソースデータ構造、と考えるのは:

構造体xsource {

    std ::リスト<はstd :: string>にドキュメント。

    std ::マップ<はstd ::文字列、のstd ::リスト<xnode * >>タグ;

    std :: <はstd :: string>にattr_names設定します。

    std ::マップ<はstd ::文字列、unsigned int型> attr_values。

}。

 

その結果xnodeの構造の変化は続きます:

構造体れるxattr {

    std ::セット<はstd ::文字列> ::イテレータ名。

    std ::マップ<はstd ::文字列、unsigned int型>の値。

}。

構造体xnode {

    std ::マップ<はstd ::文字列、のstd ::リスト<xnode * >> ::イテレータタグ。

    std ::リスト<xnode *> ::イテレータITAG; //タグは、削除xsource.docsからノードポインタを削除するために使用されます。

    std ::リスト<れるxattr> attrsに。

    std ::リスト<のstd ::文字列> ::イテレータinner_begin、inner_end。

    std ::リスト<xnode>チャイルズ。

    xnode *親。

    std ::リスト<xnode> ::イテレータ自己;

}。

この今夜について考え始めるために、私が最初にこのアイデアを実現する予備プレスを見てみましょう。

 

継続するには...

 

おすすめ

転載: www.cnblogs.com/babypapa/p/11785051.html