【问题标题】:cannot in parsing nested xml structure无法解析嵌套的 xml 结构
【发布时间】:2012-05-17 12:23:27
【问题描述】:

这是我的 xml 结构:

<menu>
<item_category>
<category_name>ICECREAM</category_name>
<item>
<item_name>SOFTY</item_name>
<item_price>7.00</item_price>
</item>
<item>
<item_name>STICK</item_name>
<item_price>15.00</item_price>
</item>
<item>
<item_name>CONE</item_name>
<item_price>25.00</item_price>
</item>
</item_category>
<item_category>
<category_name>PIZZA</category_name>
<item>
<item_name>PIZZA-HOT</item_name>
<item_price>35.00</item_price>
</item>
<item>
<item_name>PIZZA-CRISPY</item_name>
<item_price>29.00</item_price>
</item>
</item_category>
</menu>

这是我正在解析为列表视图的代码

public class AndroidXMLParsingActivity extends ListActivity {

    // All static variables
    //static final String URL = "http://api.androidhive.info/pizza/?format=xml";
    static final String URL = "http://192.168.1.112/dine/index.php/dineout/mob_view";
    //static final String URL = "http://192.168.1.112/dineout/index.php/dineout/view";

    // XML node keys
    static final String KEY_MENU= "menu"; // parent node
    //static final String KEY_ID = "foodjoint_id";
    static final String KEY_CATEGORY= "category_name";

    static final String KEY_ITEM= "item";
    static final String KEY_ITEM_NAME= "item_name";
    static final String KEY_PRICE= "item_price";


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

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

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

        NodeList nl = doc.getElementsByTagName(KEY_ITEM);


        // looping through all item nodes <item>
        for (int i = 0; i < nl.getLength(); i++) 
        {
            HashMap<String, String> map = new HashMap<String, String>();
            Element e = (Element) nl.item(i);

          map.put(KEY_CATEGORY, parser.getValue(e,KEY_CATEGORY));
         map.put(KEY_ITEM_NAME, parser.getValue(e, KEY_ITEM_NAME));
           map.put(KEY_PRICE, parser.getValue(e, KEY_PRICE));



            menuItems.add(map);
            }


        // Adding menuItems to ListView
        ListAdapter adapter = new SimpleAdapter(this, menuItems,
                R.layout.list_item,
new String[] {KEY_CATEGORY,KEY_ITEM_NAME,KEY_PRICE}, new int[] {R.id.category,R.id.name,R.id.costlab });

        setListAdapter(adapter);

        // selecting single ListView item
        ListView lv = getListView();

        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // getting values from selected ListItem
                String category = ((TextView) view.findViewById(R.id.category)).getText().toString();
                String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
                //String description = ((TextView) view.findViewById(R.id.desciption)).getText().toString();
                String cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
                // Starting new intent
                Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
                //in.putExtra(KEY_ITEM, name);

                in.putExtra(KEY_CATEGORY, category);
                in.putExtra(KEY_ITEM_NAME,name);
                in.putExtra(KEY_PRICE, cost);

                //in.putExtra(KEY_DESC, description);
                startActivity(in);

            }
        });
    }
}

我的问题是我没有得到 category_name 的值。我尝试使用嵌套循环,但它都一样。请帮我 。我应该在代码中更改什么。

这是我的 xmlParser

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

【问题讨论】:

  • @derekerdmann 抱歉,我无法了解您要更改的内容
  • 最后一个块中的第一行代码没有缩进,我只是把它推到同一个格式化块中。您可以通过单击问题底部的“已编辑 N 分钟前”来查看差异。
  • 另外,请查看常见问题解答以获取有关编辑的更多信息:stackoverflow.com/faq#editing
  • 得到它与否比我添加我的答案
  • @khan 抱歉回复晚了,我会检查

标签: android xml-parsing


【解决方案1】:

试试这个方法

NodeList n,ncategories;
Element e;
static final String KEY_ITEMCATEGORY= "item_category";
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();


   ncategories = doc.getElementsByTagName(KEY_MENU);

   for(int i=0;i<ncategories.getLength();i++){
       e=(Element)ncategories.item(i);
       n=e.getElementsByTagName(KEY_ITEMCATEGORY);

       for(int c=0;c<n.getLength();c++){ 
         HashMap<String, String> map = new HashMap<String, String>();
          e=(Element)n.item(c);

        String category= parser.getValue(e, KEY_CATEGORY).toString();
          Log.e("catname", parser.getValue(e, KEY_CATEGORY).toString());
          map.put(KEY_CATEGORY, category);

          NodeList  ns=e.getElementsByTagName(KEY_ITEM);
          for(int j=0;j<ns.getLength();j++){

             e=(Element)ns.item(j);
             Log.e("itemname", parser.getValue(e,KEY_ITEM_NAME).toString());
             Log.e("itemprice", parser.getValue(e, KEY_PRICE).toString()+"\n");
             map.put(KEY_ITEM_NAME, parser.getValue(e, KEY_ITEM_NAME));
             map.put(KEY_PRICE, parser.getValue(e, KEY_PRICE));

          }
     menuItems.add(map);

   }

【讨论】:

  • 我用来解析的类你用你的xmlParser类替换它
  • @divaNilisha 如果你得到输出而不是让我进入
  • 我在 logcat 中看到 05-18 11:05:47.351: E/catname(19510): ICECREAM 05-18 11:05:47.351: E/itemname(19510): SOFTY 05- 18 11:05:47.351:E/项目名称(19510):STICK 05-18 11:05:47.351:E/项目名称(19510):CONE 05-18 11:05:47.351:E/catname(19510):PIZZA 05 -18 11:05:47.351: E/itemname(19510): PIZZA-HOT 05-18 11:05:47.351: E/itemname(19510): PIZZA-CRISPY
  • 但不是价格。在我的 xml 中,奇怪的是我只看到了一份冰淇淋(锥形)和一份披萨(脆皮披萨)的价值
【解决方案2】:

试试这样的:

    NodeList nl_Cat = doc.getElementsByTagName(KEY_ITEM_CATEGORY);
    for (int i = 0; i < nl_Cat.getLength(); i++) 
    {
      HashMap<String, String> map = new HashMap<String, String>();
      Element cat = (Element) nl_Cat(i);
      NodeList nl = doc.getElementsByTagName(KEY_ITEM);
      for (int j = 0; j < nl.getLength(); j++) 
      {
        Element e = (Element) nl.item(j);
        map.put(KEY_ITEM_NAME, parser.getValue(e, KEY_ITEM_NAME));
        map.put(KEY_PRICE, parser.getValue(e, KEY_PRICE));
       }
      menuItems.add(map);
     }

希望这行得通!

【讨论】:

    【解决方案3】:

    您正在检索项目元素列表并尝试在项目元素中查找 category_name。但是,查看您的 xml,category_name 是 item 元素的兄弟,而不是子元素。所以你不会以这种方式获得类别名称。 您可能想要检索 item_category 的列表,然后从中填充项目。

    NodeList nl_categories = doc.getElementsByTagName(KEY_ITEM_CATEGORY);
    
    for(int i = 0; i < nl_categories; i++)
    {
        Element e = (Element) nl.item(i);
        String category = parser.getValue(e,KEY_CATEGORY);
    
        NodeList nl = e.getElementsByTagName(KEY_ITEM);
    
        // looping through all item nodes <item>
        for (int j = 0; j < nl.getLength(); j++) 
        {
            HashMap<String, String> map = new HashMap<String, String>();
            Element e = (Element) nl.item(j);
    
            map.put(KEY_CATEGORY, category);
            map.put(KEY_ITEM_NAME, parser.getValue(e, KEY_ITEM_NAME));
            map.put(KEY_PRICE, parser.getValue(e, KEY_PRICE));
    
            menuItems.add(map);
        }
    }
    

    【讨论】:

    • 我不想更改 xml 你能告诉我代码吗?
    • 您不需要为此更改 xml。只需稍微改变您检索项目的方式。先检索item_category的nodelist,检索category_name再检索该类别下的item。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 2013-10-19
    • 1970-01-01
    • 2021-12-17
    • 2019-06-28
    相关资源
    最近更新 更多