通过JAVA解析xml的麻烦

时间:2013-12-10 07:24:12

标签: java android xml parsing

我正在尝试通过JAVA解析xml,但在解析后我得到org.apache.harmony.xml.dom.DocumentImpl@418b4c98

以下是我要解析的XML,例如,我需要id数据为5default_imagehttps://www.10ngah.com/api/images/products/5/5

XML

<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<products>
<product>
<id>
<![CDATA[ 5 ]]>
</id>
<id_default_image xlink:href="https://www.10ngah.com/api/images/products/5/5"not_filterable="true">
<![CDATA[ 5 ]]>
</id_default_image>
<price>
<![CDATA[ 525 ]]>
</price>
<name>
<language id="1" xlink:href="https://www.10ngah.com/api/languages/1">
<![CDATA[ iPad 2 GB with Cellular ]]>
</language>
</name>
</product>
<product>
<id>
<![CDATA[ 6 ]]>
 </id>
<id_default_image xlink:href="https://www.10ngah.com/api/images/products/6/6" not_filterable="true">
<![CDATA[ 6 ]]>
</id_default_image>
<price>
<![CDATA[ 525 ]]>
</price>
<name>
<language id="1" xlink:href="https://www.10ngah.com/api/languages/1">
<![CDATA[ iPad 2 GB with Cellular ]]>
</language>
</name>
</product>
</products>
</prestashop>

解析代码

package com.prestoshop.xmlparser;

import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import android.app.Activity;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.BaseAdapter;
import android.widget.Toast;
import com.prestoshop.beans.ProductItems;
import com.prestoshop.utils.Utils;

public class ProductLoaderTask extends AsyncTask<Void, ProductItems, Void> {

private Activity mContext;
private List<ProductItems> products;
private BaseAdapter adapter;

public ProductLoaderTask(Activity context, List<ProductItems> productList,
        BaseAdapter adapter) {
    mContext = context;
    products = productList;
    this.adapter = adapter;
}

static final String KEY_PRESTASHOP = "prestashop";
static final String KEY_ALL_PRODUCTS = "products";

@Override
protected Void doInBackground(Void... params) {

    String url = Utils.PRODUCTS_URL;// use varargs just like an array
    Log.e("urlll", "" + url);
    XMLParser parser = new XMLParser();
    String xml = parser.getXmlFromUrl(url);
    Log.e("string xml", "" + xml);
    Document doc = parser.getDomElement(xml, mContext);


    NodeList nl = doc.getElementsByTagName("product");
            Log.e("noddd",""+nl);
    for (int i = 0; i < nl.getLength(); i++) {
        Element e = (Element) nl.item(i);
        Log.e("eeee", "" + e.toString());
        Log.e("nodelist", ""
                + parser.getValue(e, "price").toString());

        publishProgress(new ProductItems(
                parser.getValue(e, "name"),
                parser.getValue(e, "id"), parser.getValue(e,
                        "id_default_image"), 12.050000));

    }

    return null;
}

@Override
protected void onProgressUpdate(ProductItems... values) {

    ProductItems product = values[0];
    products.add(product);
    adapter.notifyDataSetChanged();
}

@Override
protected void onPostExecute(Void result) {
    Log.e("All done", products.toString());
    super.onPostExecute(result);
 }
}

4 个答案:

答案 0 :(得分:1)

首先,您的示例有语法错误(属性前缺少空格)...

我非常喜欢JAXB ......所以我会向你推荐它。如果您的数据具有静态格式(不及时更改格式),那么这是最好的方法。 CDATA块只有“问题”,有关详细信息,请参阅this post。 这是“快速”的例子......这不是一个很好的代码只是一个例子!



    public class AdapterCDATA extends XmlAdapter {


      @Override
      public String marshal(String arg0) throws Exception {
        return "";
      }

      @Override
      public String unmarshal(String arg0) throws Exception {
        return arg0;
      }
    }



    public class TestData {

      @XmlRootElement(name = "prestashop")
      @XmlAccessorType(XmlAccessType.FIELD)
      static class Prestashop {

        @XmlElementWrapper(name = "products")
        @XmlElement(name = "product")
        List products;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class Product {
        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlElement(name = "id")
        String id;

        @XmlElement(name = "id_default_image")
        IdDefaultImage idDefaultImage;

        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlElement(name = "price")
        String price;

        @XmlElement(name = "name")
        Name name;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class IdDefaultImage {
        @XmlAttribute(name = "not_filterable")
        String notFilterable;

        @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
        String href;

        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlValue
        String idDefaultImage;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class Name {
        @XmlElement(name = "language")
        Language language;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class Language {
        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlValue
        String language;

        @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
        String href;

        @XmlAttribute(name = "id")
        String id;
      }

      public static void main(String[] args) throws JAXBException {
        JAXBContext jc = JAXBContext.newInstance(Prestashop.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/test/resources/testData.xml");
        Prestashop prestashop = (Prestashop) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(prestashop, System.out);
      }
    }

答案 1 :(得分:1)

在文档http://developer.android.com/training/basics/network-ops/xml.html

之后使用XmlPullParser

将xml复制到assests文件夹到本地解析器(仅用于测试)。您可以从URL获取xml并解析。

 InputStream is = MainActivity.this.getResources()
                     .getAssets().open("xmlparser.xml");
               new parserPull(is);

然后解析

public class parserPull
{

    private static final String ns = null;
    public parserPull(InputStream open) {
        try
        {
             XmlPullParser parser = Xml.newPullParser();
             parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
             parser.setInput(open, null);
             parser.nextTag();
             List<Entry> all = readFeed(parser);
             for(int i=0;i<all.size();i++)
             {
             Log.i("ID is..........",all.get(i).id);
             Log.i("Link is........",all.get(i).link);
             Log.i("Price is.......",all.get(i).price);
             }
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
         List<Entry> entry = null;
        parser.require(XmlPullParser.START_TAG, ns, "prestashop");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
            //Log.i("..................",name);
            // Starts by looking for the prestashop tag
            if (name.equals("products")) {
              entry= readProducts(parser);
            } else {
                skip(parser);
            }
        }  
        return entry;
    }
    private List<Entry> readProducts(XmlPullParser parser) throws XmlPullParserException, IOException {
        List<Entry> entries = new ArrayList<Entry>();

        parser.require(XmlPullParser.START_TAG, ns, "products");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
           // Log.i("..................",name);
            // Starts by looking for the products tag
            if (name.equals("product")) {
                entries.add(readEntry(parser));
            } else {
                skip(parser);
            }
        }  
        return entries;
    }
    private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
        parser.require(XmlPullParser.START_TAG, ns, "product");
        String title = null;
        String summary = null;
        String link = null;
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
           // Log.i("...................",name);
            if (name.equals("id")) {
                title = readId(parser);
            } else if (name.equals("id_default_image")) {
                summary = readLink(parser);
            } else if (name.equals("price")) {
                link = readPrice(parser);
            } else {
                skip(parser);
            }
        }
        return new Entry(title, summary, link);
    }
    private String readPrice(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "price");
        String summary = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "price");
        return summary;
    }
    private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {
        String link = "";
        parser.require(XmlPullParser.START_TAG, ns, "id_default_image");
        String tag = parser.getName();
       // Log.i("............",tag);
        String relType = parser.getAttributeValue(null, "not_filterable");  
        if (tag.equals("id_default_image")) {
            if (relType.equals("true")){
                link = parser.getAttributeValue(null, "xlink:href");
                parser.nextTag();
            } 
        }
        parser.require(XmlPullParser.END_TAG, ns, "id_default_image");
        return link;
    }
    private String readId(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "id");
        String title = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "id");
        return title;
    }
    private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }
    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            throw new IllegalStateException();
        }
        int depth = 1;
        while (depth != 0) {
            switch (parser.next()) {
            case XmlPullParser.END_TAG:
                depth--;
                break;
            case XmlPullParser.START_TAG:
                depth++;
                break;
            }
        }
     }
    public static class Entry {
        public final String id;
        public final String link;
        public final String price;

        private Entry(String id, String link, String price) {
            this.id = id;
            this.link = link;
            this.price = price;
        }
    }
} 

日志输出

12-10 03:29:44.664: I/ID is..........(1511):  5 
12-10 03:29:44.664: I/Link is........(1511): https://www.10ngah.com/api/images/products/5/5
12-10 03:29:44.674: I/Price is.......(1511):  525 
12-10 03:29:44.674: I/ID is..........(1511):  6 
12-10 03:29:44.674: I/Link is........(1511): https://www.10ngah.com/api/images/products/6/6
12-10 03:29:44.674: I/Price is.......(1511):  525 

答案 2 :(得分:0)

示例XML:

<a>
<b category='3' number='25' points='2'>
<c>
<d filename='' content='some content'/>
<d filename='0134.jpg'/>
</c>
<e>
<f description='desc' correct='1'/>
</e>
</a>

分享代码
解析类以便以后修改的字段更容易:

//data to parse
private static final String TAG_A = "a";        //root

private static final String TAG_B = "b";
private static final String ATT_CATEGORY = "category";
private static final String ATT_POINTS = "points";

private static final String TAG_D = "d";
private static final String ATT_FILE_NAME = "filename";
private static final String ATT_CONTENT = "content";

private static final String TAG_F = "f";
private static final String ATT_DESCRIPTION = "description";
private static final String ATT_CORRECT = "correct";

解析类的方法:

    private void parseXml()
    {
        try
        {
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(questionsXmlFile, null);
            parser.nextTag();
            parser.require(XmlPullParser.START_TAG, null, TAG_A);
            while (parser.next() != XmlPullParser.END_DOCUMENT)
            {
                if (parser.getEventType() == XmlPullParser.START_TAG)
                {
                    String name = parser.getName();
                    if (name.equalsIgnoreCase(TAG_B))
                    {
                        parser.getAttributeValue(null, ATT_CATEGORY));
                        parser.getAttributeValue(null, ATT_POINTS));
                    }
                    else if (name.equalsIgnoreCase(TAG_D))
                    {
                        parser.getAttributeValue(null, ATT_CONTENT));
                        parser.getAttributeValue(null, ATT_FILE_NAME));
                    }
                    else if (name.equalsIgnoreCase(TAG_ANSWER))
                    {
                    }
                }
            }
        }
        catch (XmlPullParserException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

这种方法有什么作用? 它从xml开始遍历END_DOCUMENT并检查标签是否有趣。如果是,请检查所需的属性并对其不执行任何操作(添加您自己的操作 请记住,getAttributeValue()可以返回null。请确保您不在null上操作 请记住,parser.require(XmlPullParser.START_TAG, null, TAG_A)如果传递给它的变量与解析器的当前情况相比是错误的,则会返回异常。

答案 3 :(得分:0)

您的代码看起来还可以,只需删除&lt;![CDATA [....]]&gt;

&lt; id&gt;&lt;![CDATA [526]]&gt;&lt; / id&gt; 更改为&lt; id&gt; 526&lt; / id&gt;

或者如果您不想删除它,请按照以下方式执行,

添加以下方法/功能:

public String getCDataValue(Element e, String id) {
        NodeList title = e.getElementsByTagName(id);
        Element ex = (Element) title.item(0);
        Node child = ex.getFirstChild();
        if (child instanceof CharacterData) {
            CharacterData cd = (CharacterData) child;
            return cd.getData().trim();
        }
        return "";
}

然后以这种方式使用它:

NodeList nl = doc.getElementsByTagName("product");
       for (int i = 0; i < nl.getLength(); i++) {
        Element e = (Element) nl.item(i);
        Toast.makeText(getApplicationContext(), getCDataValue(e, "price"),
        Toast.LENGTH_SHORT).show();
}

如果是您的代码:

publishProgress(new ProductItems(
                      getCDataValue(e, "name"),
                      getCDataValue(e, "id"),
                      getCDataValue(e, "id_default_image"),
                      12.050000)
);