反射

1 下列XML文档中,符合XML语法规范的是

A.

  1. <customer>
  2.      <address>123 MainStreet></Address>
  3. </customer>

B.

  1. <customer>
  2. <name>Joe’s XML Works</name>
  3. <address>New York
  4. </costomer>

C.

  1. <customer type=extemal>
  2. <name>Partners Unlimited</name>
  3. </customer>

D.

 
  1. <customer name="JohnDoe">
  2. <address>123 Main Street</address>
  3. <zip code="01837"/>
  4. </customer>

参考答案

本题正确答案为D。

AB选项,不符合XML语法规范。在XML中,元素要成对出现,而且大小写敏感。A选项元素address的结尾为</Address>,“A”字母要小写。B选项元素<address>没有结尾标记。

C选项,不符合XML语法规范。在XML中,属性必须被引号包围,不过单引号和双引号均可使用。

2 简述SAX和DOM解析方式的不同

参考答案

DOM:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成各个Node对象(节点)。

优点:把xml文件在内存中构造树形结构,可以遍历和修改节点

缺点:如果文件比较大,内存有压力,解析的时间会比较长

SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析。

优点: 解析可以立即开始,速度快,没有内存压力

缺点: 不能对节点做修改

3 客户端以XML格式向服务器端发送数据V1

客户端以XML格式向服务器端发送数据,详细要求如下:

1)客户端读取EmpList.xml数据,将其发送到服务器端。

2)服务器接收到XML格式的数据后,进行解析,将解析到的数据输出到控制台。

参考答案

实现此案例需要按照如下步骤进行。

步骤一:导入dom4j对应的jar包

在当前工程下导入dom4j对应的jar包。

步骤二:创建服务器端Server类

首先,新建类Server;然后在该类的main方法中创建ServerSocket对象,监听客户端的连接以及网络输入流对象,代码如下所示:

 
  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. public class Server {
  5.     public static void main(String[] args) {
  6.         try {
  7.             //创建服务端Socket
  8.             ServerSocket server = new ServerSocket(8088);
  9.             System.out.println("等待客户端连接");
  10.             //监听客户端连接
  11.             Socket socket = server.accept();
  12.             System.out.println("客户端已经连接");
  13.             //获取输入流
  14.             InputStream in = socket.getInputStream();
  15.         } catch (Exception e) {
  16.             e.printStackTrace();
  17.         }
  18.     }
  19. }

步骤三:创建SAXReader类的对象,获取Document对象

首先,创建SAXReader类的对象来实现读取XML文档;然后,使用SAXReader类的read方法获取Document对象,代码如下所示:

 
  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.Element;
  8. import org.dom4j.io.SAXReader;
  9. public class Server {
  10.     public static void main(String[] args) {
  11.         try {
  12.             //创建服务端Socket
  13.             ServerSocket server = new ServerSocket(8088);
  14.             System.out.println("等待客户端连接");
  15.             //监听客户端连接
  16.             Socket socket = server.accept();
  17.             System.out.println("客户端已经连接");
  18.             //获取输入流
  19.             InputStream in = socket.getInputStream();
  20.             //创建SAXReader
  21.             SAXReader reader = new SAXReader();
  22.             System.out.println("开始解析客户端发送的xml");
  23. //读取指定文件
  24.             Document doc = reader.read(in);
  25.         } catch (Exception e) {
  26.             e.printStackTrace();
  27.         }
  28.     }
  29. }

步骤四:获取根元素

使用Document对象的getRootElement方法获取EmpList.xml文档的根元素,代码如下所示:

 
  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.Element;
  8. import org.dom4j.io.SAXReader;
  9. public class Server {
  10.     public static void main(String[] args) {
  11.         try {
  12.             //创建服务端Socket
  13.             ServerSocket server = new ServerSocket(8088);
  14.             System.out.println("等待客户端连接");
  15.             //监听客户端连接
  16.             Socket socket = server.accept();
  17.             System.out.println("客户端已经连接");
  18.             //获取输入流
  19.             InputStream in = socket.getInputStream();
  20.             //创建SAXReader
  21.             SAXReader reader = new SAXReader();
  22.             System.out.println("开始解析客户端发送的xml");
  23.             //读取指定文件
  24.             Document doc = reader.read(in);
  25.             //获取跟节点list
  26.             Element root = doc.getRootElement();
  27.         } catch (Exception e) {
  28.             e.printStackTrace();
  29.         }
  30.     }
  31. }

步骤五:获取<list>元素下的所有子元素

使用Element对象的elements方法获取<list>元素下的所有子元素,即所有的<emp>节点,代码如下所示:

 
  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.Element;
  8. import org.dom4j.io.SAXReader;
  9. public class Server {
  10.     public static void main(String[] args) {
  11.         try {
  12.             //创建服务端Socket
  13.             ServerSocket server = new ServerSocket(8088);
  14.             System.out.println("等待客户端连接");
  15.             //监听客户端连接
  16.             Socket socket = server.accept();
  17.             System.out.println("客户端已经连接");
  18.             //获取输入流
  19.             InputStream in = socket.getInputStream();
  20.             //创建SAXReader
  21.             SAXReader reader = new SAXReader();
  22.             System.out.println("开始解析客户端发送的xml");
  23.             //读取指定文件
  24.             Document doc = reader.read(in);
  25.             //获取跟节点list
  26.             Element root = doc.getRootElement();
  27.             //获取list下的所有子节点emp
  28.             List<Element> elements = root.elements();
  29.         } catch (Exception e) {
  30.             e.printStackTrace();
  31.         }
  32.     }
  33. }

步骤六:封装Emp对象,存储到List集合中

1)创建存储的数据类型为Emp类型的List集合emps;

2)循环上一步中的elements集合,每循环一次获取一个emp元素。在循环中使用Element对象的attribute方法获取id属性对应的Attribute对象,再使用Attribute对象的getValue方法就可以获取到属性id对应的文本信息,即Emp对象的属性id的信息;

3)在循环中,使用Element对象的elementText方法获取节点<name>、<age>、<gender>以及<salary>对应的文本信息,即Emp对象的属性name、age、gender以及salary。

4)在循环中,将上述获取到的信息封装为Emp对象,存储到集合emps中。

代码如下所示:

 
  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.Element;
  8. import org.dom4j.io.SAXReader;
  9. public class Server {
  10.     public static void main(String[] args) {
  11.         try {
  12.             //创建服务端Socket
  13.             ServerSocket server = new ServerSocket(8088);
  14.             System.out.println("等待客户端连接");
  15.             //监听客户端连接
  16.             Socket socket = server.accept();
  17.             System.out.println("客户端已经连接");
  18.             //获取输入流
  19.             InputStream in = socket.getInputStream();
  20.             //创建SAXReader
  21.             SAXReader reader = new SAXReader();
  22.             System.out.println("开始解析客户端发送的xml");
  23.             //读取指定文件
  24.             Document doc = reader.read(in);
  25.             //获取跟节点list
  26.             Element root = doc.getRootElement();
  27.             //获取list下的所有子节点emp
  28.             List<Element> elements = root.elements();
  29.             //保存所有员工对象的集合
  30.             List<Emp> emps = new ArrayList<Emp>();
  31.             for(Element element : elements){            
  32.                 int id = Integer.parseInt(element.attribute("id").getValue());
  33.                 String name = element.elementText("name");
  34.                 int age = Integer.parseInt(element.elementText("age"));
  35.                 String gender = element.elementText("gender");
  36.                 double salary = Double.parseDouble(element.elementText("salary"));
  37.                 Emp emp = new Emp(id,name,age,gender,salary);
  38.                 emps.add(emp);
  39.             }
  40.             System.out.println("解析完毕");
  41.         } catch (Exception e) {
  42.             e.printStackTrace();
  43.         }
  44.     }
  45. }

步骤七:输出集合

将emps集合的信息输出到控制台并关闭Socket对象,代码如下所示:

 
  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.Element;
  8. import org.dom4j.io.SAXReader;
  9. public class Server {
  10.     public static void main(String[] args) {
  11.         try {
  12.             //创建服务端Socket
  13.             ServerSocket server = new ServerSocket(8088);
  14.             System.out.println("等待客户端连接");
  15.             //监听客户端连接
  16.             Socket socket = server.accept();
  17.             System.out.println("客户端已经连接");
  18.             //获取输入流
  19.             InputStream in = socket.getInputStream();
  20.             //创建SAXReader
  21.             SAXReader reader = new SAXReader();
  22.             System.out.println("开始解析客户端发送的xml");
  23.             //读取指定文件
  24.             Document doc = reader.read(in);
  25.             //获取跟节点list
  26.             Element root = doc.getRootElement();
  27.             //获取list下的所有子节点emp
  28.             List<Element> elements = root.elements();
  29.             //保存所有员工对象的集合
  30.             List<Emp> emps = new ArrayList<Emp>();
  31.             for(Element element : elements){            
  32.                 int id = Integer.parseInt(element.attribute("id").getValue());
  33.                 String name = element.elementText("name");
  34.                 int age = Integer.parseInt(element.elementText("age"));
  35.                 String gender = element.elementText("gender");
  36.                 double salary = Double.parseDouble(element.elementText("salary"));
  37.                 Emp emp = new Emp(id,name,age,gender,salary);
  38.                 emps.add(emp);
  39.             }
  40.             System.out.println("解析完毕");
  41.             System.out.println(emps);
  42.             server.close();
  43.         } catch (Exception e) {
  44.             e.printStackTrace();
  45.         }
  46.     }
  47. }

步骤八: 创建客户端Client类

新建类Client,在该类的main方法中,首先,创建Socket去连接服务器端;然后获取网络输出流,代码如下所示:

 
  1. import java.io.File;
  2. import java.io.OutputStream;
  3. import java.net.Socket;
  4. import org.dom4j.Document;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. public class Client {
  8.     public static void main(String[] args) {
  9.         try {
  10.             //连接服务端
  11.             Socket socket = new Socket("127.0.0.1",8088);
  12.             //获取输出流
  13.             OutputStream out = socket.getOutputStream();
  14.         } catch (Exception e) {
  15.             e.printStackTrace();
  16.         }
  17.     }
  18. }

步骤九: 读取XML文档

创建SAXReader对象,来读取XML文档,并获取Document对象,代码如下所示:

  1. import java.io.File;
  2. import java.io.OutputStream;
  3. import java.net.Socket;
  4. import org.dom4j.Document;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. public class Client {
  8.     public static void main(String[] args) {
  9.         try {
  10.             //连接服务端
  11.             Socket socket = new Socket("127.0.0.1",8088);
  12.             //获取输出流
  13.             OutputStream out = socket.getOutputStream();
  14.             //创建SAXReader
  15.             SAXReader reader = new SAXReader();
  16.             //读取指定文件
  17.             Document doc = reader.read(new File("EmpList.xml"));
  18.         } catch (Exception e) {
  19.             e.printStackTrace();
  20.         }
  21.     }
  22. }

步骤十:发送XML文件到服务器端

首先,创建XML输出流XMLWriter类的对象;然后,设置该XML输出流的字节输出流为网络输出流out;最后,将Document对象写出到服务器端并关闭Socket对象,代码如下所示:

 
  1. import java.io.File;
  2. import java.io.OutputStream;
  3. import java.net.Socket;
  4. import org.dom4j.Document;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. public class Client {
  8.     public static void main(String[] args) {
  9.         try {
  10.             //连接服务端
  11.             Socket socket = new Socket("127.0.0.1",8088);
  12.             //获取输出流
  13.             OutputStream out = socket.getOutputStream();
  14.             //创建SAXReader
  15.             SAXReader reader = new SAXReader();
  16.             //读取指定文件
  17.             Document doc = reader.read(new File("EmpList.xml"));
  18.             //创建XML输出流
  19.             XMLWriter writer = new XMLWriter();
  20.             writer.setOutputStream(out);
  21.             writer.write(doc);
  22.             socket.close();
  23.         } catch (Exception e) {
  24.             e.printStackTrace();
  25.         }
  26.     }
  27. }

步骤十一: 测试

运行代码,首先启动服务器端,然后启动客户端,服务器端控制台输出结果如下所示:

 
  1. 等待客户端连接
  2. 客户端已经连接
  3. 开始解析客户端发送的xml
  4. 解析完毕
  5. [Emp [id=1,name=张三, age=34, gender=男, salary=3000.0], Emp [id=2,name=李四, age=21, gender=女, salary=4000.0], Emp [id=3,name=王五, age=46, gender=女, salary=6500.0], Emp [id=4,name=赵六, age=28, gender=男, salary=4400.0], Emp [id=5,name=钱七, age=53, gender=男, salary=12000.0]]

本案例中,Emp类的完整代码如下所示:

 
  1. /**
  2. * 描述xml文件中每一个员工信息
  3. */
  4. public class Emp {
  5.     private int id;
  6.     private String name;
  7.     private int age;
  8.     private String gender;
  9.     private double salary;
  10.     public Emp(int id,String name, int age, String gender, double salary) {
  11.         this.id = id;
  12.         this.name = name;
  13.         this.age = age;
  14.         this.gender = gender;
  15.         this.salary = salary;
  16.     }
  17.     public int getId() {
  18.         return id;
  19.     }
  20.     public void setId(int id) {
  21.         this.id = id;
  22.     }
  23.     public String getName() {
  24.         return name;
  25.     }
  26.     public void setName(String name) {
  27.         this.name = name;
  28.     }
  29.     public int getAge() {
  30.         return age;
  31.     }
  32.     public void setAge(int age) {
  33.         this.age = age;
  34.     }
  35.     public String getGender() {
  36.         return gender;
  37.     }
  38.     public void setGender(String gender) {
  39.         this.gender = gender;
  40.     }
  41.     public double getSalary() {
  42.         return salary;
  43.     }
  44.     public void setSalary(double salary) {
  45.         this.salary = salary;
  46.     }
  47.     @Override
  48.     public String toString() {
  49.         return "Emp [id=" + id + ",name=" + name + ", age=" + age + ", gender=" + gender
  50.                 + ", salary=" + salary + "]";
  51.     }
  52. }

Server类的完整代码如下所示:

  1. import java.io.InputStream;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.Element;
  8. import org.dom4j.io.SAXReader;
  9. public class Server {
  10.     public static void main(String[] args) {
  11.         try {
  12.             //创建服务端Socket
  13.             ServerSocket server = new ServerSocket(8088);
  14.             System.out.println("等待客户端连接");
  15.             //监听客户端连接
  16.             Socket socket = server.accept();
  17.             System.out.println("客户端已经连接");
  18.             //获取输入流
  19.             InputStream in = socket.getInputStream();
  20.             //创建SAXReader
  21.             SAXReader reader = new SAXReader();
  22.             System.out.println("开始解析客户端发送的xml");
  23.             //读取指定文件
  24.             Document doc = reader.read(in);
  25.             //获取跟节点list
  26.             Element root = doc.getRootElement();
  27.             //获取list下的所有子节点emp
  28.             List<Element> elements = root.elements();
  29.             //保存所有员工对象的集合
  30.             List<Emp> emps = new ArrayList<Emp>();
  31.             for(Element element : elements){            
  32.                 int id = Integer.parseInt(element.attribute("id").getValue());
  33.                 String name = element.elementText("name");
  34.                 int age = Integer.parseInt(element.elementText("age"));
  35.                 String gender = element.elementText("gender");
  36.                 double salary = Double.parseDouble(element.elementText("salary"));
  37.                 Emp emp = new Emp(id,name,age,gender,salary);
  38.                 emps.add(emp);
  39.             }
  40.             System.out.println("解析完毕");
  41.             System.out.println(emps);
  42.             server.close();
  43.         } catch (Exception e) {
  44.             e.printStackTrace();
  45.         }
  46.     }
  47. }

Client类的完整代码如下所示:

  1. import java.io.File;
  2. import java.io.OutputStream;
  3. import java.net.Socket;
  4. import org.dom4j.Document;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. public class Client {
  8.     public static void main(String[] args) {
  9.         try {
  10.             //连接服务端
  11.             Socket socket = new Socket("127.0.0.1",8088);
  12.             //获取输出流
  13.             OutputStream out = socket.getOutputStream();
  14.             //创建SAXReader
  15.             SAXReader reader = new SAXReader();
  16.             //读取指定文件
  17.             Document doc = reader.read(new File("EmpList.xml"));
  18.             //创建XML输出流
  19.             XMLWriter writer = new XMLWriter();
  20.             writer.setOutputStream(out);
  21.             writer.write(doc);        
  22.             socket.close();
  23.         } catch (Exception e) {
  24.             e.printStackTrace();
  25.         }
  26.     }
  27. }

4 客户端以XML格式向服务器端发送数据V2(提高题,选做)

客户端以XML格式向服务器端发送数据,详细要求如下:

1)客户端读取EmpList.xml中的数据,将其发送到服务器端。

2)服务器接收到XML格式的数据后,将其输出到Emp_Server.xml文件中。

参考答案

在上一案例中,是将客户端发送来的EmpList.xml解析输出到控制台,本案例要求将客户端发送来的XML格式的数据输出到Emp_Server.xml文件中,即,我们只要将服务器端Server类解析输出到控制台的代码,改为将XML格式的数据输出到Emp_Server.xml文件即可。

实现此案例需要按照如下步骤进行。

步骤一:修改Server类

修改Server类,将解析输出到控制台的代码,改为将XML格式的数据输出到Emp_Server.xml文件,代码如下所示:

  1. import java.io.FileOutputStream;
  2. import java.io.InputStream;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. import org.dom4j.Document;
  6. import org.dom4j.io.SAXReader;
  7. import org.dom4j.io.XMLWriter;
  8. public class Server {
  9.     public static void main(String[] args) {
  10.         try {
  11.             //创建服务端Socket
  12.             ServerSocket server = new ServerSocket(8088);
  13.             System.out.println("等待客户端连接");
  14.             //监听客户端连接
  15.             Socket socket = server.accept();
  16.             System.out.println("客户端已经连接");
  17.             //获取输入流
  18.             InputStream in = socket.getInputStream();
  19.             //创建SAXReader
  20.             SAXReader reader = new SAXReader();
  21.             System.out.println("开始解析客户端发送的xml");
  22.             //读取用户发送过来的xml
  23.             Document doc = reader.read(in);
  24.             //写出XML
  25.             XMLWriter writer = new XMLWriter();
  26.             FileOutputStream fos = new FileOutputStream("Emp_Server.xml");
  27.             writer.setOutputStream(fos);
  28.             writer.write(doc);
  29.             writer.close();
  30.             server.close();
  31.         } catch (Exception e) {
  32.             e.printStackTrace();
  33.         }
  34.     }
  35.     
  36. }

运行代码,首先启动服务器端,然后启动客户端,在你当前工程目录下会生成emp_server.xml文件。文件内容与EmpList.xml文件内容相同。

本案例中,Emp类的完整代码如下所示:

 
  1. /**
  2. * 描述xml文件中每一个员工信息
  3. */
  4. public class Emp {
  5.     private int id;
  6.     private String name;
  7.     private int age;
  8.     private String gender;
  9.     private double salary;
  10.     public Emp(int id,String name, int age, String gender, double salary) {
  11.         this.id = id;
  12.         this.name = name;
  13.         this.age = age;
  14.         this.gender = gender;
  15.         this.salary = salary;
  16.     }
  17.     public int getId() {
  18.         return id;
  19.     }
  20.     public void setId(int id) {
  21.         this.id = id;
  22.     }
  23.     public String getName() {
  24.         return name;
  25.     }
  26.     public void setName(String name) {
  27.         this.name = name;
  28.     }
  29.     public int getAge() {
  30.         return age;
  31.     }
  32.     public void setAge(int age) {
  33.         this.age = age;
  34.     }
  35.     public String getGender() {
  36.         return gender;
  37.     }
  38.     public void setGender(String gender) {
  39.         this.gender = gender;
  40.     }
  41.     public double getSalary() {
  42.         return salary;
  43.     }
  44.     public void setSalary(double salary) {
  45.         this.salary = salary;
  46.     }
  47.     @Override
  48.     public String toString() {
  49.         return "Emp [id=" + id + ",name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + "]";
  50.     }
  51. }

Server类的完整代码如下所示:

 
  1. import java.io.FileOutputStream;
  2. import java.io.InputStream;
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5. import org.dom4j.Document;
  6. import org.dom4j.io.SAXReader;
  7. import org.dom4j.io.XMLWriter;
  8. public class Server {
  9.     public static void main(String[] args) {
  10.         try {
  11.             //创建服务端Socket
  12.             ServerSocket server = new ServerSocket(8088);
  13.             System.out.println("等待客户端连接");
  14.             //监听客户端连接
  15.             Socket socket = server.accept();
  16.             System.out.println("客户端已经连接");
  17.             //获取输入流
  18.             InputStream in = socket.getInputStream();
  19.             //创建SAXReader
  20.             SAXReader reader = new SAXReader();
  21.             System.out.println("开始解析客户端发送的xml");
  22.             //读取用户发送过来的xml
  23.             Document doc = reader.read(in);
  24.             //写出XML
  25.             XMLWriter writer = new XMLWriter();
  26.             FileOutputStream fos = new FileOutputStream("Emp_Server.xml");
  27.             writer.setOutputStream(fos);
  28.             writer.write(doc);
  29.             writer.close();
  30.             server.close();
  31.         } catch (Exception e) {
  32.             e.printStackTrace();
  33.         }
  34.     }    
  35. }
 

Client类的完整代码如下所示:

 
  1. import java.io.File;
  2. import java.io.OutputStream;
  3. import java.net.Socket;
  4. import org.dom4j.Document;
  5. import org.dom4j.io.SAXReader;
  6. import org.dom4j.io.XMLWriter;
  7. public class Client {
  8.     public static void main(String[] args) {
  9.         try {
  10.             //连接服务端
  11.             Socket socket = new Socket("127.0.0.1",8088);
  12.             //获取输出流
  13.             OutputStream out = socket.getOutputStream();
  14.             //创建SAXReader
  15.             SAXReader reader = new SAXReader();
  16.             //读取指定文件
  17.             Document doc = reader.read(new File("EmpList.xml"));
  18.             //创建XML输出流
  19.             XMLWriter writer = new XMLWriter();
  20.             writer.setOutputStream(out);
  21.             writer.write(doc);        
  22.             socket.close();
  23.         } catch (Exception e) {
  24.             e.printStackTrace();
  25.         }
  26.     }
  27. }
 
posted @ 2018-01-22 20:26  清风已来  阅读(341)  评论(0编辑  收藏  举报