【问题标题】:Trouble with xml parsing through JAVA通过JAVA解析xml的问题
【发布时间】:2013-12-10 07:24:11
【问题描述】:

我正在尝试通过 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);
 }
}

【问题讨论】:

  • 嗯,听起来您在文档上调用toString(),而且看起来它还没有被覆盖。很遗憾,我们看不到您的代码,也不知道您要实现什么目标,因此很难为您提供帮助。
  • 你在使用哪个解析器XmlPullParser ?developer.android.com/training/basics/network-ops/xml.html
  • 我在上面添加了我的java代码,我正在使用dom解析器。请帮帮我
  • @ashutiwari4 查看选择解析器下的文档,引用“推荐 XmlPullParser,这是在 Android 上解析 XML 的一种高效且可维护的方式”。还有一个例子可以在文档中解析 stackoverflow 的 rss fedd
  • @Raghunandan 我已经经历过了,解析后,日志中没有打印任何内容

标签: java android xml parsing


【解决方案1】:

使用XmlPullParser 遵循文档http://developer.android.com/training/basics/network-ops/xml.html

将 xml 复制到本地解析器的评估文件夹(仅用于测试)。您可以从 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】:

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

    我非常喜欢 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);
          }
        }
    
    

    【讨论】:

      【解决方案3】:

      示例 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) 如果传递给它的变量与解析器的当前情况相比是错误的,则会返回异常。

      【讨论】:

        【解决方案4】:

        您的代码看起来一切正常,只有您需要删除

        更改为 526

        或者如果你不想删除它,那么按照以下方式进行,

        添加以下方法/功能:

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

        【讨论】:

          猜你喜欢
          • 2012-03-14
          • 1970-01-01
          • 2012-03-23
          • 1970-01-01
          • 2013-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-27
          相关资源
          最近更新 更多