xml知识补充:
在xml文件中,<?xml version= ....?> 称为 start document ,即xml起始位置,最末尾为 end document ,即为xml结束,每一个<>都是一个节点,称之为tag, <person>为starttag,而</person>为endtag 每个节点都可以有属性,<person id="1">,则id为attribute name,而1 为attribute value 节点也可以包含内容, <name>Tom</name>, Tom就是内容,即text
pull解析:就是对xml文件的逐行扫描,pull解析器会将文件内容拆分为char[],逐字符读取,在调用其方法时,以每个节点为一次完整的读取来确定如恶化完成具体的解析工作
PULL一共有5种事件类型:
* START_DOCUMENT:文档的开始,解析器尚未读取任何输入。
* START_TAG:开始标签的解析。
* TEXT:标签内元素的内容解析。
* END_TAG:结束标签的解析。
* END_DOCUMENT:文档的结束。
主要用的是4个,他们与XML文件相应内容是这么对应的(他们在XML文件中的位置是这样)
简单总结就是:
文档的开头和结束分别有文档开始和文档结束事件文档中的每个节点,无论是根节点还是叶子节点,都在节点开始和节点结束的地方有事件
具体使用的建议:
文档开始和文档结束事件是有固定位置的,你只要在这个位置做你要做的事情就好了,比如初始化一些资源节点开始和节点结束的事件在很多位置都可能发生,为了精确控制,你可以使用【获取他们的节点名称(name)进行判断】这一方法
代码:
data.xml,在assets目录下
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<objects>
<students>
<student id="2222" type="23">
<name>王大</name>
<sex>男</sex>
<age>12</age>
<grade>3</grade>
</student>
</students>
<teachers>
<teacher id="110" type="22">
<name>张老师</name>
<sex>男</sex>
<age>12</age>
<grade>3</grade>
</teacher>
</teachers>
</objects></span>
这不是最常见的简单的xml,因为他里面包含了2个元素,students 和 teachers
一个简单的布局文件 activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >
<LinearLayout
android:id="@+id/line_s"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_alignParentTop="true"
android:orientation="vertical" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6" >
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</ScrollView>
<EditText
android:id="@+id/et_delete"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#7f7f7f" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="bottom"
android:orientation="vertical" >
<Button
android:id="@+id/btn_add_node_to_xml"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="add node to xml" />
<Button
android:id="@+id/btn_delete_from_xml"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="delete from xml" />
<Button
android:id="@+id/btn_in_db"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="writer to db" />
<Button
android:id="@+id/btn_writer_xml"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="writer to xml" />
<Button
android:id="@+id/btn_pull_analysis"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="analysis" />
</LinearLayout>
</LinearLayout>
实体类
Teacher.class
@Column行可以无视删除,是因为这里用到这个倒数据库,Student.class 跟这个一样写就可以了
package com.example.pullanalysis;
import org.xutils.db.annotation.Column;
public class Teacher {
@Column(name = "name")
String name;
@Column(name = "sex")
String sex;
@Column(name = "age")
String age;
@Column(name = "grade")
String grade;
@Column(name = "id")
String id;
@Column(name = "type")
String type;
@Column(name = "code")
String code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "Teacher [name=" + name
+ ", sex=" + sex
+ ", age=" + age
+ ", grade=" + grade
+ ", id=" + id
+ ", type="+ type
+ ", code=" + code
+ "]";
}
}
MainActivity.class
<pre name="code" class="java">package com.example.pullanalysis;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import org.xutils.common.util.LogUtil;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
/**
* 对xml文件的pull解析 生成xml文件 对xml文件的增加,删除
*/
private TextView mtvResult;
private Button mbtnAnalysis;
private Button mbtnWriter;
private Button mbtnWriterdb;
private Button mbtnDelete;
private Button mbtnAdd;
private EditText metdelete;
private List<Student> mStudentlist;
private List<Teacher> mTeacherlist;
Map<String, Object> mListMap;
private String path;
private File file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initData() {
// TODO Auto-generated method stub
path = Environment.getExternalStorageDirectory().getAbsolutePath();
file = new File(path, "Astudent.xml");
}
private void initView() {
// TODO Auto-generated method stub
mtvResult = (TextView) findViewById(R.id.tv_result);
mbtnAnalysis = (Button) findViewById(R.id.btn_pull_analysis);
mbtnWriter = (Button) findViewById(R.id.btn_writer_xml);
mbtnWriterdb = (Button) findViewById(R.id.btn_in_db);
mbtnDelete = (Button) findViewById(R.id.btn_delete_from_xml);
metdelete = (EditText) findViewById(R.id.et_delete);
mbtnAdd = (Button) findViewById(R.id.btn_add_node_to_xml);
mListMap = new HashMap<String, Object>();
mbtnAnalysis.setOnClickListener(this);
mbtnWriter.setOnClickListener(this);
mbtnWriterdb.setOnClickListener(this);
mbtnDelete.setOnClickListener(this);
mbtnAdd.setOnClickListener(this);
metdelete.requestFocus();
metdelete.setText("测试数据");
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_pull_analysis:
readxml();
break;
case R.id.btn_writer_xml:
writertoxml(mListMap);
break;
case R.id.btn_in_db:
writertodb();
break;
case R.id.btn_delete_from_xml:
delete("teacher", "id", "0");
break;
case R.id.btn_add_node_to_xml:
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("name", "白雪公主");
map.put("sex", "man");
map.put("age", "7");
map.put("grade", "2");
add("books", "book", "123", map);
break;
default:
break;
}
}
/**
* 将对象写入数据库
*/
private void writertodb() {
TStudent tstu = new TStudent(MainActivity.this);
Student stu = mStudentlist.get(0);
boolean d = true;
int n = 1;
long btime = System.currentTimeMillis();
long etime = 0;
while (d) {
tstu.insert(stu);
if (n < 1000) {
n++;
} else {
d = false;
etime = System.currentTimeMillis();
mtvResult.setText(String.valueOf(etime - btime));
}
}
}
/**
* pull 解析读取xml文件
*/
private void readxml() {
try {
InputStream ips = getAssets().open("data.xml");// 打开assets下的文件
XmlPullParser parser = Xml.newPullParser();
parser.setInput(ips, "utf-8");
int eventtype = parser.getEventType();// 产生第一个事件
Student student = null;
Teacher teacher = null;
StringBuffer str1 = new StringBuffer();
StringBuffer str2 = new StringBuffer();
while (eventtype != XmlPullParser.END_DOCUMENT) {
switch (eventtype) {
case XmlPullParser.START_DOCUMENT:// 判断当前事件是否为文档开始事件
break;
case XmlPullParser.START_TAG:// 判断当前事件是否为标签元素开始事件
String name = parser.getName();
if (name.equals("students")) {
mStudentlist = new ArrayList<Student>();
}
if (name.equals("student")) { // 判断开始标签元素是否是student
student = new Student();
student.setCode("student");
student.setId(parser.getAttributeValue(0));
student.setType(parser.getAttributeValue(1));
}
if (student != null) {
if (name.equals("name")) {
student.setName(parser.nextText());
} else if (name.equals("sex")) {
student.setSex(parser.nextText());
} else if (name.equals("age")) {
student.setAge(parser.nextText());
} else if (name.equals("grade")) {
student.setGrade(parser.nextText());
}
}
if (name.equals("teachers")) {
mTeacherlist = new ArrayList<Teacher>();
}
if (name.equals("teacher")) {
teacher = new Teacher();
teacher.setCode("teacher");
teacher.setId(parser.getAttributeValue(0));
teacher.setType(parser.getAttributeValue(1));
}
if (teacher != null) {
if (name.equals("name")) {
teacher.setName(parser.nextText());
} else if (name.equals("sex")) {
teacher.setSex(parser.nextText());
} else if (name.equals("age")) {
teacher.setAge(parser.nextText());
} else if (name.equals("grade")) {
teacher.setGrade(parser.nextText());
}
}
break;
case XmlPullParser.END_TAG:// 判断当前事件是否为标签元素结束事件
// 当读到student的时候,表示一个student对象读完了,这时候就可以把这个对象加入到list里了
// 当然,在读到student前还会读到</name></sex>等的end_tag 直接无视就好了
if (parser.getName().equals("student")) {
mStudentlist.add(student);
student = null;
}
if (parser.getName().equals("teacher")) {
mTeacherlist.add(teacher);
teacher = null;
}
// 读到</students>表示,students读完了
if (parser.getName().equals("students")) {
mListMap.put("students", mStudentlist);
}
if (parser.getName().equals("teachers")) {
mListMap.put("teachers", mTeacherlist);
}
break;
default:
break;
}
eventtype = parser.next();// 不断的去更新,持续的解析XML文件直到文件的尾部。
}
if (mStudentlist != null && mStudentlist.size() != 0) {
for (int i = 0; i < mStudentlist.size(); i++) {
str1.append("name:" + mStudentlist.get(i).getName())
.append(" sex:" + mStudentlist.get(i).getSex())
.append(" age:" + mStudentlist.get(i).getAge())
.append(" grade:" + mStudentlist.get(i).getGrade()).append("\n\n");
}
Toast.makeText(MainActivity.this, "解析成功", Toast.LENGTH_LONG).show();
}
if (mTeacherlist != null && mTeacherlist.size() != 0) {
for (int i = 0; i < mTeacherlist.size(); i++) {
str2.append("name:" + mTeacherlist.get(i).getName())
.append(" sex:" + mTeacherlist.get(i).getSex())
.append(" age:" + mTeacherlist.get(i).getAge())
.append(" grade:" + mTeacherlist.get(i).getGrade()).append("\n\n");
}
Toast.makeText(MainActivity.this, "解析成功", Toast.LENGTH_SHORT).show();
}
mtvResult.setText(str1.toString() + "" + str2);
} catch (IOException e) {
LogUtil.d("IOException", e);
} catch (XmlPullParserException e) {
LogUtil.d("XmlPullParserException", e);
}
}
/**
* 将对象的list写入xml文件
*
* @param list
*/
private void writertoxml(Map<String, Object> listmap) {
if (listmap != null && listmap.size() > 0) {
FileOutputStream out = null;
XmlSerializer xsl = Xml.newSerializer();
List<Student> stlist = (List<Student>) listmap.get("students");
List<Teacher> tealist = (List<Teacher>) listmap.get("teachers");
int a = stlist.size();
try {
out = new FileOutputStream(file);
xsl.setOutput(out, "utf-8");
xsl.startDocument("utf-8", true);
xsl.startTag("", "Object");
xsl.attribute("", "path", "http://xxxx.yyyy.cc.v");
xsl.attribute("", "time", "23:23:23");
if (stlist != null && stlist.size() > 0) {
xsl.startTag("", "students");
int i = 0;
for (Student stu : stlist) {
String node = "student" + (i++);
xsl.startTag("", "student");
xsl.attribute("", "id", String.valueOf(i));
xsl.attribute("", "type", stu.getType());
xsl.startTag("", "name");
xsl.text(stu.getName());
xsl.endTag("", "name");
xsl.startTag("", "sex");
xsl.text(stu.getSex());
xsl.endTag("", "sex");
xsl.startTag("", "age");
xsl.text(stu.getAge());
xsl.endTag("", "age");
xsl.startTag("", "grade");
xsl.text(stu.getGrade());
xsl.endTag("", "grade");
xsl.endTag("", "student");
}
xsl.endTag("", "students");
}
if (tealist != null && tealist.size() > 0) {
xsl.startTag("", "teachers");
int j = 0;
for (Teacher teacher : tealist) {
String node = "teacher" + (j++);
xsl.startTag("", "teacher");
xsl.attribute("", "id", String.valueOf(j));
xsl.attribute("", "type", teacher.getType());
xsl.startTag("", "name");
xsl.text(teacher.getName());
xsl.endTag("", "name");
xsl.startTag("", "sex");
xsl.text(teacher.getSex());
xsl.endTag("", "sex");
xsl.startTag("", "age");
xsl.text(teacher.getAge());
xsl.endTag("", "age");
xsl.startTag("", "grade");
xsl.text(teacher.getGrade());
xsl.endTag("", "grade");
xsl.endTag("", "teacher");
}
xsl.endTag("", "teachers");
}
xsl.endTag("", "Object");
xsl.endDocument();
out.close();
Toast.makeText(MainActivity.this, "写入成功", Toast.LENGTH_LONG).show();
} catch (IllegalArgumentException e) {
LogUtil.d("IllegalArgumentException", e);
} catch (IllegalStateException e) {
LogUtil.d("IllegalStateException", e);
} catch (IOException e) {
LogUtil.d("IOException", e);
}
}
}
/**
* 根据节点code以及对于的属性值删除对应的节点
*
* @param code
* @param property
* @param value
*/
private void delete(String code, String property, String value) {// code,子节点,子节点的值
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder bulider = factory.newDocumentBuilder();
Document doc = bulider.parse(file);
doc.normalize();
Element root = doc.getDocumentElement();// 得到根节点
NodeList listnode = doc.getElementsByTagName(code);
for (int i = 0; i < listnode.getLength(); i++) {
Element elink = (Element) listnode.item(i);
String prop = elink.getAttribute(property);
if (prop.equals(value)) {
if(listnode.getLength()==1){
//如果只有一条数据,那么这条数据删除之后,大节点也应该被删除
root.removeChild(elink.getParentNode());
}else{
elink.getParentNode().removeChild(elink);
}
Toast.makeText(MainActivity.this, "删除成功", Toast.LENGTH_LONG).show();
}
}
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer trans = tfactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
trans.transform(source, result);// 将原文件覆盖
} catch (Exception e) {
LogUtil.d("ParserConfigurationException", e);
}
}
private int getMaxId(String code, String idnum) {
int num = 0;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder bulider = factory.newDocumentBuilder();
Document doc = bulider.parse(file);
doc.normalize();
NodeList listnode = doc.getElementsByTagName(code);
for (int i = 0; i < listnode.getLength(); i++) {
Element elink = (Element) listnode.item(i);
String id = elink.getAttribute(idnum);
if (Integer.valueOf(id) > num) {
num = Integer.valueOf(id);
}
}
return num;
} catch (ParserConfigurationException e) {
LogUtil.d("ParserConfigurationException", e);
return num;
} catch (SAXException e) {
LogUtil.d("SAXException", e);
return num;
} catch (IOException e) {
LogUtil.d("IOException", e);
return num;
}
}
/**
* 添加节点尚不存在的对象
*/
private void addtoxml(String bigcode, String code, String type, Map<String, String> map) {
FileOutputStream out = null;
XmlSerializer xsl = Xml.newSerializer();
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder bulider = factory.newDocumentBuilder();// 1.通过DocumentBuilder工厂得到对应的xml解析器
Document doc = bulider.parse(file);// 2.通过解析器得到Document对象
doc.normalize();
Element root = doc.getDocumentElement();// 得到根节点
Element bigNode = doc.createElement(bigcode);
Element codeNode = doc.createElement(code);
codeNode.setAttributeNS("", "id", String.valueOf(getMaxId(code, "id") + 1));
codeNode.setAttributeNS("", "type", type);
for (String key : map.keySet()) {
Node node = codeNode.appendChild(doc.createElement(key)).appendChild(doc.createTextNode(map.get(key)));
}
bigNode.appendChild(codeNode);
root.appendChild(bigNode);
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer trans = tfactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
trans.transform(source, result);
Toast.makeText(MainActivity.this, "增加成功", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("www", e + "");
}
}
/**
* 添加已存在节点的对象
*
* @param code
*/
private void add(String bigCode, String code, String type, Map<String, String> map) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder bulider = factory.newDocumentBuilder();// 1.通过DocumentBuilder工厂得到对应的xml解析器
Document doc = bulider.parse(file);// 2.通过解析器得到Document对象
doc.normalize();
Element root = doc.getDocumentElement();// 得到根节点
NodeList employees = root.getChildNodes();
// 判断是节点是否存在
if (employees != null) {
int flag = 0;
for (int i = 0; i < employees.getLength(); i++) {
Node mycode = employees.item(i);
if (mycode.getNodeName().equals(bigCode)) {
flag++;
}
}
if (flag == 0) {
addtoxml(bigCode, code, type, map);
return;
}
}
Element per = (Element) selectSingleNode("/Object/" + bigCode, root);
Element codeNode = doc.createElement(code);
codeNode.setAttributeNS("", "id", String.valueOf(getMaxId(code, "id") + 1));
codeNode.setAttributeNS("", "type", type);
for (String key : map.keySet()) {
Node node = codeNode.appendChild(doc.createElement(key)).appendChild(doc.createTextNode(map.get(key)));
}
per.appendChild(codeNode);
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer trans = tfactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
trans.transform(source, result);
Toast.makeText(MainActivity.this, "增加成功", Toast.LENGTH_LONG).show();
} catch (ParserConfigurationException e) {
LogUtil.d("ParserConfigurationException", e);
} catch (SAXException e) {
LogUtil.d("SAXException", e);
} catch (IOException e) {
LogUtil.d("IOException", e);
} catch (TransformerConfigurationException e) {
LogUtil.d("TransformerConfigurationException", e);
} catch (TransformerException e) {
LogUtil.d("TransformerException", e);
}
}
/**
* 选择具体某一结点
*
*
*/
public static Node selectSingleNode(String express, Element source) {
Node result = null;
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
try {
result = (Node) xpath.evaluate(express, source, XPathConstants.NODE);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return result;
}
}
注: 1.运行的时候先点解析,在生成,增加,删除
2. 关于数据库的直接注释掉就可以了
转载请注明原文地址: https://ju.6miu.com/read-1299093.html