1

XML から最上位要素のリストを取得しようとしています (重複したサブ要素が含まれています)。

XML の例

<feed>
   <folder name="subfolder1">
       <file name="subfile1" />
       <file name="subfile2" />
       <folder name="subsubfolder1">
            <file name="subsubfile1" />
            <file name="subsubfile2" />
        </folder>
   </folder>
   <folder name="subfolder2">
       <file name="subfile1" />
       <file name="subfile2" />
       <folder name="subsubfolder1">
            <file name="subsubfile1" />
            <file name="subsubfile2" />
        </folder>
   </folder>
   <file name="file1"/>
</feed>

トップレベルの要素のすべての名前のリストを取得しようとしています。

.subfolder1
.subfolder2

これが私のフィードリーダーです....

private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
        List<Entry> entries = new ArrayList<Entry>();

        Log.v("ab", "reed feed started");

        parser.require(XmlPullParser.START_TAG, ns, "feed");
        while (parser.next() != XmlPullParser.END_TAG) {

            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String sectionName = parser.getName();

            if(sectionName.equals("folder")) {
                readFolder(parser);
            } 
        }

        return entries;
    }

private void readFolder (XmlPullParser parser) throws XmlPullParserException, IOException  {
        parser.require(XmlPullParser.START_TAG, ns, "folder");
        Log.v("ab", parser.getAttributeValue(null, "name"));
        parser.require(XmlPullParser.END_TAG, ns, "folder");
    }

そして、ここに私のLogCatがあります....

09-02 13:40:22.537  31736-31753/? V/ab reed feed started
09-02 13:40:22.537  31736-31753/? V/ab﹕ subfolder1

フォルダー要素の最初のインスタンスを見つけた後にこれが停止する理由を誰か助けてもらえますか?

4

1 に答える 1

1

最後の parser.require 行に問題があるようです:

parser.require(XmlPullParser.END_TAG, ns, "folder");

ドキュメントから、ここで行っていることは、これらの条件が満たされているかどうかを確認し、満たされていない場合は例外をスローすることです。つまり、あなたは今読んだばかりの 'folder' 開始タグにいて、'folder' 終了タグにいるかどうかをチェックしています。'folder' 終了タグにいないため、parser.require は例外をスローします。

その行を削除すると、while ループが次のフォルダー開始タグまで継続するようになります。

編集:ここに完全な解決策があります

END_TAG までだけでなく、ドキュメントの最後まで続行する必要があるため、while ループを に修正しwhile (parser.next() != XmlPullParser.END_DOCUMENT)、readFolder メソッド呼び出しの後にコードを追加しました。私が正しく理解していれば、「サブフォルダー」という名前のフォルダーの後にのみあり、「サブサブフォルダー」をスキップしています。そのため、それらをスキップするループを含めました。個人的に必要性を感じなかったので、 parser.require 行も削除しましたが、これはそれを行う 1 つの方法にすぎません。

private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    List<Entry> entries = new ArrayList<Entry>();

    Log.v("ab", "reed feed started");

    while (parser.next() != XmlPullParser.END_DOCUMENT) {

        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String sectionName = parser.getName();

        if(sectionName.equals("folder")) {
            readFolder(parser);

            //these booleans will be used to help us skip the subfolders
            boolean finishedTopLevelElement = false;
            boolean unwantedSubFolderFound = false;

            //this will loop until we are at a "folder" tag and have 
            //confirmed we have finished with the top level folder
            while (!(("folder".equals(parser.getName())) && finishedTopLevelElement)){
                parser.next();

                //we only care about 'folder' tags, for anything else
                //we keep looping
                if ("folder".equals(parser.getName())){

                    if (parser.getEventType() == XmlPullParser.START_TAG){

                        //if we hit a folder start tag, we're at a sub-folder
                        unwantedSubFolderFound = true;

                    } else if (parser.getEventType() == XmlPullParser.END_TAG && !unwantedSubFolderFound){

                        //if we hit a 'folder' end tag and we've not got an unwanted subfolder then
                        //we're done, it's the end tag of the top-level folder
                        finishedTopLevelElement = true;
                        unwantedSubFolderFound = false;

                    } else {

                        //if it's a folder end tag and we HAVE previously found an unwanted sub folder start tag
                        //then we've successfully skipped that sub-folder and can keep looking
                        unwantedSubFolderFound = false;
                    }
                }


            }
        } 
    }

    return entries;
}

private void readFolder (XmlPullParser parser) throws XmlPullParserException, IOException  {
    Log.v("ab", parser.getAttributeValue(null, "name"));
}
于 2015-09-02T14:59:23.663 に答える