我正在尝试通过JAVA解析xml,但在解析后我得到org.apache.harmony.xml.dom.DocumentImpl@418b4c98
。
以下是我要解析的XML,例如,我需要id
数据为5
而default_image
为https://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);
}
}
答案 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)
);