2

XMLファイルをデータストアとして作成したい。次のようになります。

<datastore>
    <item>
        <subitem></subitem>
        ...
        <subitem></subitem>
    </item>
    ....
    <item>
        <subitem></subitem>
        ...
        <subitem></subitem>
    </item>
</datastore>

実行時に、データストアにアイテムを追加する必要がある場合があります。アイテムの数が多い可能性があるため、ドキュメント全体をメモリに保持したくなく、DOMを使用できません。変化が起こる部分を書きたいだけです。または、DOMはこれをサポートしていますか?

私はStAXを最初に見ましたが、それが私が望むことをするかどうかはわかりません。

ルート要素が閉じられる直前のファイルの最後にあるカーソル位置を覚えておくのが最善ではないでしょうか。それは常に新しいアイテムが追加される位置です。したがって、その位置を覚えていて、変更中に最新の状態に保つと、ファイル全体を繰り返すことなく、最後に新しいアイテムを追加できます。

たぶん、2番目のカーソルは、最初のカーソルから独立して使用して、読む目的でドキュメントを反復処理することができます。

StAXがこれをサポートしていることがわかりませんね。

ストリームベースのAPIではなく、ファイル用のブロックベースのAPIはありませんか?ファイルとファイルシステムは、ブロック「デバイス」の典型的な例ではありませんか?そして、そのようなAPIがある場合、それは私の問題を解決するのに役立ちますか?

前もって感謝します。

4

4 に答える 4

1

XML を更新することは基本的に不可能です。データを挿入する「安価な」方法がないからです。

XML を追加することはそれほど悪くありません。そこで行う必要があるのは、ファイルの最後までシークし、「終了タグ」(この場合は </datastore>) を GO BACK してから、書き込みを開始することだけです。これは安価な操作ですが、どのフレームワークもこれを実際にサポートしていません。なぜなら、ほとんどのフレームワークは、適切に形成された完全なボートの XML ドキュメントを、バラバラではなく全体として動作するように設計されているためです。

StAX のようなものを使用することもできますが、この場合、StAX は <datastore> タグを認識せず、むしろ <item> タグとその要素を認識するだけです。次に、Items を作成し、設定した同じ OutputStream に何度も何度も書き込みを開始します。

これが最善の方法です。

しかし、データを削除または変更する必要がある場合は、要素を「非アクティブ」としてマークし、XML ファイルでそれらを探し出し、'active="Y"' 属性を探して、何かを書き直すか、ハックを行う必要があります。 Y を N にインプレースで変更します。それは可能です。ほとんどの場合効率的ですが、通常の XML 処理フレームワークでできることとはかけ離れています。もしそうするなら、ファイル全体を読んでそれらのエントリを追跡し、その中の場所をメモして、後で簡単に検索して効率的に変更できるようにします.

次に、何かを更新するときは、古いものを「非アクティブ化」し、新しいものを「追加」します。最終的に、ファイルをすべて書き換えて、古い「非アクティブ」なエントリを破棄することで、GC に到達します。

于 2011-01-26T19:22:06.803 に答える
1

経験則として、XML ファイルはデータストアとしてはあまり効率的ではありません。XML ファイルを使用したいと思われるレコードベースのデータには適していません。

ただし、既にファイルを取得していて、それに対して何もできない場合は、StAXXMLEventReaderとを使用XMLEventWriterしてファイルをすばやく読み取り、要素を挿入/変更できます。

しかし、簡単に言うと、DOM よりも高速ですが、リレーショナル DB ほど効果的ではありません。

更新:検討できる別のオプションはvtd-xmlです。実際のプロジェクトでは試していませんが、実際にはかなりまともに見えます。

于 2011-01-26T19:23:22.327 に答える
0

XML ファイルを部分的に更新するのは簡単でも効率的でもありません。

データを XML としてエクスポートするツールを備えた、適切なデータベースが必要なようです。

DB を使用せず、データを純粋に XML として格納することを主張する場合は、すべての項目をオブジェクトとしてメモリに保持することを検討してください。新しいものが追加されるたびに、それらすべてを XML に書き出すことができます。非効率に思えるかもしれませんが、データ サイズによってはそれでも十分な場合があります。

このパスを選択した場合は、Xstream ライブラリをチェックアウトして、これを非常に簡単にすることができます。簡単な例については、ストリーム チュートリアルを参照してください。

于 2011-01-26T23:41:04.323 に答える
0

常に最後に項目を追加したい場合、これを処理する最善の方法は、2 つの XML ファイルを用意することです。外側の datstore.xml は単純なラッパーで、次のようになります。

<!DOCTYPE datastore [
  <!ENTITY e SYSTEM "items.xml">
]>
<datastore>&e;</datastore>

ファイル items.xml は次のようになります。

<item>....</item>
<item>....</item>
<item>....</item>

ラッパー要素なし。

データを追加したい場合は、items.xml を開いてその末尾に書き込むことができます。データを読み取る場合は、datastore.xml を XML パーサーで開きます。

もちろん、データが 20Mb 程度を超えると、XML データベースを使用した方がよい場合もあります。しかし、私はこのアプローチを何年もの間、Saxon の注文の記録に使用しており、現在約 8Mb のファイルを使用しており、問題なく動作しています。

于 2011-01-26T23:24:55.100 に答える