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中,属性必须被引号包围,不过单引号和双引号均可使用。
参考答案
DOM:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成各个Node对象(节点)。
优点:把xml文件在内存中构造树形结构,可以遍历和修改节点
缺点:如果文件比较大,内存有压力,解析的时间会比较长
SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析。
优点: 解析可以立即开始,速度快,没有内存压力
缺点: 不能对节点做修改
客户端以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 #cold_bold SAXReader reader = new SAXReader(); #cold_bold System.out.println("开始解析客户端发送的xml"); #cold_bold//读取指定文件 #cold_bold 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 #cold_bold 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(); //保存所有员工对象的集合 #cold_bold List<Emp> emps = new ArrayList<Emp>(); #cold_bold for(Element element : elements){ #cold_bold int id = Integer.parseInt(element.attribute("id").getValue()); #cold_bold String name = element.elementText("name"); #cold_bold int age = Integer.parseInt(element.elementText("age")); #cold_bold String gender = element.elementText("gender"); #cold_bold double salary = Double.parseDouble(element.elementText("salary")); #cold_bold Emp emp = new Emp(id,name,age,gender,salary); #cold_bold emps.add(emp); #cold_bold } #cold_bold 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("解析完毕"); #cold_bold System.out.println(emps); #cold_bold 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(); #cold_bold //创建SAXReader #cold_bold SAXReader reader = new SAXReader(); #cold_bold //读取指定文件 #cold_bold 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输出流 #cold_bold XMLWriter writer = new XMLWriter(); #cold_bold writer.setOutputStream(out); #cold_bold writer.write(doc); #cold_bold 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(); } } }
客户端以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 #cold_bold XMLWriter writer = new XMLWriter(); #cold_bold FileOutputStream fos = new FileOutputStream("Emp_Server.xml"); #cold_bold writer.setOutputStream(fos); #cold_bold writer.write(doc); #cold_bold writer.close(); #cold_bold 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(); } } }