本文重点两点: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,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 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,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 } }