1

XmlPullParser がその XML をデータ モデル クラスにバインドするための推奨されるソリューションである Android アプリケーションに XML があります。XmlPullParser の Android ドキュメントは、要素間の空白を処理する方法を除いて、かなり優れています。推奨されるアプローチは、低レベルの IGNORABLE_WHITESPACE 解析イベントを検出し、それらのイベントをスキップすることです。ただし、受け入れようとしている XML の場合、このアプローチはうまくいきません。低レベルの IGNORABLE_WHITESPACE イベントが発生していることはありません。XmlPullParser の動作、受け入れ可能な XML、または構成の問題など、特定のユース ケースのいくつかの側面を正しく理解していないと私は信じています。

私が受け入れようとしている XML スニペットの簡単なテスト ケースは次のとおりです。

<a>  <b></b>  </a>

推奨される getNextToken() メソッドでこの要素を受け入れるために使用しているコード ハックは次のとおりです。

            boolean hasEvent = false;
            String desc = null;
            while (!hasEvent) {
                result = xpp.nextToken();
                desc = xpp.getPositionDescription();
                Log.i(TAG, String.format("Processing: %s", desc));
                switch (result) {
                case START_TAG:
                case END_TAG:
                case END_DOCUMENT:
                    hasEvent = true;
                    break;

                case TEXT:
                    // Use a real hack to detect whitespace.
                    if (desc.contains("TEXT (whitespace)@")) {
                        hasEvent = false;
                    } else {
                        hasEvent = true;
                    }
                    break;

                default:
                    break;
                }
            }

基本的には、START_TAG(a) を取得、TEXT (空白) を取得、START_TAG(b) を取得、END_TAG(b) を取得、TEXT (空白) を取得、END_TAG(a) を取得。

質問は次のとおりです。私が正しく理解していないのは何ですか? そして、醜いハックに頼ることなく、このシーケンスをどのように受け入れることができますか?

これは疑わしい XML であるという予感がありますが、これは私が提示するものを代表するものです。つまり、入力ストリーム内の要素間の空白を制御することはできません。

fwiw、Simple Framework for XML は問題なくこの入力ストリームを処理し、私の好みのアプローチですが、そのパッケージは、基礎となる stax および epp ライブラリとの依存関係の競合により、Gradle および Android Studio で使用するのが非常に面倒ですが、それはまったく別の問題。

4

1 に答える 1

0

私自身の質問にある程度答えるために、ある時点で私の状況に陥った開発者に次のことを提案します。しかし、すぐにさらに良い答えが得られることを非常に楽しみにしています。

理解不足に関しては、最初のポイントは、非検証パーサーを使用していることを理解したということです。この主張は、isWhitespace() の Android XmlPullParser ソース コード/Javadoc で行われます。

注意: 非検証パーサーは、ルート要素の外側の空白を除いて、空白と無視できる空白を区別できません。無視できる空白は別のイベントとして報告され、nextToken を介してのみ公開されます。

これにより、JAXB と Simple はパーサーを検証しており、この要素間の空白をスムーズに処理できると信じていますが、今では明示的に処理する必要があります。

傘の理解の欠如に該当する 2 つ目のポイントは、Android の XmlPullParser は、検証をサポートする「スキーマ」を提供することによってのみ検証パーサーを作成できることです。これは、このインスタンスではほとんど制御できません。

要素間の空白を処理するより洗練された方法として、私の答えは次の START_TAG または END_TAG イベントを返すが、テキストが空白であるすべての TEXT イベントを破棄する getNextElement() という 2 つのメソッドを持つことです。解析エラーと見なされます。もう 1 つのメソッドは getNextText() で、TEXT または CDSECT 解析イベントからテキストを返し、その他のイベントをエラーとして報告します。

私が言ったように、私はより良い答えを楽しみにしています。

于 2014-03-02T06:46:51.167 に答える