2011-09-16 4 views
1

私はRSSリーダーで非常に簡単なアプリケーションを作っています。読者は素晴らしい作品ですが、それは私にタイトルを与えてくれるだけで、私もその説明が欲しいです。 私はアンドロイドにとってとても新しいです。私はたくさんのことを試しましたが、うまく動作することはできません。 私は多くのパーサを見つけましたが、理解するのが難しいので、簡単な解決策を見つけることを望んでいました。タイトルと説明だけです。 誰でも助けてくれますか?Java -Android。パーサーの問題

import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.xml.sax.Attributes; 
import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLReader; 
import org.xml.sax.helpers.DefaultHandler; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

public class NyhedActivity extends Activity { 
    String streamTitle = ""; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.nyheder); 

     TextView result = (TextView)findViewById(R.id.result); 

      try { 
     URL rssUrl = new URL("http://tv2sport.dk/rss/*/*/*/248/*/*"); 
     SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance(); 
     SAXParser mySAXParser = mySAXParserFactory.newSAXParser(); 
     XMLReader myXMLReader = mySAXParser.getXMLReader(); 
     RSSHandler myRSSHandler = new RSSHandler(); 
     myXMLReader.setContentHandler(myRSSHandler); 
     InputSource myInputSource = new InputSource(rssUrl.openStream()); 
     myXMLReader.parse(myInputSource); 

     result.setText(streamTitle); 

     } catch (MalformedURLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     result.setText("Cannot connect RSS!"); 
     } catch (ParserConfigurationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     result.setText("Cannot connect RSS!"); 
     } catch (SAXException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     result.setText("Cannot connect RSS!"); 
     } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     result.setText("Cannot connect RSS!"); 
     } 


     } 

     private class RSSHandler extends DefaultHandler 
     { 
     final int stateUnknown = 0; 
     final int stateTitle = 1; 
     int state = stateUnknown; 

     int numberOfTitle = 0; 
     String strTitle = ""; 
     String strElement = ""; 

     @Override 
     public void startDocument() throws SAXException { 
     // TODO Auto-generated method stub 
     strTitle = "Nyheder fra "; 
     } 

     @Override 
     public void endDocument() throws SAXException { 
     // TODO Auto-generated method stub 
     strTitle += ""; 
     streamTitle = "" + strTitle; 
     } 

     @Override 
     public void startElement(String uri, String localName, String qName, 
     Attributes attributes) throws SAXException { 
     // TODO Auto-generated method stub 
     if (localName.equalsIgnoreCase("title")) 
     { 
     state = stateTitle; 
     strElement = ""; 
     numberOfTitle++; 
     } 
     else 
     { 
     state = stateUnknown; 
     } 
     } 

     @Override 
     public void endElement(String uri, String localName, String qName) 
     throws SAXException { 
     // TODO Auto-generated method stub 
     if (localName.equalsIgnoreCase("title")) 
     { 
     strTitle += strElement + "\n"+"\n"; 
     } 
     state = stateUnknown; 
     } 

     @Override 
     public void characters(char[] ch, int start, int length) 
     throws SAXException { 
     // TODO Auto-generated method stub 
     String strCharacters = new String(ch, start, length); 
     if (state == stateTitle) 
     { 
     strElement += strCharacters; 
     } 
     } 
    } 

} 
+0

あなたが投稿したコードは、説明を読むことさえも*試行していません。タイトルにはコードだけが含まれています。 –

+0

私はそれがすべてを台無しにしたので、私は他のコードを削除したためです。 私はそれを正しくするための解決策を探しています:) – Kano

答えて

1

JavaのXML解析では、SAXを使ったことはありません。私はいつもJDOMを使用します。シンプルで使いやすいです。

JDOMでXMLファイルを読み込むには、ドキュメントを作成し、InputStreamとSAXBuilderを使用してそれを埋める:あなたの投稿の場合

SAXBuilder builder = new SAXBuilder(); 
Document document = builder.builder(myInputStream); 

myInputStream = url.openStream();

次にあなたがフェッチする必要がありますXML文書のルート:

Element root = document.getRootElement(); 

これで非常に簡単です。

List<Element> news = root.getChildren("news"); 

:あなたは、このようなすべての要素を一覧表示することができます

<rssfeed> 
    <news> 
    <title> Title </title> 
    <description> Description </description> 
    </news> 
    <news> 
    <title> ... </title> 
    <description> ... </description> 
    </news> 
    <news> 
    <title> ... </title> 
    <description> ... </description> 
    </news> 
<rssfeed> 

:私はあなたが取得しているXMLの構造を知らないので、私はちょうどそれのようなものに見えることを前提としています

ArrayList<News> newsList = new ArrayList<News>(); 
for(Element child : news) { 
    News news = new News(); 
    news.setTitle(child.getChildText("title"); 
    news.setDescription(child.getChildText("description"); 
    newsList.add(news); 
} 

は、今あなたが持っている:そして、あなたはタイトルと説明を(ニュース・クラスなどの助けになり、これらの情報を保持するために、データ・クラスを持つ)取得のために、各ループでリストを実行しますあなたのニュースのリスト周りの遊び。

私はあなたを助けることを願って
+0

あなたの提案に感謝しますが、答えは現時点で私のスキルレベルを少し上回っています。私は多くのチュートリアルを見つけましたが、現時点ではすべてのコード行を理解していないため、自分のパーサークラスを書くことが非常に難しくなっています。私は取得しています データは次のとおりです。 タイトル 説明 Kano

+0

JDOMを使用してのアイデアは、解析クラスがあなたのために書かれていることであり、あなたが必要とするすべてのためにそれを使用することです必要なデータを入手してください。 JDOMをダウンロードしてプロジェクトのビルドパスに追加すると、実際にサンプルをコピー&ペーストすることができます。あなたがする必要があるのは、文字列 "news"を "item"に置き換えるだけです。それはうまくいくはずです。 – kaspermoerch

+0

ありがとうございます。私はそれをすることができると確信していないにもかかわらず、私はそれを試みます:) – Kano

0

@Override 
    public void endElement(String uri, String localName, String qName) 
    throws SAXException { 
    // TODO Auto-generated method stub 
    if (localName.equalsIgnoreCase("title")) 
    { 
    strTitle += strElement + "\n"+"\n"; 
    } 
    else if (localName.equalsIgnoreCase("lead")) 
    { 
    lead += strElement + "\n"+"\n"; 
    } 
    } 
+0

私はそれを試みたが、それは動作しません。なぜリード?それは説明ではありませんか? 上記のコードで書くことができます。私はすべてのことが正しいことを確認していますか? – Kano

1

狩野、

あなたはあなたの人生を簡素化し、(免責事項:私は著者午前)このRSSフィードパーサーを書くことSJXPを利用してtop-notch performanceを得ることができます。

SJXPはXML Pull Parsing APIの上にあり(Androidは独自のものを提供するので、sjxp.JARの依存関係のみ、他のすべてのプラットフォームにはXPP3)、XPathのような構文解析ルールを使用できます。ドキュメントの特定の場所に対して単純な規則を照合し、次にそれらの場所から必要な情報を解析するように指示します。

私は6分間でTV2 Sportsフィードを解析するためのEclipseプロジェクトの例を書いています(下にリンクします)。

主な方法は、あなたが流れのアイデアを得る次のようになります。

public static void main(String[] args) throws IllegalArgumentException, 
    XMLParserException, IOException { 
// Location we want to parse. 
URL feedURL = new URL("http://tv2sport.dk/rss/*/*/*/248/*/*"); 

// List we will hold all parsed stories in. 
List<Item> itemList = new ArrayList<Item>(); 

// Get all the rules we will use to parse this file 
IRule[] rules = createRules(); 

// Create the parser and populate it with the rules. 
XMLParser<List<Item>> parser = new XMLParser<List<Item>>(rules); 

// Parse the RSS feed. 
parser.parse(feedURL.openStream(), itemList); 

// Print the results. 
System.out.println("Parsed " + itemList.size() + " RSS items."); 

for (Item i : itemList) 
    System.out.println("\t" + i); 
} 

あなたはフローは、我々はドキュメントからそれらを解析するように私たちの項目を保持するために私たちのリストを作成して開始します参照してください。その後、パーサに与える一連のIRuleインスタンスを取得し、パーサーを作成し、作業中に使用するルールを与えます。

次に、フィードの内容についてparseメソッドを呼び出し、「ユーザーオブジェクト」と呼ばれるものを渡します。具体的には、ルールにパススルーしたいもののインスタンスだけです。実行する。

この場合、項目を追加できるようにリストにアクセスしたいので、それを渡すだけで、パーサーは実行するとすぐにIRule logicに渡します。

Itemクラスを利用してデータを保持し、印刷が素敵に見えるようにするだけのシンプルなPOJOです:

public class Item { 
    public String title; 
    public String description; 

    @Override 
    public String toString() { 
     return "Item [title='" + title + "', description='" + description + "']"; 
    } 
} 

あなたは(文字をターゲットにしている要素の種類を定義する場所すべての興味深いものがあなたのiRuleで起こりますデータ、属性データまたはタグのオープン/クローズイベントのみ)、IRuleインターフェイスから適切なメソッドをオーバーライドして、何かを行うハンドラを提供します。例えば

は、ここでタイトルを解析ハンドラは次のとおりです。

IRule<List<Item>> itemDescRule = new DefaultRule<List<Item>>(Type.CHARACTER, "/rss/channel/item/description") { 
    @Override 
    public void handleParsedCharacters(XMLParser<List<Item>> parser, String text, List<Item> userObject) { 
     Item item = userObject.get(userObject.size() - 1); 
     item.description = text; 
    } 
}; 

あなたはパーサのインスタンス自体を与え得ることがわかりますが、早期の解析終了する場合(あなたが「STOP」メソッドをトリガーすることができます)、あなたは文字データであるテキストを取得し、あなたはあなたに渡された私たちのリストになった 'ユーザーオブジェクト'を取得します。

私たちは私たちがリストから移入しているアイテムをつかんで、その説明を与えてください。 2行のコード。

オープンタグに遭遇するたびに新しい項目をリストに追加するもう1つのIRuleがあります。これは、このような後続のルールでエンド要素をリストからポップして移入することができます。

プロジェクトを実行すると、出力は次のようになります。

Parsed 50 RSS items. 
    Item [title='Barcas bøddel beæret over Barca-føler', description='Tirsdag snød Thiago Silva Barcelona for tre point, da han headede AC Milans udligning i kassen i Champions League-kampens overtid.'] 
    Item [title='Guardiola: Pato hurtigere end Usain Bolt', description='FC Barcelona-træner, Josep Guardiola, er dybt imponeret af Milan-målscoreren Alexandre Patos hurtighed.'] 
    Item [title='Milan-profil: Vi kan nå semifinalen', description='Clarence Seedorf mener, at AC Milan kan nå semifinalerne i Champions League efter 2-2 i Barcelona.'] 
    <SNIP...> 

あなたは私があなたhereのために作成した全体のEclipseプロジェクトをダウンロードすることができます。

希望に役立ちます。

+0

ありがとうございました。私はtommorowそれを見てみましょう。 私の問題の解決策が見つかりましたが、私はあなたのプロジェクトを見て、あなたの解決策が良いかどうかを見ていきます。私は後でコメントを残します。 – Kano