大家知道Android开发使用的是Java语言而对于XML解析熟悉JavaSE的朋友一定不陌生。对于Android来说,XML的解析主要有三种方式:DOM、SAX、Android自带的PULL下面逐一写一个Demo来分析。
首先是最为熟悉的DOM:
首先通过Document构件一个XML文档,通过Environment.getExternalStorageDirectory()即可得到SD卡的信息。这样在通过TransformerFactory即可实现xml保存包SD卡的效果。其实Android中DOM解析就是用的java 所以其原理也一样可以参考Java的四种XML解析方式。具体Demo:
public class MainActivity extends Activity implements OnClickListener {
private Button createDOM, parseDOM;
private TextView showView;
private DocumentBuilderFactory factory;
private DocumentBuilder builder;
private Document doc;
private File sdCardDir;
private File bookXml;
private static final String FILE_NAME = "book.xml";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initial();
factory = DocumentBuilderFactory.newInstance();
try {
builder = factory.newDocumentBuilder();
sdCardDir = Environment.getExternalStorageDirectory();
bookXml = new File(sdCardDir.getCanonicalPath() + File.separator
+ FILE_NAME);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void initial() {
createDOM = (Button) findViewById(R.id.createDOM);
parseDOM = (Button) findViewById(R.id.parseDOM);
createDOM.setOnClickListener(this);
parseDOM.setOnClickListener(this);
showView = (TextView) findViewById(R.id.show);
}
public void onClick(View view) {
if (R.id.createDOM == view.getId()) {
try {
createDom();
} catch (Exception e) {
Log.e("debug", "chucuol ");
e.printStackTrace();
}
} else if (view.getId() == R.id.parseDOM) {
try {
parseDom();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 创建xml
*/
private void createDom() throws SAXException, IOException,
TransformerException {
doc = builder.newDocument();
Element rootElement = (Element) doc.createElement("books");
doc.appendChild(rootElement);
Element bookElement = (Element) doc.createElement("book");
// bookElement.setAttribute("id", "001");
rootElement.appendChild(bookElement);
Element publishElement = doc.createElement("publisher");
publishElement.appendChild(doc.createTextNode("华章图书"));
bookElement.appendChild(publishElement);
Element authorElement = doc.createElement("author");
authorElement.appendChild(doc.createTextNode("author"));
bookElement.appendChild(authorElement);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
/** 编码 */
// transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
DOMSource source = new DOMSource(doc);
OutputStream output = new ByteArrayOutputStream();
StreamResult r = new StreamResult(output);
transformer.transform(source, r);
String xmlString = output.toString();
showView.setText(xmlString);
StreamResult result = new StreamResult(bookXml);
transformer.transform(source, result);
}
/**
* 解析xml
*
* @throws IOException
* @throws SAXException
*/
private void parseDom() throws SAXException, IOException {
doc = builder.parse(bookXml);
Element rootElement = doc.getDocumentElement();
NodeList items = rootElement.getElementsByTagName("book");
for (int i = 0; i < items.getLength(); i++) {
Node book = items.item(i);
String publish = doc.getElementsByTagName("publisher").item(i)
.getFirstChild().getNodeValue();
String author = doc.getElementsByTagName("author").item(i)
.getFirstChild().getNodeValue();
Log.e("debug", publish + "===" + author);
}
}
}
最后最终要的因为使用到SD卡不要忘记申请权限:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Pull是Android系统提供的一种XML解析方式与SAX一样其也是基于事件的方式进行解析的其也提供了类似SAX的事件(开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等),但需要调用next() 方法提取它们(主动提取事件)不同的是:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。
Android中的xml布局文件或配置文件也都是采取PUll的方式进行解析的。
写一个Demo:
public class MainActivity extends Activity implements OnClickListener{
private Button createPull,parsePull;
private TextView showView;
private XmlPullParser pullParser;
private XmlSerializer serializer;
private File sdCardDir ;
private File bookFile;
private List<Book> bookList;
private Book book;
private static final String FILE_NAME="book.xml";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initView();
}
private void init(){
pullParser = Xml.newPullParser();
sdCardDir = Environment.getExternalStorageDirectory();
bookFile =new File(sdCardDir+File.separator+FILE_NAME);
serializer = Xml.newSerializer();
}
private void initView(){
createPull = (Button)findViewById(R.id.createPULL);
parsePull = (Button)findViewById(R.id.parsePULL);
showView = (TextView)findViewById(R.id.show);
createPull.setOnClickListener(this);
parsePull.setOnClickListener(this);
}
public void onClick(View view){
if(R.id.createPULL == view.getId()){
try {
Log.e("debug", "创建XML");
createPull();
Log.e("debug", "OKKK");
} catch (Exception e) {
// TODO: handle exception
}
}else if (R.id.parsePULL == view.getId()) {
try {
parsePull();
} catch (Exception e) {
// TODO: handle exception
}
}
}
private void parsePull()throws Exception{
InputStream fis = new FileInputStream(bookFile);
pullParser.setInput(fis, "utf-8");
int event =pullParser.getEventType();
while(event!=XmlPullParser.END_DOCUMENT){
switch (event) {
case XmlPullParser.START_DOCUMENT:
bookList = new ArrayList<Book>();
break;
case XmlPullParser.START_TAG:
if("book".equals(pullParser.getName())){
book = new Book();
book.setID(pullParser.getAttributeValue(0));
}
if("name".equals(pullParser.getName())){
book.setName(pullParser.nextText());
}
if("author".equals(pullParser.getName())){
book.setAuthor(pullParser.nextText());
}
break;
case XmlPullParser.END_TAG:
if("book".equals(pullParser.getName())){
bookList.add(book);
book= null;
}
break;
default:
break;
}
event = pullParser.next();
}
for (Book book : bookList) {
Log.e("debug", book.toString());
}
}
private void createPull()throws Exception{
OutputStream fos = new FileOutputStream(bookFile);
Log.e("ee", "eee");
serializer.setOutput(fos, "utf-8");
serializer.startDocument("utf-8", true);
serializer.startTag(null, "books");
serializer.startTag(null, "book");
serializer.attribute(null, "ID", "001");
serializer.startTag(null, "name");
serializer.text("Java编程思想");
serializer.endTag(null, "name");
serializer.startTag(null, "author");
serializer.text("埃史尔");
serializer.endTag(null, "author");
serializer.endTag(null, "book");
serializer.startTag(null, "book");
serializer.attribute(null, "ID", "002");
serializer.startTag(null, "name");
serializer.text("Java核心技术");
serializer.endTag(null, "name");
serializer.startTag(null, "author");
serializer.text("霍斯特曼");
serializer.endTag(null, "author");
serializer.endTag(null, "book");
serializer.endTag(null, "books");
serializer.endDocument();
fos.close();
}
}
当然同样是要申请权限的
第三SAX的方式操作XML,SAX是基于事件的方式的,这个比较难理解先写一个Demo
public class SAXParseXMLService {
public void getBooks(InputStream fis) throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
BookParserHandle bookHandle = new BookParserHandle();
parser.parse(fis, bookHandle);
List<Book> bookList = bookHandle.parseBooks();
for (Book book : bookList) {
Log.e("ee", book.toString());
}
}
public class BookParserHandle extends DefaultHandler{
private List<Book> bookList;
private String preTag;
private Book book;
public List<Book> parseBooks(){
return bookList;
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
bookList = new ArrayList<Book>();
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
if(preTag!=null){
String data = new String(ch,start,length);
if("name".equals(preTag)){
book.setName(data);
}
if("author".equals(preTag)){
book.setAuthor(data);
}
}
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
if("book".equals(localName)){
book = new Book();
book.setID(attributes.getValue(0));
}
preTag = localName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if("book".equals(localName)){
bookList.add(book);
book = null;
}
preTag = null;
}
}
}
各位兄台欢迎提宝贵意见呀。诚心希望祥大家学习。