2

RSS フィードからデータを読み取ることを目的とした練習用アプリケーションを作成しています。

私のアプリケーションで特殊文字の問題が発生したことを除けば、これまでのところうまくいっています。ノード内の最初の特殊文字を読み取り、次のノードに移動します。

助けていただければ幸いです。その後に続く大きなコード ブロックについては申し訳ありません。

RSS フィード - www.usu.co.nz/usu-news/rss.xml

<title>Unitec hosts American film students</title>
<link>http://www.usu.co.nz/node/4640</link>
<description>&lt;p&gt;If you’ve been hearing American accents around the Mt Albert campus over the past week.</description>

表示コード

String xml = XMLFunctions.getXML();
Document doc = XMLFunctions.XMLfromString(xml);

NodeList nodes = doc.getElementsByTagName("item");

for (int i = 0; i < nodes.getLength(); i++) 
{                           
    Element e = (Element)nodes.item(i);
    Log.v("XMLTest", XMLFunctions.getValue(e, "title"));
    Log.v("XMLTest", XMLFunctions.getValue(e, "link"));
    Log.v("XMLTest", XMLFunctions.getValue(e, "description"));  
    Log.v("XMLTest", XMLFunctions.getValue(e, "pubDate"));
    Log.v("XMLTest", XMLFunctions.getValue(e, "dc:creator"));
}

リーダーコード

public class XMLFunctions 
{

public final static Document XMLfromString(String xml)
{

    Document doc = null;

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {

        DocumentBuilder db = dbf.newDocumentBuilder();

        InputSource is = new InputSource();
        is.setCharacterStream(new StringReader(xml));
        doc = db.parse(is); 

    } catch (ParserConfigurationException e) {
        System.out.println("XML parse error: " + e.getMessage());
        return null;
    } catch (SAXException e) {
        System.out.println("Wrong XML file structure: " + e.getMessage());
        return null;
    } catch (IOException e) {
        System.out.println("I/O exeption: " + e.getMessage());
        return null;
    }

    return doc;

}

/** Returns element value
  * @param elem element (it is XML tag)
  * @return Element value otherwise empty String
  */
 public final static String getElementValue( Node elem ) {
     Node kid;
     if(elem != null)
     {
         if (elem.hasChildNodes())
         {
             for(kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling())
             {
                 if( kid.getNodeType() == Node.TEXT_NODE  )
                 {
                     return kid.getNodeValue();
                 }
             }
         }
     }
     return "";
 }

 public static String getXML(){  
        String line = null;

        try {

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost("http://www.usu.co.nz/usu-news/rss.xml");

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            line = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
        } catch (MalformedURLException e) {
            line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
        } catch (IOException e) {
            line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
        }

        return line;

}

public static int numResults(Document doc){     
    Node results = doc.getDocumentElement();
    int res = -1;

    try{
        res = Integer.valueOf(results.getAttributes().getNamedItem("count").getNodeValue());
    }catch(Exception e ){
        res = -1;
    }

    return res;
}

public static String getValue(Element item, String str) {       
    NodeList n = item.getElementsByTagName(str);        
    return XMLFunctions.getElementValue(n.item(0));
}
}

出力

Unitec hosts American film students
http://www.usu.co.nz/node/4640
<
Wed, 01 Aug 2012 05:43:22 +0000
Phillipa
4

5 に答える 5

3

コードは、要素から最初の子テキスト ノードのみを抽出します。DOM 仕様では、隣接する複数のテキスト ノードが許可されているため、ここで起こっていることは、パーサーが<p>および残りのテキストを (少なくとも) 4 つの別個のテキスト ノードとして表していると思われます。ノードを連結して 1 つの文字列にするかnormalize()、含まれている要素ノードを呼び出す必要があります (隣接するテキスト ノードを 1 つにマージするように DOM ツリーを変更します)。

あなたを助けることができるさまざまなライブラリがあります。たとえば、アプリケーションが Spring フレームワークを使用している場合、要素から完全なテキスト値を抽出org.springframework.util.xml.DomUtilsするgetTextValue静的メソッドがあります。

于 2012-08-06T09:55:03.397 に答える
2

あなたの機能

public final static String getElementValue( Node elem ) {
    Node kid;
    if(elem != null)
    {
        if (elem.hasChildNodes())
        {
            for(kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling())
            {
                if( kid.getNodeType() == Node.TEXT_NODE  )
                {
                    return kid.getNodeValue();
                }
            }
        }
    }
    return "";
}

指定された要素の下にある最初のテキスト ノードを返します。1 つのタグ内のテキストのチャンクは、複数のテキスト ノードに分割できます。これは、特殊文字が存在する場合に発生する傾向があります。

おそらく、すべてのテキスト ノードを戻り値の文字列に追加する必要があります。

おおよそ次のようなものが機能する可能性があります。

public final static String getElementValue( Node elem ) {
    if ((elem == null) || (!(elem.hasChildNodes())))
        return "";

    Node kid;
    StringBuilder builder = new StringBuilder();
    for(kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling())
    {
        if( kid.getNodeType() == Node.TEXT_NODE  )
        {
            builder.append(kid.getNodeValue());
        }
    }
    return builder.toString();
}
于 2012-08-06T09:52:47.227 に答える
1

少し本題から外れますが、既存の RSS フレームワークの 1 つ ( ROMEなど) をチェックしてみてください。車輪の再発明よりも優れています。

于 2012-08-06T10:37:07.173 に答える
0

XML 文字列が DefaultHttpClient によって変換されていませんか? 私はあなたのコードを試し、メソッド XMLFunctions.getXML() を変更して、XML 文字列を DefaultHttpClient で取得するのではなく、直接フィードするようにしました。出力は次のようになります。

Unitec hosts American film students
http://www.usu.co.nz/node/4640
<p>If you’ve been hearing American accents around the Mt Albert campus over the past week.

予想通り。

于 2012-08-06T09:44:57.800 に答える
0

<?xml version="1.0" encoding="UTF-8"?>行方不明のようです。また、ルート要素はありません。

于 2012-08-06T09:26:58.880 に答える