1 下列XML文档中,符合XML语法规范的是
A.
- <customer>
- <address>123 MainStreet></Address>
- </customer>
B.
- <customer>
- <name>Joe’s XML Works</name>
- <address>New York
- </costomer>
C.
- <customer type=extemal>
- <name>Partners Unlimited</name>
- </customer>
D.
- <customer name="JohnDoe">
- <address>123 Main Street</address>
- <zip code="01837"/>
- </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对象,监听客户端的连接以及网络输入流对象,代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤三:创建SAXReader类的对象,获取Document对象
首先,创建SAXReader类的对象来实现读取XML文档;然后,使用SAXReader类的read方法获取Document对象,代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取指定文件
- Document doc = reader.read(in);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤四:获取根元素
使用Document对象的getRootElement方法获取EmpList.xml文档的根元素,代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取指定文件
- Document doc = reader.read(in);
- //获取跟节点list
- Element root = doc.getRootElement();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤五:获取<list>元素下的所有子元素
使用Element对象的elements方法获取<list>元素下的所有子元素,即所有的<emp>节点,代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取指定文件
- Document doc = reader.read(in);
- //获取跟节点list
- Element root = doc.getRootElement();
- //获取list下的所有子节点emp
- List<Element> elements = root.elements();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤六:封装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中。
代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取指定文件
- Document doc = reader.read(in);
- //获取跟节点list
- Element root = doc.getRootElement();
- //获取list下的所有子节点emp
- List<Element> elements = root.elements();
- //保存所有员工对象的集合
- List<Emp> emps = new ArrayList<Emp>();
- for(Element element : elements){
- int id = Integer.parseInt(element.attribute("id").getValue());
- String name = element.elementText("name");
- int age = Integer.parseInt(element.elementText("age"));
- String gender = element.elementText("gender");
- double salary = Double.parseDouble(element.elementText("salary"));
- Emp emp = new Emp(id,name,age,gender,salary);
- emps.add(emp);
- }
- System.out.println("解析完毕");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤七:输出集合
将emps集合的信息输出到控制台并关闭Socket对象,代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取指定文件
- Document doc = reader.read(in);
- //获取跟节点list
- Element root = doc.getRootElement();
- //获取list下的所有子节点emp
- List<Element> elements = root.elements();
- //保存所有员工对象的集合
- List<Emp> emps = new ArrayList<Emp>();
- for(Element element : elements){
- int id = Integer.parseInt(element.attribute("id").getValue());
- String name = element.elementText("name");
- int age = Integer.parseInt(element.elementText("age"));
- String gender = element.elementText("gender");
- double salary = Double.parseDouble(element.elementText("salary"));
- Emp emp = new Emp(id,name,age,gender,salary);
- emps.add(emp);
- }
- System.out.println("解析完毕");
- System.out.println(emps);
- server.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤八: 创建客户端Client类
新建类Client,在该类的main方法中,首先,创建Socket去连接服务器端;然后获取网络输出流,代码如下所示:
- import java.io.File;
- import java.io.OutputStream;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Client {
- public static void main(String[] args) {
- try {
- //连接服务端
- Socket socket = new Socket("127.0.0.1",8088);
- //获取输出流
- OutputStream out = socket.getOutputStream();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤九: 读取XML文档
创建SAXReader对象,来读取XML文档,并获取Document对象,代码如下所示:
- import java.io.File;
- import java.io.OutputStream;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Client {
- public static void main(String[] args) {
- try {
- //连接服务端
- Socket socket = new Socket("127.0.0.1",8088);
- //获取输出流
- OutputStream out = socket.getOutputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- //读取指定文件
- Document doc = reader.read(new File("EmpList.xml"));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤十:发送XML文件到服务器端
首先,创建XML输出流XMLWriter类的对象;然后,设置该XML输出流的字节输出流为网络输出流out;最后,将Document对象写出到服务器端并关闭Socket对象,代码如下所示:
- import java.io.File;
- import java.io.OutputStream;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Client {
- public static void main(String[] args) {
- try {
- //连接服务端
- Socket socket = new Socket("127.0.0.1",8088);
- //获取输出流
- OutputStream out = socket.getOutputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- //读取指定文件
- Document doc = reader.read(new File("EmpList.xml"));
- //创建XML输出流
- XMLWriter writer = new XMLWriter();
- writer.setOutputStream(out);
- writer.write(doc);
- socket.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
步骤十一: 测试
运行代码,首先启动服务器端,然后启动客户端,服务器端控制台输出结果如下所示:
- 等待客户端连接
- 客户端已经连接
- 开始解析客户端发送的xml
- 解析完毕
- [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类的完整代码如下所示:
- /**
- * 描述xml文件中每一个员工信息
- */
- public class Emp {
- private int id;
- private String name;
- private int age;
- private String gender;
- private double salary;
- public Emp(int id,String name, int age, String gender, double salary) {
- this.id = id;
- this.name = name;
- this.age = age;
- this.gender = gender;
- this.salary = salary;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getGender() {
- return gender;
- }
- public void setGender(String gender) {
- this.gender = gender;
- }
- public double getSalary() {
- return salary;
- }
- public void setSalary(double salary) {
- this.salary = salary;
- }
- @Override
- public String toString() {
- return "Emp [id=" + id + ",name=" + name + ", age=" + age + ", gender=" + gender
- + ", salary=" + salary + "]";
- }
- }
Server类的完整代码如下所示:
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.ArrayList;
- import java.util.List;
- import org.dom4j.Document;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取指定文件
- Document doc = reader.read(in);
- //获取跟节点list
- Element root = doc.getRootElement();
- //获取list下的所有子节点emp
- List<Element> elements = root.elements();
- //保存所有员工对象的集合
- List<Emp> emps = new ArrayList<Emp>();
- for(Element element : elements){
- int id = Integer.parseInt(element.attribute("id").getValue());
- String name = element.elementText("name");
- int age = Integer.parseInt(element.elementText("age"));
- String gender = element.elementText("gender");
- double salary = Double.parseDouble(element.elementText("salary"));
- Emp emp = new Emp(id,name,age,gender,salary);
- emps.add(emp);
- }
- System.out.println("解析完毕");
- System.out.println(emps);
- server.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
Client类的完整代码如下所示:
- import java.io.File;
- import java.io.OutputStream;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Client {
- public static void main(String[] args) {
- try {
- //连接服务端
- Socket socket = new Socket("127.0.0.1",8088);
- //获取输出流
- OutputStream out = socket.getOutputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- //读取指定文件
- Document doc = reader.read(new File("EmpList.xml"));
- //创建XML输出流
- XMLWriter writer = new XMLWriter();
- writer.setOutputStream(out);
- writer.write(doc);
- socket.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
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文件,代码如下所示:
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取用户发送过来的xml
- Document doc = reader.read(in);
- //写出XML
- XMLWriter writer = new XMLWriter();
- FileOutputStream fos = new FileOutputStream("Emp_Server.xml");
- writer.setOutputStream(fos);
- writer.write(doc);
- writer.close();
- server.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
运行代码,首先启动服务器端,然后启动客户端,在你当前工程目录下会生成emp_server.xml文件。文件内容与EmpList.xml文件内容相同。
本案例中,Emp类的完整代码如下所示:
- /**
- * 描述xml文件中每一个员工信息
- */
- public class Emp {
- private int id;
- private String name;
- private int age;
- private String gender;
- private double salary;
- public Emp(int id,String name, int age, String gender, double salary) {
- this.id = id;
- this.name = name;
- this.age = age;
- this.gender = gender;
- this.salary = salary;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getGender() {
- return gender;
- }
- public void setGender(String gender) {
- this.gender = gender;
- }
- public double getSalary() {
- return salary;
- }
- public void setSalary(double salary) {
- this.salary = salary;
- }
- @Override
- public String toString() {
- return "Emp [id=" + id + ",name=" + name + ", age=" + age + ", gender=" + gender + ", salary=" + salary + "]";
- }
- }
Server类的完整代码如下所示:
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Server {
- public static void main(String[] args) {
- try {
- //创建服务端Socket
- ServerSocket server = new ServerSocket(8088);
- System.out.println("等待客户端连接");
- //监听客户端连接
- Socket socket = server.accept();
- System.out.println("客户端已经连接");
- //获取输入流
- InputStream in = socket.getInputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- System.out.println("开始解析客户端发送的xml");
- //读取用户发送过来的xml
- Document doc = reader.read(in);
- //写出XML
- XMLWriter writer = new XMLWriter();
- FileOutputStream fos = new FileOutputStream("Emp_Server.xml");
- writer.setOutputStream(fos);
- writer.write(doc);
- writer.close();
- server.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
Client类的完整代码如下所示:
- import java.io.File;
- import java.io.OutputStream;
- import java.net.Socket;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.dom4j.io.XMLWriter;
- public class Client {
- public static void main(String[] args) {
- try {
- //连接服务端
- Socket socket = new Socket("127.0.0.1",8088);
- //获取输出流
- OutputStream out = socket.getOutputStream();
- //创建SAXReader
- SAXReader reader = new SAXReader();
- //读取指定文件
- Document doc = reader.read(new File("EmpList.xml"));
- //创建XML输出流
- XMLWriter writer = new XMLWriter();
- writer.setOutputStream(out);
- writer.write(doc);
- socket.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }