SAX解析XML

来源:互联网 发布:linux由sql server吗 编辑:程序博客网 时间:2024/06/06 02:50

关于使用SAX解析器的用法


SAX的解析是逐行的解析方式,与DOM不同的点就是DOM是需要对XML文档先进行全部内容的加载,
所以一般的XML解析采用SAX方式,效率比较高,而对于需要对XML文档进行修改操作,可以使用DOM,dom4j,
另外对于XML的解析还有PULL的方法。


举例:
需要解析的原XML文件的具体内容:
____________________________________________________________________________


workers.xml


<?xml version="1.0" encoding="UTF-8"?>
<workers>
    <worker id="001">
         <name>zhangsan</name>
         <age>23</age>
         <money>4000</money>
         <sex>male</sex>
         <status>staff</status>
    </worker>
    <worker id="002">
         <name>lisi</name>
         <age>33</age>
         <money>8000</money>
         <sex>male</sex>
         <status>marketingManager</status>
    </worker>
    <worker id="003">
         <name>wangxiao</name>
         <age>29</age>
         <money>6000</money>
         <sex>female</sex>
         <status>administrativeAssistant</status>
    </worker>
</workers>
————————————————————————————————————————————————————————————————————————————————
dtid3.xml


<?xml version="1.0" encoding="UTF-8"?>
<root>
  <DecisionTree value="null">
    <outlook value="sunny">
      <humidity value="high">no</humidity>
      <humidity value="normal">yes</humidity>
    </outlook>
    <outlook value="overcast">yes</outlook>
    <outlook value="rainy">
      <windy value="TRUE">no</windy>
      <windy value="FALSE">yes</windy>
    </outlook>
  </DecisionTree>
</root>


——————————————————————————————————————————————————————————————————————————————————————————————
package com.kuatang.decode;


import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
/**
 * 具体XML解析实现,采用DefaultHandler是由于假如实现ContentHandler接口,
 * 需要实现其所有抽象函数,而DefaultHandler已经以空函数实现过这些方法。
 * 注意:SAX是逐行解析,每一次解析都会经过开始解析文档函数,开始查元素函数,元素数据获取函数,结束函数。
 * 优缺点:可以按需获取数据,并且能够产生中止行为,对于Android客户端较为实用,但是,如果需要向文档中添加或者删除数据(更改),较为困难,操作复杂。
 * 解析文件:workers.xml
 * 对于Android处SAX方式,还有PULL和DOM(树)的解析方式。
 * @author KUATANG
 *
 */
public class DecodeFromWorkersXML extends DefaultHandler{

private static final String LOG_TAG = "System.out.print.sax";
/**
* xml 每一行的标记
*/
private String tagXML;
/**
* 存放多个员工的list
*/
private List<Workers> list = null;

Workers workers = null;
/**
* 拼接字符串,因为当XML中含有换行回车等情况时,并且一个节点有可能会被执行多次,故而出现错误。
*/
private StringBuffer buffer = null;

public void startDocument() throws SAXException{
list = new ArrayList<DecodeFromWorkersXML.Workers>();
Log.v(LOG_TAG, "---------start decode workers xml document--------");

}

public void endDocument() throws SAXException{
Log.v(LOG_TAG, "--------end decode workers xml document-----------");
System.out.println("-------end decode workers xml document--------");
}
/**
* namespaceUri:命名空间
* qName:带前缀的XML标记
* loaclName:不带前缀的XML标记
* attr:xml标签属性
*/
public void startElement(String namespaceUri, String localName,
String qName, Attributes attrs) throws SAXException{
tagXML = localName;
buffer = new StringBuffer();

if (localName.equals("worker")){
workers = new Workers();
//打印样本
for (int i = 0; i < attrs.getLength(); i++){
Log.v(LOG_TAG, "worker attribute is: " + attrs.getLocalName(i)
+ " and value is: " + attrs.getValue(i));
workers.setId(attrs.getValue(i));
Log.v(LOG_TAG, "workers.id:  " + workers.getId());
}
}
}


public void characters(char[] ch, int start, int length) 
       throws SAXException{
if (tagXML.equals("name")){

String name = buffer.append(new String(ch, start, length)).toString();
workers.setName(name);
Log.v(LOG_TAG, "workers.name:  " + workers.name);

} else if (tagXML.equals("sex")){

workers.sex = buffer.append(new String(ch, start, length)).toString();
Log.v(LOG_TAG, "workers.sex:  " + workers.sex);

} else if (tagXML.equals("money")){
//  使用int定义在节点被齿形多次时,尾节点时报错,原因未明
// workers.money = Integer.parseInt(buffer.append(new String(ch, start, length)).toString());
workers.money = buffer.append(new String(ch, start, length)).toString();
Log.v(LOG_TAG, "workers.money:  " + workers.money);

} else if (tagXML.equals("age")){

workers.setAge(buffer.append(new String(ch, start, length)).toString());
Log.v(LOG_TAG, "workers.age:  " + workers.age);

} else if (tagXML.equals("status")){

workers.status = buffer.append(new String(ch, start, length)).toString();
Log.v(LOG_TAG, "workers.status:  " + workers.status);
}
}

public void endElement(String namespaceUri, String localName, 
String qName) throws SAXException{
if (qName.equals("worker")){
list.add(workers);
printResult();

}

private void printResult(){
for (int i = 0; i < list.size(); i++){
int j = i + 1;
Log.v(LOG_TAG, "-------------第" + j + "员工数据解析完成----------------");
Log.v(LOG_TAG, "编号:" + list.get(i).id);
Log.v(LOG_TAG, "姓名:" + list.get(i).name);
Log.v(LOG_TAG, "年龄:" + list.get(i).age);
Log.v(LOG_TAG, "性别:" + list.get(i).sex);
Log.v(LOG_TAG, "当下职位:" + list.get(i).status);
Log.v(LOG_TAG, "月薪:" + list.get(i).money);
}

}

class Workers{
public String id;
public String name;
public String age;
public String sex;
public String money;
public String status;

public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}


public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}

}


}
————————————————————————————————————————————————————————————————————————————————————————————————————————————

/**
* 以字符流的方式读入文件,一般文本文件等采用
* @param context
* @return
*/
private String StrToReadXML(Context context) throws IOException{
String line;
StringBuffer buffer = new StringBuffer();
String readedXML = "";
BufferedReader bufferedReader = null;


FileInputStream fileInputStream = null;
InputStream in = null;
// in = (context.getAssets().open("dtid3.xml"));
in = (context.getAssets().open("workers.xml"));
if (in instanceof FileInputStream){
fileInputStream = (FileInputStream) in;
try {
bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, "utf-8"));

} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
// InputStreamReader inputStreamReader = new InputStreamReader(context.getResources().getAssets().open("dtid3.xml"));
            InputStreamReader inputStreamReader = new InputStreamReader(context.getResources().getAssets().open("workers.xml"));
            bufferedReader = new BufferedReader(inputStreamReader);
// 另外一种方法 
            // path = "file:///android_asset/dtid3.xml";
            // File file = new File(path);
            // bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));;
}


try {
while ((line = bufferedReader.readLine()) != null){
buffer.append(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
bufferedReader.close();
} catch (Exception e){
e.printStackTrace();
}
}

readedXML = buffer.toString();
Log.v("System.out.print.sax", readedXML);
return readedXML;
}
——————————————————————————————————————————————————————————————————————————————————————————————

/**
* 进行解析
* @param context
*            :上下文
*/
public void decodeXMLUser(Context context){

// String xmlContent = readedXMLFile(context);
String xmlContent = "";
try {
xmlContent = StrToReadXML(context);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//解析器工厂类
SAXParserFactory factory = SAXParserFactory.newInstance();
//读入文件内容,并且做逐行扫描
try {
XMLReader reader = factory.newSAXParser().getXMLReader();
//设置内容处理器
            reader.setContentHandler(new DecodeFromWorkersXML());
// reader.setContentHandler(new SaxXml());
//开始解析
try {
reader.parse(new InputSource(new StringReader(xmlContent)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.v("System.out.print.sax", "SAXException: " + e.getMessage());
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
——————————————————————————————————————————————————————————————————————————————————————————————————
package com.kuatang.decode;


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


import android.util.Log;


/**
 * 具体XML解析实现,采用DefaultHandler是由于假如实现ContentHandler接口,
 * 需要实现其所有抽象函数,而DefaultHandler已经以空函数实现过这些方法。
 * 注意:SAX是逐行解析,每一次解析都会经过开始解析文档函数,开始查元素函数,元素数据获取函数,结束函数。
 * 解析文件:dtid3.xml
 * @author KUATANG
 *
 */
public class SaxXml extends DefaultHandler{

private static final String LOG_TAG = "System.out.print.sax"; 


private String tagAttribute;

private String decisionTree;
private String valueFlag;
private String outFlag;

public void startDocument() throws SAXException{
Log.v(LOG_TAG, "---------start decode xml document--------");
System.out.println("-----------------start decode xml---------------");
}

public void endDocument() throws SAXException{
Log.v(LOG_TAG, "--------end decode xml document-----------");
System.out.println("-----------------end decode xml---------------");
}

public void startElement(String namespaceUri, String localName,
String qName, Attributes attr) throws SAXException{
tagAttribute = localName;
if(localName.equals("DecisionTree")){
//获取标签的全部属性
for(int i = 0; i < attr.getLength(); i++){
// System.out.println("DecisionTree属性名称:" + attr.getLocalName(i)
// + ",属性值:" + attr.getValue(i));
Log.v(LOG_TAG, "DecisionTree属性名称:" + attr.getLocalName(i) + ",属性值:" + attr.getValue(i));
decisionTree =  attr.getValue(i);
valueFlag = attr.getLocalName(i) + "=" +attr.getValue(i);
}
} else if (localName.equals("outlook")){
for(int i = 0; i < attr.getLength(); i++){
// System.out.println("outlook属性名称:" + attr.getLocalName(i)
// + ",属性值:" + attr.getValue(i));
Log.v(LOG_TAG, "outlook属性名称:" + attr.getLocalName(i)
+ ",属性值:" + attr.getValue(i));


valueFlag = attr.getLocalName(i) + "=" +attr.getValue(i);
}
} else if (localName.equals("humidity")){
for(int i = 0; i < attr.getLength(); i++){
// System.out.println("humidity属性名称:" + attr.getLocalName(i)
// + ",属性值:" + attr.getValue(i));
Log.v(LOG_TAG, "humidity属性名称:" + attr.getLocalName(i)
+ ",属性值:" + attr.getValue(i));
valueFlag = attr.getLocalName(i) + "=" +attr.getValue(i);
}
} else if (localName.equals("windy")){
for(int i = 0; i < attr.getLength(); i++){
// System.out.println("windy属性名称:" + attr.getLocalName(i)
// + ",属性值:" + attr.getValue(i));
Log.v(LOG_TAG, "windy属性名称:" + attr.getLocalName(i)
+ ",属性值:" + attr.getValue(i));
valueFlag = attr.getLocalName(i) + "=" +attr.getValue(i);
}
}
}

public void characters(char[] ch, int start, int length) 
       throws SAXException{
if (tagAttribute.equals("DecisionTree")){
System.out.println(decisionTree);


} else if (tagAttribute.equals("outlook")){
System.out.println(valueFlag);
outFlag = new String(ch, start, length);
//输出valueFlag的目的检验是否为每次读取一行数据
Log.v(LOG_TAG, "outlook attribute's valueFlag = " + valueFlag);
       //输出outlook的值
Log.v(LOG_TAG, "outlook's outFlag = " + outFlag);
} else if (tagAttribute.equals("humidity") && valueFlag.equals("high")){
outFlag = new String(ch, start, length);
//输出valueFlag的目的检验是否为每次读取一行数据
Log.v(LOG_TAG, "humidity attribute's valueFlag = " + valueFlag);
       //输出humidity的值
Log.v(LOG_TAG, "humidity's outFlag = " + outFlag);
} else if (tagAttribute.equals("humidity") && valueFlag.equals("normal")){
outFlag = new String(ch, start, length);
Log.v(LOG_TAG, "humidity attribute's valueFlag = " + valueFlag);
Log.v(LOG_TAG, "humidity's outFlag = " + outFlag);
} else if (tagAttribute.equals("windy") && valueFlag.equals("TRUE")){
//此种逻辑判断可能存在开发者并不知晓所有的属性值得可能性,需要根据具体应用需求进行处理。
outFlag = new String(ch, start, length);
Log.v(LOG_TAG, "windy attribute's valueFlag = " + valueFlag);
Log.v(LOG_TAG, "windy's outFlag = " + outFlag);
} else if (tagAttribute.equals("windy") && valueFlag.equals("FALSE")){
outFlag = new String(ch, start, length);
Log.v(LOG_TAG, "windy attribute's valueFlag = " + valueFlag);
Log.v(LOG_TAG, "windy's outFlag = " + outFlag);
}
}

public void endElement(String namespaceUri, String localName, 
String qName) throws SAXException{
if (localName.equals("DecisionTree")){
printResult();
}
}

private void printResult(){
Log.v(LOG_TAG, "元素解析完成。");
}


}
____________________________________________________________________________________


//测试XML解析。
DecodeSAXToXML decodeSAXToXML = DecodeSAXToXML.getInstance();
Context context = this.getApplicationContext();
decodeSAXToXML.decodeXMLUser(context);
____________________________________________________________________________________
0 0
原创粉丝点击