java实用工具之XOM

来源:互联网 发布:软件打不开 编辑:程序博客网 时间:2024/06/10 00:31

前言:在编程中,虽然说在程序执行完毕之后销毁对象是合理并且必须的。但是,我们不可避免的,有时候我们希望将对象持久化,以便于我们下次可以直接恢复他们,而不需要重新去给对象赋值等。于是便有了对象序列化的问题。这种对象的序列化让我们可以在不同的平台上进行对象数据的正确的传输,但是这种序列化也是有局限的,这仅仅是针对于java的解决方案,必须同是java程序才能进行解析。为了追求更加通用的方案,我们可以将数据转化为XML格式,以追求更为通用的解决方案。也就是说,XML是跨平台,跨语言的!


一、什么是XML?

可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。


二、Java中的XML支持

  • 随JDK发布的javax.xml.*类库。
  • XOM开源库,这个看起来更加直观易学,因此这里我们采用XOM来提供支持。开源库的地址:www.xom.nu,有兴趣和精力的完全可以按照上面提供的教程来学习,还是很容易入手的。

三、XOM中的实用类和方法

Element:顾名思义,代表XML的元素,不论是根元素和子元素都用它来表示,相关的方法有:
  • getChildElements(),有多个重载的方法,用于获得当前元素下面的所有子元素,返回Elements对象。
  • getFirstChildElement(),同样有多个重载版本,不能被这个方法命名所误导,这个方法用于获得单个的Element对象(对比上一个方法),而不仅仅只能获得第一个子元素对象。
  • appendChild(),用于为当前元素添加自元素。
  • addAttribute(),为元素添加属性。
Elements:Element对象的一个列表,但并不是真正意义上Java中的List,有get()和size()方法。
Document:一般将根元素作为参数传递可以构造出Document对象,这个对象实际上可以理解为封装XML元素,构造一个XML的“文档”对象。有toXML()方法可以真正地转换为XML格式的数据(前面的操作相当于只是一种构造XML的逻辑)。但是下面我们将看到这个方法不能产生我们想要的格式严格的XML文档。需要借助于Serializer类进行格式的调整。getRootElement()获取根元素。
Serializer:用于对XML进行“格式化”,使得输出更具有可读性,常用的方法有:
  • setIndent(),设置行缩进
  • setMaxLength(),设置行最大的长度,这个长度不是固定死的,当元素名长度比设置的长度还要长的时候,那么设置的这个长度不会限制到这个元素名的显示。
  • write(),将待转格式的Document对象传入,生成按照我们通过上述方法设置的格式的XML输出。
  • Serializer():构造函数,可以传入“格式化”后的输出流,也可以设置编码方式,默认的编码是UTF8编码。
Builder:这个类用于将数据从XML格式中恢复,通过build()方法传入XML数据源,返回一个Document对象。这样我们便可以通过Document对象进行数据恢复了。
Attribute:代表元素的参数。(本文不细讲这个类)

四、XOM实战

1.下载并导入jar包,这个比较简单,就不阐述了,可以百度搜搜教程

2.将数据转换为XML格式(写)

首先是一个Student类,这个类的实例将作为XML的子元素,代码如下:
public class Student {private String firstName;private String lastName;public Student() {}public Student(String firstName, String lastName) {super();this.firstName = firstName;this.lastName = lastName;}// 将Student对象转换为位于root下的一个XML子元素public Element getXML() {Element student = new Element("Student");Element first = new Element("first");first.appendChild(firstName);student.appendChild(first);Element last = new Element("last");last.appendChild(lastName);student.appendChild(last);return student;}}
主类中代码如下:
public class Main {public static void main(String args[]) {List<Student> students = new ArrayList<Student>();students.add(new Student("Dr.Bunsen", "Honeydew"));students.add(new Student("Gonzo", "The Great"));students.add(new Student("Phillip J.", "Fry"));students.add(new Student("明", "王"));students.add(new Student("红", "林"));// 将列表中的学生数据一一放入存放至根目录root下Element root = new Element("Students");for (Student student : students) {root.appendChild(student.getXML());}// 构造XML的Document对象Document document = new Document(root);System.out.println(document.toXML());}}
将结果输出到控制台,我们发现,toXML()的确的并没有什么格式,仅仅是,如下:(部分截图)


下面我们采用Serializer进行XML的“格式化”:
在主类Main中添加方法format(),并在main()方法中调用,format()方法如下:
<span style="font-size:14px;">/*** 将document进行XML的“格式化”* * @param document需要格式化的Document对象* @throws IOException*/public static void format(Document document) throws IOException {Serializer serializer = new Serializer(System.out, "GBK");// 设置行缩进serializer.setIndent(4);// 设置行最大长度serializer.setMaxLength(60);serializer.write(document);}</span>
输出如下,可以看到,的确是比上面的输出更加可读了。

当然我们发现,上述的操作不过是将XML格式的数据输出到控制台,当然我们很多时候需要把它作为文件存储下来,这个也很容易做到,修改format()的方法签名,format(OutputSteam os,Document doc),可以传入输出流让我们有更大的灵活性。
在主函数中再次调用format()函数:
<span style="font-size:14px;">format(new BufferedOutputStream(new FileOutputStream("Students.xml")), document);</span>
可以在相应目录中找到XML文件,用记事本打开查看如下,检验正确。


3.将数据从XML格式中恢复(读)

为Student类添加toString()方法。然后在主类中添加方法recovery()并在main()函数中调用,传入文件路径,进行解析,代码如下:
<span style="font-size:14px;">/*** 将指定XML文件进行数据恢复* * @param fileName* @throws Exception*/private static List<Student> recovery(String fileName) throws Exception {List<Student> students = new ArrayList<Student>();Document document = new Builder().build(new File(fileName));Elements elements = document.getRootElement().getChildElements();for (int i = 0; i < elements.size(); i++) {Element element = elements.get(i);Student student = new Student(element.getFirstChildElement("first").getValue(), element.getFirstChildElement("last").getValue());students.add(student);}return students;}</span>
输出如下,读出成功。

这里有一个陷阱,查阅XOM官方教程也提到了,是这么说的。
Depending on platform, relative URLs may or may not be interpreted as file names. On Windows they seem to be. On Unix/Linux, they are not. It is much safer to use full, unrelative file URLs such as file:///home/elharo/Projects/data/example.xml which should work on essentially any platform. Alternately, you can pass a java.io.File object to the build method instead of a URL.
大体的意思是很可能我们传入的URL并不能被识别为一个正确的文件路径,会使得我们的程序尝试去访问网络获取XML文件,因而产生异常,因此我们需要做的是像上面那样将fileName传递给File对象,强行指定这是一个File对象。若是反其道而行,将build()方法调用改为
Document document = new Builder().build(fileName);
便会出现这样的异常:

五、总结:

我们可以看到,XOM开源库的确是给我们提供了很多的便利,但是它所提供的远不仅仅这些。例如还可以通过Attribute来设置元素的参数等等。具体可以参照官网的教程。






0 0
原创粉丝点击