【问题标题】:Parse CDATA with XMLParser in this specific case for ANDROID在 ANDROID 的这种特定情况下,使用 XMLParser 解析 CDATA
【发布时间】:2012-08-14 10:32:07
【问题描述】:

我看过很多关于这个的帖子,但实际上我没有得到任何工作。我正在构建一个简单的电视指南 android 应用程序。我只是使用来自 tvprofil.net 的 RSS 来显示今天电视上的内容。问题是,我不知道如何在 XML 中解析 CDATA。我正在使用一些带有 DOM 的标准解析器……至少我是这么认为的……

这是一些 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 标记... 有人知道这个吗?

【问题讨论】:

  • 不需要特殊的方法来处理 CDATA。只需像通常的项目一样解析它。我在我的一个应用程序中做到了,但我没有实现一些特殊的解析。
  • 这行代码“static final String KEY_DESC = "content:encoded"; "可能有问题吗?我应该在那里设置其他东西吗?
  • 只使用 encoded 而不是 content:encoded
  • 您必须在开始解析之前对文档进行规范化()。尝试在 getDomElement 函数中添加 doc.getDocumentElement().normalize()。
  • 试过了,还是不行……该死的

标签: android xml xml-parsing cdata


【解决方案1】:

添加这个

 dbf.setCoalescing(true); 

dbf 在哪里

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

【讨论】:

  • hmm.. 我添加了它,但没有任何改变,我什至在 Log.w 上设置了它,以便在解析后向我显示字符串,但它仍然没有显示任何内容,也没有显示在电话或日志上......现在我很忙,也许标签“内容:编码”是个问题,当我设置“静态最终字符串KEY_DESC =“内容:编码”;“......也许我应该设置别的东西?
【解决方案2】:
  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。希望这会有所帮助

【讨论】:

    【解决方案3】:

    获取文本内容。 该属性返回该节点的文本内容及其 后代

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

    通常你应该使用 getTextContent。

    【讨论】:

      【解决方案4】:

      当我需要在一组“描述”xml 元素中从 CDATA 中提取图像 URL 时,zg_spring 的答案对我来说非常有效:

      //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);
      } 
      

      【讨论】:

        猜你喜欢
        • 2021-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-24
        • 1970-01-01
        • 2016-07-29
        • 1970-01-01
        相关资源
        最近更新 更多