本文重点两点:1.再一次解析一个xml,验证之前的理解。 2. 发现endElement内最后一定要 currentTag = null
------------------------------------------------------------------------------------------------------------------
注意:一定要在endElement内最后currentTag = null .
原因:如前一篇所讲,对于非根节点(eg :<name>),在经历 startElement(currentTag = name) , characters (currentTag = name , currentValue = "刘德华") , endElement()后,还会触发一次 characters 。
所以,1. 若endElement内不currentTag = null 的话,那endElement后的currentTag 还是 “name” , 然后再触发一次 characters ,但此时 characters 内的 new String (ch , start ,length) 是空值,不是之前第二步的"刘德华",这样的话本来在第二步中已经赋值的 name = 刘德华 ,会在第四步中 name = 空。
2. 若endElement内最后 设置currentTag = null , 则 触发第四步 characters时,原来在第二步已经被保存的name = "刘德华" 就不会被 更新为 空值。因为根据characters内的判断条件可知,currentTag = 空时不进行操作。
总结一句话:在解析一个node节点结束标签(例如</name>)时,会触发endElement和characters方法,要在endElement方法内,将currentTag = null .
(本例中可以把 endElement内最后的 currentTag = null 删除作为测试)
-----------------------------------------------------------------------------------------------------------------
student.xml
<?xml version="1.0" encoding="UTF-8"?>
<StudentInfo>
<student>
<name>刘德华</name>
<sex>男</sex>
<lesson>
<lessonName>Spring整合开发</lessonName>
<lessonScore>85</lessonScore>
</lesson>
<lesson>
<lessonName>轻量级J2EE应用开发</lessonName>
<lessonScore>95</lessonScore>
</lesson>
<lesson>
<lessonName>Ajax应用开发</lessonName>
<lessonScore>80</lessonScore>
</lesson>
</student>
<student>
<name>宋慧乔</name>
<sex>女</sex>
<lesson>
<lessonName>Spring整合开发</lessonName>
<lessonScore>80</lessonScore>
</lesson>
<lesson>
<lessonName>轻量级J2EE应用开发</lessonName>
<lessonScore>85</lessonScore>
</lesson>
<lesson>
<lessonName>Ajax应用开发</lessonName>
<lessonScore>90</lessonScore>
</lesson>
</student>
</StudentInfo>
程序运行结果:
name :宋慧乔 sex :女 Ajax应用开发=90 Spring整合开发=80 轻量级J2EE应用开发=85 ----------------------------------- name :刘德华 sex :男 Spring整合开发=85 轻量级J2EE应用开发=95 Ajax应用开发=80 -----------------------------------
客户端eclipse java工程android_sax_xml2 目录(左边) 和 服务器端 myeclipse web工程myhttp目录
客户端 Lesson.java
package com.sax.data;
import java.util.HashSet;
public class Lesson {
private String lessonName ; //课程名称
private String lessonScore ; //课程分数
public Lesson() {
// TODO Auto-generated constructor stub
}
public String getLessonName() {
return lessonName;
}
public void setLessonName(String lessonName) {
this.lessonName = lessonName;
}
public String getLessonScore() {
return lessonScore;
}
public void setLessonScore(String lessonScore) {
this.lessonScore = lessonScore;
}
}
客户端 Student.java
package com.sax.data;
import java.util.Set;
public class Student {
private String name ;
private String sex;
private Set<Lesson> lessons;
public Student() {
// TODO Auto-generated constructor stub
}
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 Set<Lesson> getLessons() {
return lessons;
}
public void setLessons(Set<Lesson> lessons) {
this.lessons = lessons;
}
}
客户端 MyHandler.java
package com.sax.handler;
import java.util.HashSet;
import java.util.Set;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.sax.data.Lesson;
import com.sax.data.Student;
public class MyHandler extends DefaultHandler {
private Lesson lesson;
private Set<Lesson> lessons;//每个学生对应的所有的lesson对象
private Student student;
private Set<Student> students; //所有的student对象
private String currentTag; //当前访问到的节点名称
/*nodeName 为一查询标签,让用户自己设定。从构造函数传入。本文nodeName = student .
* 为了直观理解解析过程,就直接用"student"字符串,而不是用nodeName.
* 实际上应该用nodeName 代替 "student"字符串
* */
private String nodeName;
public MyHandler(String nodeName) {
//这里nodeName由用户输入 本程序 为"student" , 下文里的 "student"字符串 其实应该用nodeName来代替
this.nodeName = nodeName;
}
public Set<Student> getStudents() {
return students;
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
students = new HashSet<Student>();
System.out.println("--startDocument--");
super.startDocument();
}
@Override
public void startElement(String url, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
currentTag = qName;
System.out.println("startElement currentTag :"+currentTag);
if ("student".equals(currentTag)) {
student = new Student();
lessons = new HashSet<Lesson>();
}
if ("lesson".equals(currentTag)) {
lesson = new Lesson() ;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String currentValue = new String(ch, start, length);
System.out.println("characters currentTag :"+currentTag+",currentValue :"+currentValue);
if (currentTag=="name") {
student.setName(currentValue);
}
if (currentTag == "sex") {
student.setSex(currentValue);
}
if (currentTag == "lessonName") {
lesson.setLessonName(currentValue);
}
if (currentTag == "lessonScore") {
lesson.setLessonScore(currentValue);
}
}
@Override
public void endElement(String url, String localName, String qName)
throws SAXException {
currentTag = qName;
System.out.println("endElement currentTag :"+currentTag);
/*
* if (currentTag == "lesson" && lesson != null) {
lessons.add(lesson);
lesson = null;
}
if(currentTag == "student" && lessons != null){
student.setLessons(lessons);
lessons = null;
}
if (currentTag == "student" && student != null) {
students.add(student);
student = null;
}
* */
if (currentTag == "lesson") {
lessons.add(lesson);
}
if(currentTag == "student"){
student.setLessons(lessons);
}
if (currentTag == "student") {
students.add(student);
}
/*
* 为了 characters方法中用作标记,因为endElement后还会触发characters方法,
* 所以,在endElement中最后要currentTag = null;
* */
currentTag = null;
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("--endDocument--");
super.endDocument();
}
}
客户端:SaxService.java
package com.sax.service;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import com.sax.data.Student;
import com.sax.handler.MyHandler;
public class SaxService {
public SaxService() {
// TODO Auto-generated constructor stub
}
public static Set<Student> readXML(
InputStream inputStream, String nodeName) {
Set<Student> students = new HashSet<Student>();
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
MyHandler handler = new MyHandler(nodeName);
parser.parse(inputStream, handler);
students = handler.getStudents();
inputStream.close();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return students;
}
}
客户端: HttpUtils.java
package com.sax.http;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class HttpUtils {
public HttpUtils() {
// TODO Auto-generated constructor stub
}
public static InputStream getXML(String path) {
InputStream inputStream = null;
try {
URL url = new URL(path);
if (url != null) {
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setDoInput(true); // 从服务器获取数据
httpURLConnection.setRequestMethod("GET");
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == 200) {
inputStream = httpURLConnection.getInputStream();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return inputStream;
}
}
客户端 Test.java
package com.sax.test;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.sax.data.Lesson;
import com.sax.data.Student;
import com.sax.http.HttpUtils;
import com.sax.service.SaxService;
public class Test {
public Test() {
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<Student> students = new HashSet<Student>();
InputStream inputStream = HttpUtils.getXML("http://192.168.0.102:8080/myhttp/student.xml");
students = SaxService.readXML(inputStream, "student");
for (Student stu : students) {
System.out.println("name :"+stu.getName());
System.out.println("sex :"+stu.getSex());
Set<Lesson> lessons = stu.getLessons();
for(Lesson lesson:lessons){
System.out.println(lesson.getLessonName()+"="+lesson.getLessonScore());
}
System.out.println("-----------------------------------");
}
}
}
服务器端 LoginAction.java
package com.login.manager;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginAction extends HttpServlet {
/**
* Constructor of the object.
*/
public LoginAction() {
super();
}
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to
* post.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//客户端 HttpUtils并没有写request方法是post ,但服务器端可自动识别
String method = request.getMethod();
System.out.println("request method :"+method);
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
System.out.println("-username->>"+username);
String password = request.getParameter("password");
System.out.println("-password->>"+password);
if (username.equals("admin") && password.equals("123")) {
// 表示服务器段返回的结果
out.print("login is success !");
} else {
out.print("login is fail !");
}
out.flush();
out.close();
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException
* if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
}
sax解析xml文件实例一(注意endElement 内部最后 currentTag=null),布布扣,bubuko.com
sax解析xml文件实例一(注意endElement 内部最后 currentTag=null)
原文:http://blog.csdn.net/neu_yousei/article/details/22695761