私はBluetoothカメラとインターフェースするAndroidアプリに取り組んでいます。カメラに保存されているクリップごとに、クリップに関するいくつかのフィールド(ユーザーが変更できるフィールド)をXMLファイルに保存します。
現在、このアプリはこのxmlデータをデバイスに書き込む唯一のアプリですが、将来的にはデスクトップアプリまたはiPhoneアプリもここにデータを書き込む可能性があります。別のアプリにも追加のフィールドを含めることができないと仮定したくありません(特に、このバージョンがまだサポートしていない新しいフィールドを追加した新しいバージョンのアプリがある場合)。
したがって、私が防ぎたいのは、別のアプリケーションでこのXMLファイルに新しいフィールドを追加し、ユーザーがAndroidアプリを使用して、他のフィールドを知らないためにそれらのフィールドを消去するという状況です。
それでは、架空の例を見てみましょう。
<data>
<title>My Title</title>
<date>12/24/2012</date>
<category>Blah</category>
</data>
デバイスから読み取ると、これは次のようなClipオブジェクトに変換されます(簡潔にするために簡略化されています)
public class Clip {
public String title, category;
public Date date;
}
そのため、SAXを使用してデータを解析し、クリップに保存しています。文字をStringBuilderに保存し、title、category、dateのend要素に到達したときにそれらを書き出すだけです。
しかし、このデータをデバイスに書き戻すときに、元のドキュメントに他のタグがあった場合、私が知っているフィールドのみを書き出すため、それらは書き込まれないことに気付きました。
これにより、SAXは間違ったオプションである可能性があり、DOMなど、元々存在していた他の要素をより簡単に書き出すことができるものを使用する必要があると思います。
あるいは、Clipクラスに一般的なXMLタイプ(おそらくDOM)のArrayListが含まれているのではないかと考えていました。startTagで、要素が事前定義されたタグの1つではないかどうかを確認し、含まれている場合は、そのタグの最後に到達するまで構造全体を保存します(ただし、何に保存しますか?)。次に、書き戻すときに、追加のタグをすべて調べて、xmlファイルに書きます(もちろん、知っているフィールドと一緒に)。
これはよく知られた解決策の一般的な問題ですか?
-更新5/22/12-
実際のxmlではルートノード(実際にはアノテーションと呼ばれます)で、1に設定されたバージョン番号を使用していることは言及しませんでした。短期的には、アプリのバージョン番号が必要です。サポートは>=xmlデータのバージョン番号です。xmlの数値が大きい場合は、読み取りのために解析を試みますが、モデルへの保存は拒否します。これを行う方法については、私はまだあらゆる種類の実用的な例に興味があります。
ところで、私はかなり簡単なはずの別の解決策を考えました。XPATHを使用して、知っているノードを見つけ、データが更新されたときにそれらのノードのコンテンツを置き換えることができると思います。ただし、いくつかのベンチマークを実行したところ、メモリに解析されるときにxmlを解析する際のオーバーヘッドはばかげています。ルックアップを行わずに解析操作を行うだけで、パフォーマンスはSAXの20分の1になりました。xpathの使用は、解析で一般に30〜50倍遅くなりました。これは、リストビューで解析することを考えると非常に悪い結果でした。したがって、私の考えは、SAXを保持してノードをクリップに解析することですが、XML全体をClipクラスの変数に格納します(このxmlは短く、2kb未満であることを忘れないでください)。次に、データを書き戻すときに、XPATHを使用して、元のXMLで認識しているノードを置き換えることができます。
ただし、他のソリューションにはまだ関心があります。いくつかのコード例が含まれていない限り、私はおそらく解決策を受け入れません。