2012-08-14 55 views
0

我见过不少文章,但实际上我没有得到任何工作。我正在构建一个简单的电视指南android应用程序。我简单地使用tvprofil.net中的RSS来显示今天的电视节目。问题是,我不知道如何解析XML中的CDATA。我使用一些标准的解析器使用DOM ......至少我是这么认为的..解析CDATA与XMLParser在这个特定情况下的ANDROID

这是一个有点XML的:

. 
. 
. 
<item> 
<title>RTS1 14.08.2012</title> 
<pubDate>Tue, 14 Aug 2012 06:00:00</pubDate> 
<content:encoded><![CDATA[06:00 Vesti<br>06:05 Jutarnji program<br>08:00 Dnevnik 
<br>8:15 Jutarnji Program<br>09:00 Vesti ... ]]></content:encoded> 
</item> 
. 
. 
. 

现在,这是我主要的应用程序:

public class Main extends ListActivity { 

// All static variables 
static final String URL = "http://tvprofil.net/rss/feed/channel-group-2.xml"; 
// XML node keys 
static final String KEY_ITEM = "item"; // parent node 
static final String KEY_NAME = "title"; 
static final String KEY_DATE = "pubDate"; 
static final String KEY_DESC = "content:encoded"; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 


    ArrayList<HashMap<String,String>> menuItems = new ArrayList<HashMap<String,String>>(); 



    XMLParser parser = new XMLParser(); 
    String xml = parser.getXmlFromUrl(URL); //get XML 
    Document doc = parser.getDomElement(xml); // get DOM elem. 



    NodeList nl = doc.getElementsByTagName(KEY_ITEM); 
    //loop 
    for (int i=0; i< nl.getLength(); i++){ 
     HashMap<String, String> map = new HashMap<String, String>(); 
     Element e = (Element) nl.item(i); 
     //add to map 
     map.put(KEY_NAME, parser.getValue(e, KEY_NAME)); 
     map.put(KEY_DATE, parser.getValue(e, KEY_DATE)); 
     map.put(KEY_DESC, parser.getValue(e, KEY_DESC)); 

     // hash => list 
     menuItems.add(map); 
    } 

    ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.list_item, 
      new String[]{KEY_NAME, KEY_DESC, KEY_DATE}, new int[]{ 
      R.id.name, R.id.description, R.id.date 
    }); 
    setListAdapter(adapter); 

    //singleView 
    ListView lv = getListView(); 

    lv.setOnItemClickListener(new OnItemClickListener(){ 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id){ 
      String name = ((TextView)view.findViewById(R.id.name)).getText().toString(); 
      String date = ((TextView)view.findViewById(R.id.date)).getText().toString(); 
      String description = ((TextView)view.findViewById(R.id.description)).getText().toString(); 

      //intent 
      Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class); 
      in.putExtra(KEY_NAME, name); 
      in.putExtra(KEY_DATE, date); 
      in.putExtra(KEY_DESC, description); 
      startActivity(in); 
     } 
    }); 

} 

} 

和解析器类:

public class XMLParser { 

// constructor 
public XMLParser() { 

} 

/** 
* Getting XML from URL making HTTP request 
* @param url string 
* */ 
public String getXmlFromUrl(String url) { 
    String xml = null; 


    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(url); 

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

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    // return XML 
    return xml; 
} 

/** 
* Getting XML DOM element 
* @param XML string 
* */ 

public Document getDomElement(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) { 
      Log.e("Error: ", e.getMessage()); 
      return null; 
     } catch (SAXException e) { 
      Log.e("Error: ", e.getMessage()); 
      return null; 
     } catch (IOException e) { 
      Log.e("Error: ", e.getMessage()); 
      return null; 
     } 

     return doc; 
} 

/** Getting node value 
    * @param elem element 
    */ 
public final String getElementValue(Node elem) { 

    Node child; 
    if(elem != null){ 
     if (elem.hasChildNodes()){ 
      for(child = elem.getFirstChild(); child != null; child = child.getNextSibling()){ 
       if(child.getNodeType() == Node.TEXT_NODE ){ 
        return child.getNodeValue(); 
       } 
      } 
     } 
    } 
    return ""; 
} 

/** 
    * Getting node value 
    * @param Element node 
    * @param key string 
    * */ 
public String getValue(Element item, String str) {  
     NodeList n = item.getElementsByTagName(str);   
     return this.getElementValue(n.item(0)); 
    } 
} 

有单菜单项多了一个类..但我认为这是无关紧要在这种情况下。 现在,我只想在解析它并处理CDATA后看到没有HTML标记... 任何人都知道这个吗?

+0

有没有需要一个特殊的方式来处理CDATA。只是像一个平常的项目解析它。我在我的一个应用程序中完成了它,并没有实现一些特殊的解析。 – denizt 2012-08-14 10:41:51

+0

可能代码行“static final String KEY_DESC =”content:encoded“;”会出问题吗?我应该在那里设置其他东西吗? – Igx33 2012-08-14 11:18:49

+0

只需使用**编码**而不是**内容:编码** – Khan 2012-08-14 11:21:28

回答

2

添加此

dbf.setCoalescing(true); 

其中DBF是

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
+0

嗯..我添加了它,但没有任何变化,我甚至在Log.w上设置它以显示解析后的字符串,但它仍然不会显示任何内容,也不会在手机或Log上显示...现在, ,maby标签“内容:编码”是一个问题,当我设置“静态最终字符串KEY_DESC =”内容:编码“;”...也许我应该设置别的东西? – Igx33 2012-08-14 11:15:25

0

getTextContent。 此属性返回此节点的文本内容和其后代

getNodeValue() 这个节点,这取决于它的类型的值;

通常你会使用getTextContent。

0

zg_spring的回答完全为我工作,当我需要在一组 “描述” XML元素从CDATA中提取图片网址:

//Get the content of all "item" elements  
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document doc = db.parse(new InputSource(new StringReader(xml))); 
NodeList nlDetails = doc.getElementsByTagName("item");  

//Loop through elements and extract content of "description" elements  
for(int k = 0; k < numDetails; k++) { 
    Element nDetails = (Element)nlDetails.item(k); 
    NodeList nlCoverURL = nDetails.getElementsByTagName("description");   
    Node nCoverURL = nlCoverURL.item(0); 
    String sCoverURL = nCoverURL.getTextContent(); 

    //Isolate the relevant part of the String and load it into an ArrayList 
    String[] descriptionContent = sCoverURL.split("\""); 
    String s = descriptionContent[11] 
    alImages.add(s); 
} 
1
  1. 首先添加此方法

    public String getCharacterDataFromElement(Element e, String str) { 
    NodeList n = e.getElementsByTagName(str); 
    Element e1=(Element) n.item(0); 
    
    Node child = e1.getFirstChild(); 
    if (child instanceof CharacterData) { 
        CharacterData cd = (CharacterData) child; 
        return cd.getData(); 
    } 
    return ""; 
    } 
    
  2. 致电上述方法 -

    map.put(KEY_DESC, parser.getCharacterDataFromElement(e, KEY_DESC)); 
    

这应该让你在字符串格式的CDATA。 HOpe这可以帮助