Android使用SAX实现XML解析,使用text/xml格式与后台交互

本文介绍了一种使用SAX解析XML文件的方法,并提供了详细的代码示例。包括自定义的实体类、解析器接口、解析器工具类以及功能实现界面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇博文正式发表于2015-02-16 14:20,现在显示的创建时间2015-02-05 10:07是当初写草稿的时间

一、SAX解析XML

1,首先展示一下要写入以及解析的xml的文件格式:

<?xml version="1.0" encoding="utf-8"?>
<dragon>
<header> 
<code>200</code>    
<time>20180123</time> 
</header>     
<body>
<luffy>            
<id>001</id>            
<name>蒙奇·D·路飞</name>            
<price>8亿</price>            
<dream>海贼王,我当定了</dream>            
<ability>三色霸气及橡胶果实能力者</ability>      
</luffy>
</body>
</dragon>


2,然后是两个简单的实体类:

DragonItem(父类):

import java.util.List;

/**
 * @date: 2015年2月15日 下午4:27:58
 * 
 * @email: 309997751@qq.com
 * 
 * @version: V1.0
 * 
 * @description: dragon,包含了luffy实体类
 * 
 * @author: diyangxia
 * 
 */
public class DragonItem {

	int code;
	String time;
	List<LuffyItem> list;

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String msg) {
		this.time = msg;
	}

	public List<LuffyItem> getLuffy() {
		return list;
	}

	public void setLuffy(List<LuffyItem> list) {
		this.list = list;
	}

}
 LuffyItem(子类):

/**
 * @date: 2015年2月15日 下午4:27:58
 * 
 * @email: 309997751@qq.com
 * 
 * @version: V1.0
 * 
 * @description: 路飞领导的草帽团
 * 
 * @author: diyangxia
 * 
 */
public class LuffyItem {

	private int id; // 编号
	private String name;// 姓名
	private String price;// 赏金
	private String dream;// 梦想
	private String ability;// 能力

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPrice() {
		return price;
	}

	public void setPrice(String price) {
		this.price = price;
	}

	public String getDream() {
		return dream;
	}

	public void setDream(String dream) {
		this.dream = dream;
	}

	public String getAbility() {
		return ability;
	}

	public void setAbility(String ability) {
		this.ability = ability;
	}

}
3,解析器接口,一个用来解析读取xml,一个用来把序列化后的xml字符串写入到文件

import java.io.InputStream;
import java.util.List;

/**
 * @date: 2015年2月15日 下午1:32:42
 * 
 * @email: 309997751@qq.com
 * 
 * @version: V1.0
 * 
 * @description: 蒙奇家族解析器接口
 * 
 * @author: diyangxia
 * 
 */
public interface MonkeyInterface {

	/**
	 * 解析从本地文件获取的输入流得到list
	 * @param is 输入流
	 * @return List<DragonItem>
	 * @throws Exception
	 */
	public List<DragonItem> parse(InputStream is) throws Exception;

	/**
	 * 把list序列化成xml格式的字符串
	 * @param luffys list
	 * @return xml格式字符串
	 * @throws Exception
	 */
	public String serialize(List<LuffyItem> luffys) throws Exception;

}

4,MonkeySaxTool 解析器工具类,实现解析器接口,这个类很重要,很关键

/**
 * @date: 2015年2月15日 下午1:36:20
 * 
 * @email: 309997751@qq.com 
 * 
 * @version: V1.0
 * 
 * @description: sax解析工具类,实现解析器接口
 * 
 * @author: diyangxia
 *
 */

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MonkeySaxTool implements MonkeyInterface {

	@Override
	public List<DragonItem> parse(InputStream is) throws Exception {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		SAXParser parser = factory.newSAXParser();
		MyHandler handler = new MyHandler();
		parser.parse(is, handler); // 根据自定义Handler规则解析输入流
		MonkeyDFamily.luffyList.clear();
		MonkeyDFamily.luffyList = handler.getLuffyList();
		return handler.getDragonList();
	}

	@Override
	public String serialize(List<LuffyItem> luffyList) throws Exception {
		SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory
				.newInstance();
		TransformerHandler handler = factory.newTransformerHandler();
		Transformer transformer = handler.getTransformer(); // 从handler获取Transformer实例
		transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明

		StringWriter writer = new StringWriter();
		Result result = new StreamResult(writer);
		handler.setResult(result);

		String uri = ""; // 代表命名空间的URI 当URI无值时 须置为空字符串
		String localName = ""; // 命名空间的本地名称(不包含前缀) 当没有进行命名空间处理时 须置为空字符串

		handler.startDocument();

		handler.startElement(uri, localName, "dragon", null);
		handler.startElement(uri, localName, "header", null);
		char[] ch1 = null;
		handler.startElement(uri, localName, "code", null);
		ch1 = String.valueOf(200).toCharArray();
		handler.characters(ch1, 0, ch1.length);
		handler.endElement(uri, localName, "code");

		handler.startElement(uri, localName, "time", null);
		ch1 = String.valueOf("20250519").toCharArray();
		handler.characters(ch1, 0, ch1.length);
		handler.endElement(uri, localName, "time");
		handler.endElement(uri, localName, "header");

		handler.startElement(uri, localName, "body", null);
		handler.startElement(uri, localName, "luffy", null);

		char[] ch = null;
		for (LuffyItem luffy : luffyList) {

			handler.startElement(uri, localName, "id", null);
			ch = String.valueOf(luffy.getId()).toCharArray();
			handler.characters(ch, 0, ch.length);
			handler.endElement(uri, localName, "id");

			handler.startElement(uri, localName, "name", null);
			ch = String.valueOf(luffy.getName()).toCharArray();
			handler.characters(ch, 0, ch.length);
			handler.endElement(uri, localName, "name");

			handler.startElement(uri, localName, "price", null);
			ch = String.valueOf(luffy.getPrice()).toCharArray();
			handler.characters(ch, 0, ch.length);
			handler.endElement(uri, localName, "price");

			handler.startElement(uri, localName, "dream", null);
			ch = String.valueOf(luffy.getDream()).toCharArray();
			handler.characters(ch, 0, ch.length);
			handler.endElement(uri, localName, "dream");

			handler.startElement(uri, localName, "ability", null);
			ch = String.valueOf(luffy.getAbility()).toCharArray();
			handler.characters(ch, 0, ch.length);
			handler.endElement(uri, localName, "ability");

		}
		handler.endElement(uri, localName, "luffy");
		handler.endElement(uri, localName, "body");
		handler.endElement(uri, localName, "dragon");
		handler.endDocument();

		return writer.toString();
	}

	// 需要重写DefaultHandler的方法
	private class MyHandler extends DefaultHandler {

		private List<DragonItem> dragonList;
		private DragonItem dragon;
		private StringBuilder builder;
		private List<LuffyItem> luffyList;
		private LuffyItem luffy;

		// 返回解析后得到的dragons对象集合
		public List<DragonItem> getDragonList() {
			return dragonList;
		}

		// 返回解析后得到的luffys对象集合
		public List<LuffyItem> getLuffyList() {
			return luffyList;
		}

		@Override
		public void startDocument() throws SAXException {
			super.startDocument();
			dragonList = new ArrayList<DragonItem>();
			luffyList = new ArrayList<LuffyItem>();
			builder = new StringBuilder();
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			super.startElement(uri, localName, qName, attributes);
			if (localName.equals("dragon")) {
				dragon = new DragonItem();
			}
			if (localName.equals("luffy")) {
				luffy = new LuffyItem();
			}
			builder.setLength(0); // 将字符长度设置为0 以便重新开始读取元素内的字符节点
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException {
			super.characters(ch, start, length);
			builder.append(ch, start, length); // 将读取的字符数组追加到builder中
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			super.endElement(uri, localName, qName);
			if (localName.equals("code")) {
				dragon.setCode(Integer.parseInt((builder.toString())));
			} else if (localName.equals("time")) {
				dragon.setTime(builder.toString());
			} else if (localName.equals("dragon")) {
				dragonList.add(dragon);
			} else if (localName.equals("ability")) {
				luffy.setAbility(builder.toString());
			} else if (localName.equals("id")) {
				luffy.setId(Integer.parseInt((builder.toString())));
			} else if (localName.equals("dream")) {
				luffy.setDream(builder.toString());
			} else if (localName.equals("name")) {
				luffy.setName(builder.toString());
			} else if (localName.equals("price")) {
				luffy.setPrice(builder.toString());
			} else if (localName.equals("luffy")) {
				luffyList.add(luffy);
			}
		}

		@Override
		public void endDocument() throws SAXException {
			// TODO Auto-generated method stub
			super.endDocument();
		}
	}

}
5,功能实现的界面

/**
 * @date: 2015年2月16日 上午11:54:45
 * 
 * @email: 309997751@qq.com
 * 
 * @version: V1.0
 * 
 * @description: xml解析功能实现界面
 * 
 * @author: diyangxia
 *
 */
public class MonkeyDFamily extends Activity {

	private EditText idET;
	private EditText nameET;
	private EditText priceET;
	private EditText dreamET;
	private EditText abilityET;
	private Button saxWBtn;
	private Button saxRBtn;
	private TextView mTextView;// 展示结果类
	private MonkeySaxTool parser = null;
	private List<LuffyItem> luffys = new ArrayList<LuffyItem>();
	private String rootPath = Environment.getExternalStorageDirectory()
			.getAbsolutePath() + File.separator;

	/**
	 * 本地xml字符串,可以保存到xml文件再解析读取
	 */
	private String sampleReturn = "<?xml version=\"1.0\" encoding=\"utf-8\"?><dragon>    <header> <code>200</code>    <time>20180123</time> </header>     <body><luffy>            <id>001</id>            <name>蒙奇·D·路飞</name>            <price>8亿</price>            <dream>海贼王,我当定了</dream>            <ability>霸王色霸气</ability>      </luffy></body></dragon>";

	public static List<LuffyItem> luffyList = new ArrayList<LuffyItem>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_monkeydfamily);

		saxWBtn = (Button) findViewById(R.id.button1);
		saxRBtn = (Button) findViewById(R.id.button2);
		idET = (EditText) findViewById(R.id.monkey_d_id);
		abilityET = (EditText) findViewById(R.id.monkey_d_ability);
		dreamET = (EditText) findViewById(R.id.monkey_d_dream);
		priceET = (EditText) findViewById(R.id.monkey_d_price);
		nameET = (EditText) findViewById(R.id.monkey_d_name);
		mTextView = (TextView) findViewById(R.id.textView1);

		saxWBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				generateXMLData();
				writeXML();
			}
		});

		saxRBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
//				saveStringToFile("diyangxiaR.xml", sampleReturn);
				readXML();
			}
		});

	}

	private void generateXMLData() {
		// TODO Auto-generated method stub
		luffys.clear();
		LuffyItem luffy = new LuffyItem();
		luffy.setId(Integer.parseInt(idET.getText().toString().trim()));
		luffy.setName(nameET.getText().toString().trim());
		luffy.setPrice(priceET.getText().toString().trim());
		luffy.setDream(dreamET.getText().toString().trim());
		luffy.setAbility(abilityET.getText().toString().trim());
		luffys.add(luffy);
	}

	private String writeXML() {
		// TODO Auto-generated method stub
		try {
			File cacheFile = new File(rootPath + "diyangxiaW.xml");// 设置参数
			if (cacheFile.exists()) {
				cacheFile.delete();
			}
			cacheFile.createNewFile();// 生成文件

			parser = new MonkeySaxTool(); // 创建SaxBookParser实例
			String xml = parser.serialize(luffys); // 序列化
			@SuppressWarnings("resource")
			FileOutputStream fos = new FileOutputStream(cacheFile);
			fos.write(xml.getBytes("UTF-8"));
			Toast.makeText(MonkeyDFamily.this, "生成xml文件成功,可至SD卡根目录查看", Toast.LENGTH_SHORT).show();
			mTextView.setText(xml);
			Log.i("TAG", "发送给后台" + xml);
			return xml;
		} catch (Exception e) {
			Log.i("TAG", "Exception-" + e.toString());
		}
		return null;
	}

	private void readXML() {
		// TODO Auto-generated method stub
		try {
			parser = new MonkeySaxTool(); // 创建SaxBookParser实例
//			InputStream in = new FileInputStream(new File(rootPath
//					+ "diyangxiaR.xml"));
			InputStream in = new FileInputStream(new File(rootPath
					+ "diyangxiaW.xml"));
			List<DragonItem> dragons = parser.parse(in); // 解析输入流
			for (DragonItem dragon : dragons) {
				Log.i("TAG", "Code--" + dragon.getCode());
				Log.i("TAG", "Time--" + dragon.getTime());
			}
			mTextView.setText("id==" + luffyList.get(0).getId() + "\nname=="
					+ luffyList.get(0).getName() + "\nprice=="
					+ luffyList.get(0).getPrice() + "\ndream=="
					+ luffyList.get(0).getDream() + "\nability=="
					+ luffyList.get(0).getAbility());
		} catch (Exception e) {
			Log.i("TAG", "Exception--" + e.toString());
		}

	}

	/**
	 * 根据content生成fileName文件
	 * @param fileName 文件名
	 * @param content 要写入文件的内容
	 */
	public void saveStringToFile(String fileName, String content) {
		try {

			File root = new File(rootPath);
			if (!root.exists()) {
				root.mkdirs();
			}
			File f = new File(rootPath + fileName);
			if (f.exists()) {
				f.delete();
			}
			f.createNewFile();
			FileOutputStream out = new FileOutputStream(f);
			out.write(content.getBytes());
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
6,写入到本地xml文件效果图如下:

7,解析读取本地xml文件效果图如下:



二、使用XML数据与服务器交互

new Thread(new Runnable() {

					@Override
					public void run() {

						result = postXMLHttpString(MonkeyDFamily.this,
								"后台接收xml的接口地址", rootPath
										+ "diyangxiaW.xml");
						Log.i("TAG", "result==>" + result);
						if (result.contains("success")) {
							try {
								JSONObject object = new JSONObject(result);
								boolean success = object.getBoolean("success");
								if (!success) {
									mHandler.sendEmptyMessage(XML_POST_FAILURE);
								}
							} catch (JSONException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						} else {
							mHandler.sendEmptyMessage(XML_POST_SUCCESS);
						}
					}
				}).start();
提交post请求方法,传递xml文件,获取输入流转化
public String postXMLHttpString(Context context, String urlStr,String fileName) {
		String result = null;
		try {
			URL url = new URL(urlStr);
			HttpURLConnection urlConn = (HttpURLConnection) url
					.openConnection();
			InputStream is = new FileInputStream(new File(fileName));
			urlConn.setDoOutput(true);
			urlConn.setRequestMethod("POST");
			urlConn.setConnectTimeout(5000);
			urlConn.setRequestProperty("Content-type", "text/xml charset=UTF-8");
			urlConn.connect();

			OutputStream os = urlConn.getOutputStream();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = is.read(buffer)) != -1) {
				baos.write(buffer, 0, len);
			}
			byte[] data = baos.toByteArray();
			os.write(data);
			is.close();
			os.flush();
			os.close();
			if (urlConn.getResponseCode() == 200) {
				result = new String(readInputStream(urlConn.getInputStream()),
						"UTF-8");// 响应xml数据
				result = URLDecoder.decode(result, "UTF-8");

			}

		} catch (Exception e) {
			e.printStackTrace();
			JSONObject obj = new JSONObject();
			try {
				obj.put("success", "false");
				obj.put("reason", "无法连接到服务器");
			} catch (JSONException e1) {
				e1.printStackTrace();
			}
			return obj.toString();
		}

		return result;
	}

	public byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		inStream.close();
		return outStream.toByteArray();
	}


使用dom4j解析xml的问题

SAXReader reader = new SAXReader();//得到解析器对象
        //通过解析器对象得到文档对象
        Document document = reader.read(new File("xml/book.xml"));
        //得到根节点(此处的根节点是“书架”)
        Element root = document.getRootElement();
        //得到子节点“书”的子节点“书名”
        Element bookname = root.element("书").element("书名");
        //得到节点的值或文本
        System.out.println(bookname.getText());

作者:yjaal
链接:https://www.jianshu.com/p/e8561ea99d03

最后,提供一个简单的DEMO下载


声明:借鉴了这篇博文,传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值