这篇博文正式发表于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下载
声明:借鉴了这篇博文,传送门