Java解析XML


1 吴 青 QQ:16910735 wuqing_bean@126.com 吴老师教学讲义 XML http://blog.sina.com/accpwulaoshi 忽然抚尺一下,群响毕绝。撤屏视之,一人、一桌、一椅、一扇、一抚 尺 而 已 吴老师教学讲义 2 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 Java 解析 XML XML 现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关 性,给数据集成与交互带来了极大的方便. W3C 定义了 XML 的语法以及 XML 的读写操作 方法,任何计算机高级语言都可以实现对 XML 的读写操作, 本节将学习 Java 对 XML 的 读写操作。 1. 两种解析方式 XML 在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析 方式有两种,一种是 SAX(Simple API for XML),另一种是 DOM(Document Object Model)。  SAX: 用于 XML 处理的简单 API 基于事件驱动的 XML 处理技术,使用 SAX 解析 XML 时,程序从 XML 文档的开头 逐字逐句的读取,在此过程中激发事件(比如:文档开始,文档结束,元素开始,元素结 束等事件),由应用程序对 XML 数据进行处理。例如,startElement()在每次 SAX 解析 器遇到元素的起始标记时激发。endElement() 在元素的结束标记时激发。  DOM:XML 文档树结构的解析 DOM 把 XML 文档中的元素、文本、属性视为节点,组成一种树结构,称为 DOM 树,通过 DOM 树可以访问所有的节点。也可以修改节点的内容,添加、删除节点等操作。 W3C Dom 是 W3C 推荐的用于解析的 XML 文件解析模型。W3C 规定了 DOM 解析的接 口和对象,用于对 DOM 进行标准操作。 两者的比较: 解析方法 优点 缺点 SAX 无需将整个文档加载到内存,减少内存消 耗。 不能够随机访问 XML 文档。 不支持在原地修改 XML。 不支持名字空间作用域。 DOM 丰富的 API 集合,可用于轻松地导航。 整棵树加载到内存,允许对 XML 文档进 行随机访问。 整个 XML 文档必须一次解析完。 将整棵树加载到内存成本较高。 Java 有丰富的组件提供对 XML 进行操作,常见的有 4 中操作方式:JAXP、JDOM、 DOM4J、JAXB 等。他们在不同的领域对 XML 进行方便操作。 吴老师教学讲义 3 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 1.1 解析用的 xml 文档 为了演示各种操作的方式,需要准备一个 xml 文档 2. JAXP (Java API for XML Processing ) JAXP是使用JavaAPI对XML 进行处理的一种规范,它提供接口来操作SAX和DOM。 JAXP 的 API 已经包含在 JDK 中,它包含了三个包: org.w3c.dom: W3C 推荐的用于 XML 操作的标准文档对象模型的接口。 org.xml.sax: 用于对 XML 进行语法分析的事件驱动的 XML 简单 API(SAX) Javax.xml.parsers: 解析器工厂工具,程序员获得并配置特殊的语法分析器。 W3C DOM 的常用对象及其方法有: 对象 说明 常用方法/属性 常用方法说明 Document DOM 最高层节点。 getDocumentElement 返回 XML 文档的根元素节点 Node 表示单一节点,包括 XML 中的元素、属性、文本等节 点。 nodeName,nodeValue 返回节点的名称和值(属性) parentNode,childNodes 返回父节点和子节点(属性) firstChild,lastChild 返回第一个和最后一个子节点 张三 1981-04-16T00:00:00+08:00 李四 1982-04-16T00:00:00+08:00 吴老师教学讲义 4 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 appendChild(c) 在子节点结尾添加新节点。 Element 元素,Node 子类。 getAttribute(n) 返回指定属性的值。 setAttribute(n,v) 设置指定属性的值。 Attr 属性,Node 子类。 name,value 属性的名称和值(属性) CharacterData 文本,Node 子类。 —— —— NodeList 节点列表。 length 返回节点列表中的节点数。 item(index) 返回 index 位置的索引项。 下面开始解析上面的 xml 文档,新建一个 java 项目,不需要引入任何 jar 包,因为 jdk 中已 经自带 JAXP 的 API 2.1 加载 XML 文件 一般情况下我们将 xml 文件放到项目的 src 目录中,经过编译 MyEclipse 工具编译 以后,放到了 bin 目录中,也就是程序运行的 classpath 路径中,从 classpath 路径下加 载一个文件(不管是什么文件),可以使用 Class 类中的 getResourceAsStream 方法, 这个方法返回一个 InputStream 文件流 2.2 获得文档解析器工厂 2.3 从工厂中获得解析器 public static void main(String[] args) { //XML文件输入流 InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); } public static void main(String[] args) { //XML文件输入流 InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); //文档解析器构建工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); } public static void main(String[] args) { //XML文件输入流 InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); //文档解析器构建工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //获取文档解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); } 吴老师教学讲义 5 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 2.4 取得文档 注意:这里为了演示方便,没有处理异常 2.5 获取根元素 2.6 使用递算法归遍历根元素下所有的子元素 parseElement 方法是遍历一个元素中的信息。 首先是元素的标记名称,这可以使用 getNodeName 方法来获取。接着获取属性, getAttributes()方法可以获取所有的属性,然后遍历每一个属性,显示属性的名称和值 接着考察该元素下所有的子元素,如果子元素只有一个并且节点类型是文本节点,判 断方法为: public static void main(String[] args) { //XML文件输入流 InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); //文档解析器构建工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //获取文档解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); //获取文档,传入文档流 Document document=builder.parse(xmlInputStream); } public static void main(String[] args) { //XML文件输入流 InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); //文档解析器构建工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //获取文档解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); //获取文档,传入文档流 Document document=builder.parse(xmlInputStream); //取得根元素 Element root=document.getDocumentElement(); System.out.println("根元素名称:"+root.getNodeName()); } 吴老师教学讲义 6 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 nodeList.getLength()==1&&nodeList.item(0).getNodeType()==Node.TEXT_NODE),则显示文 本信息,方法调用结束(return),否则取出元素中所有的子元素,递归调用该方法继续遍 历元素中的信息。 ①由于 xml 文件是格式化的,带有空格和回车换行符,JAXP 把这些字符也解析为一 个文本节点(CharacterData),此处在遍历 XML 文件的节点时,需要把 Element 元素 检索出来。 2.7 在 main 方法中调用递归 private static void parseElement(Element element){ System.out.println("元素名称:"+element.getNodeName()); NamedNodeMap namedNodeMap=element.getAttributes(); for(int i=0;i张三像这样的元素 JDOM 认为没有孩子节点,而 W3C DOM 则认为有孩子节点,节点的类型为文本节点,这里我们 需要加以区别。如果还有孩子几点,则遍历这些孩子节点,递归调用 parseElement 方法 public static void main(String[] args) throws JDOMException, IOException { InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); SAXBuilder builder=new SAXBuilder();//使用Sax解析器 } public static void main(String[] args) throws JDOMException, IOException { InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); SAXBuilder builder=new SAXBuilder();//使用Sax解析器 Document document=builder.build(xmlInputStream); } public static void main(String[] args) throws JDOMException, IOException { InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); SAXBuilder builder=new SAXBuilder();//使用Sax解析器 Document document=builder.build(xmlInputStream); //取得根元素 Element root=document.getRootElement(); } 吴老师教学讲义 11 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 3.6 在 main 方法中调用自定义方法:parseElement 3.7 增加元素 增加一个编号为 3,姓名为王五,性别为女,生日为系统当前时间的元素,并保存到 xml 文档中。 注意:保存后的结果放在了 bin 目录中,这里使用的 Class 类中的 getResource 方法, 该方法的参数是一个文件在 classpath 中的路径,返回一个文件的 URL,通过调用 URL 的 getFile 方法可以获取文件的完成的路径名,这个路径经过了 URL 编码,如果路径中带有中 文字符,就需要进行 URL 解码。 private static void parseElement(Element element){ System.out.println("元素名称:"+element.getName()); //解析属性 List attributeList=element.getAttributes(); for (Attribute attribute : attributeList) { System.out.println("属性:"+attribute.getName()+"-->"+attribute.getValue()); } //取得孩子节点 List children=element.getChildren(); if(children.size()==0 && element.getText()!=null){ System.out.println(element.getText()); }else{ for (Element child : children) { parseElement(child); } } } public static void main(String[] args) throws JDOMException, IOException { InputStream xmlInputStream=Test1.class.getResourceAsStream("/employee.xml"); SAXBuilder builder=new SAXBuilder();//使用Sax解析器 Document document=builder.build(xmlInputStream); //取得根元素 Element root=document.getRootElement(); parseElement(root); } 吴老师教学讲义 12 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 4. XPath XPath 是一种在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素 和属性进行遍历。XPath 是 W3C XSLT 标准的主要内容之一,它使用路径表达式在 XML 文档中进行导航。XPath 含有丰富的内建函数,这些函数用于字符串、数值,日期和时间 比较,节点和 QName 处理、序列处理、逻辑处理等。QName 是指一个合法的 XML 元 素,由命名空间(namespace)前缀(prefix)以及冒号(:)和一个元素名称构成。 4.1XPath 术语  节点(Node) public static void main(String[] args) throws JDOMException, IOException { InputStream xmlInputStream = Test2.class .getResourceAsStream("/employee.xml"); SAXBuilder builder = new SAXBuilder();// 使用Sax解析器 Document document = builder.build(xmlInputStream); xmlInputStream.close(); // 取得根元素 Element root = document.getRootElement(); Element element=new Element("employee");//创建元素 element.setAttribute("id","3");//添加元素 element.addContent(new Element("name").setText("王五")); element.addContent(new Element("sex").setText("女")); element.addContent(new Element("birthday").setText(new Date().toString())); //将创建的元素添加到根上 root.addContent(element); //创建输出器,参数是一个输出的格式 XMLOutputter xmlOutputter=new XMLOutputter(Format.getPrettyFormat()); //输出路径 String filePath=URLDecoder.decode(Test2.class.getResource("/employee.xml").getFile(),"UTF-8"); File xmlFile=new File(filePath); xmlOutputter.output(document,new FileOutputStream(xmlFile)); } 进行 URL 解码。 这个 xml 文件最 终保存在了 bin 目录中 吴老师教学讲义 13 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以 及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节 点。  基本值(或称原子值,Atomic value) 无父节点(根节点)或者无子节点(叶子节点)的节点  项目(Item) 节点和基本值的总称。  父节点(parent) 每一个元素有一个父节点。  子节点(children) 每一个元素有零个、1 个或者多个子节点。  兄弟节点(sibling)[`sibliŋ] 拥有相同父节点的节点。  先辈(Ancestor)[`ænsistə] 某节点的父节点,父节点的父节点……  后代(Descendant)[di’sendənt] 某节点的子节点,子节点的子节点…… 4.2 路径表达式 XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path)来选取的。 表达式 描述 nodename 选取此节点的所有子节点 / 从根节点选取 吴老师教学讲义 14 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 . 选取当前节点 .. 选取当前节点的父节点 @ 选取属性 以上面的 xml 文档为例,下面列出了表达式的意义 路径表达式 结果 employees 选取 employees 元素的所有子节点 / employees 选取根元素 employees 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的 绝对路径! employees /employee 选取所有属于 employees 的子元素的 employee 元素。 // employee 选取所有 employee 子元素,而不管它们在文档中的位置。 employees// employee 选择所有属于 employees 元素的后代的 employee 元素,而不 管它们位于 employees 之下的什么位置。 //@id 选取所有名为 id 的属性。 4.3 查找某个特定的节点或者包含某个指定的值的节点 谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。 下面是一些使用的例子:  /employees/employee[1] 选取 employees 下的第一个 employee 元素 吴老师教学讲义 15 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有  /employees/employee[last()] 选取 employees 下的最后一个 employee 元素  /employees/employee[last()-1] 选取 employees 下的倒数第二个 employee 元素  /employees/employee[position()<3] 选取 employees 下的第 1 个和第 2 个 employee 元素  //employee[@id] 选取所有拥有名为 id 的属性的 employee 元素。  //employee [@id='2'] 选取所有拥有名为 id 的属性,并且值为 2 的 employee 元素。  /employees/employee[sex=’男’] 选取所有 employee 元素,并且其中的 sex 元素的值为‘男’  /employees/employee[sex=’男’]/name 选取所有 employee 下的 name 元素,并且其中的 sex 元素的值为‘男’ 4.5 使用通配符 XPath 中可以使用通配符:*、@*、node()等: 通配符 描述 * 匹配任何元素节点 @* 匹配任何属性节点 node() 匹配任何类型的节点 例子: 路径表达式 结果 吴老师教学讲义 16 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 /employees /* 选取 employees 元素的所有子节点 //* 选取文档中的所有元素 //employee [@*] 选取所有带有属性的 employee 元素。 4.6 选取多个路径 通过在路径表达式中使用“|”运算符,您可以选取若干个路径。 路径表达式 结果 //book/title | //book/price 选取所有 book 元素的 title 和 price 元素。 //title | //price 选取所有文档中的 title 和 price 元素。 /bookstore/book/title | //price 选取所有属于 bookstore 元素的 book 元素 的 title 元素,以及文档中所有的 price 元素。 4.7 运算符 同时 XPath 还支持算术运算符(+、-、*、div、mod)、关系运算符(>、<、>=、 <=、=、!=)和逻辑运算符(or、and)。 4.8 JDOM 中的 xpath 对象 JDOM 中提供了 Xpath 对象来封装 xpath 表达式,然后调用 selectNodes 方法,该 方法需要传递一个 Document 对象,这样就可以在文档中选出我们想要的元素了。在下面 的例子中,我们修改 “张三”的生日为当前时间. 思路:我们需要修改的是生日,也就是 birthday 元素,所以我们可以使用表达式: /employees/employee[name=’张三’]/birthday 表达式 public static void main(String[] args) throws JDOMException, IOException { InputStream xmlInputStream = Test3.class .getResourceAsStream("/employee.xml"); SAXBuilder builder = new SAXBuilder();// 使用Sax解析器 Document document = builder.build(xmlInputStream); xmlInputStream.close(); XPath xpath=XPath.newInstance("/employees/employee[name='张三']/birthday"); List list=xpath.selectNodes(document); Element birthdayElement=list.get(0); 吴老师教学讲义 17 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 注意,这段代码在运行的过程中,需要有 jaxen.jar 的支持,否 则 会 报如下异常. (jaxen.jar 文件在 JDOM 发行包的 lib 目录中) 5. JAXB 操作 XML 读取 XML 对于应用软件来说是一个必不可少的工作,JDK 为我们提供了很好的 XML 处理方式,读写 XML 的组件也有很多(比如:JDOM),但都是对 XML 的解析工具,需 要手工调用 get 和 set 方法操作对象属性,不能直接绑定到 Java 对象。 JAXB(Java Architecture ([`ɑ:kitektʃə] ,体系结构,层次结构)for XML Binding) 是 一个业界的标准,可以根据 XML Schema 产生 Java 对象,也可以把 Java 类中的 Annotation 与 XML 文件绑定,通过操作 Java 类,自动完成对 XML 的操作。 Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/JaxenException at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) at org.jdom.xpath.XPath.newInstance(XPath.java:134) 张三 1981-04-16T00:00:00+08:00 李四 XML 文件 吴老师教学讲义 18 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 该过程中,JAXB 提供了将 XML 实例文档反向生成 Java 对象树的方法,并能将 Java 对象内存树的内容重新写到 XML 实例文档。从另一方面来讲,JAXB 提供了快速而简便的 方法将 XML 模式绑定到 Java 表示,从而使得 Java 开发者在 Java 应用程序中能方便地结 合 XML 数据和处理函数。 JDK6 中,定义了很多的 Annotation,可以直接使用这些 Annotation 来完成 xml 文 档与 JavaBean 的“绑定”,所以我们需要掌握这些 Annotation 所代表的意义。 5.1 @XmlAccessorType 作用:指明如何绑定(修饰 Class 或者包) JavaBean 有 Filed(字段),用来保存数据。Filed 有对应的 Getter/Setter 方法,那 么是将 Filed 绑定到 XML 中的元素呢还是 Getter/Setter 方法绑定到 XML 元素呢,使用 JDK6 中定义好的@ XmlAccessorType 可以明确指定,它完整的类型名是: javax.xml.bind.annotation.XmlAccessorType: public class Employee { private Integer id; private String name; private String sex; private Date birthday; //省略Getter Setter } public class Employees { public Employees() { } private List employee= new ArrayList(); //省略getter setter } JavaBean JavaBean 吴老师教学讲义 19 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 标记在 JavaBean 类上,控制默认情况下是否对字段或 Javabean 属性与 XML 进行 绑定),该 Annotation 有一个值是一个枚举值,定义在 javax.xml.bind.annotation. XmlAccessType 中。  XmlAccessType.PROPERTY 表示默认情况下对 JavaBean 的属性(getter/setter 方法)自动绑定到 XML 上。  XmlAccessType. FIELD 表示默认情况下对 JavaBean 的字段(不包括静态、瞬态字段)自动绑定到 XML 上。 5.2 @XmlType 作用:将类或枚举类型映射到 XML 模式类型(修饰 Class) 我们知道,xml schema 可以定义 xml 中的元素是简单类型还是复杂类型。 简单类型元素的意思是只包含文本而不包含任何其它元素或者属性,比如 张三,或者20,或者2005-5-5就是简 单元素类型。 复杂类型元素的意思是:包含其它元素或者属性的元素,如 或者 javax.xml.bind.annotation.XmlType,它指明了将类或枚举类型映射到 XML 的 Schema 类型,如果是复杂类型还可以规定 JavaBean 的属性或字段映射到 XML 中元素 出现的先后顺序。 使用方法是: @XmlType(name = "Schema 类型名称", propOrder = { XML 中元素的顺序 }) 当缺省“XML 中元素的顺序”时,则 XML 中元素顺序为无序。 @XmlType(name = "", propOrder = {}) 要被映射,类必须拥有一个不带参数的公共构造方法,或者一个静态的不带参数的工 厂方法。使用静态不带参数的工厂方法构造该 JavaBean 时,使用方法是: 吴老师教学讲义 20 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 @XmlType(name = "Schema 类型名称", propOrder = { XML 中元素的顺序 },factoryClass=工厂类,factoryMethod="工厂方法名") 5.3 @XmlRootElement 作用:指定根元素(修饰 Class) 如果要映射的 JavaBean 对象是 xml 文件中的根元素,则使用它,全称是 javax.xml.bind.annotation.XmlRootElement 5.4 @XmlElement 作用:指定类中的 Filed 或者属性到 XML 元素的映射(修饰 Filed 或者 getter/setter 方法)将 JavaBean 属性或者字段映射到 XML 元素。这里的字段必须非 static、非 transient 字段。 使用方法是: @XmlElement(name="标记名称" required=true|false) 缺省 name 时,属性或者字段名将视为 XML 的标记名称。 5.5 @XmlAttribute 作用是:指定 Filed 或者属性到 XML 元素属性的映射(修饰 Filed 或者 getter/setter 方法)全称是:javax.xml.bind.annotation.XmlAttribute 将 JavaBean 属性或者字段映射到 XML 属性。如果字段或属性的类型是集合类型, 则必须将集合项类型映射到基本类型。如果字段或属性的类型是非集合类型,则必须将属 性或字段的类型映射到基本类型。Java 的 8 种基本类型以及 String 类型、Date 类型及他 们的集合映射给 XML 时,不需要转换,称为简单类型。使用方法是: @XmlAttribute(required = true|false,name="属性名") 缺省 name 时,属性或者字段名将视为 XML 的标记属性名称。 5.6 @XmlTransient 作用:指明不需要做映射的字段或者属性(修饰 Field 或者 Getter/Setter 方法) 全称是:javax.xml.bind.annotation.XmlTransient 阻止将 JavaBean 属性或字段映射到 XML 表示形式。@XmlTransient 注释可 以解决 JavaBean 属性名称和字段名称之间的名称冲突,或者用于防止字段/属性的映射。 吴老师教学讲义 21 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 5.7 @XmlJavaTypeAdapter 作用:完成自定义映射(修饰 Field 或者 Getter/Setter 方法) 使用自定义编程完成 XML 与 JavaBean 的映射,需要实现 XmlAdapter 的适配器, 经常作用在 JavaBean 的属性和字段中。 5.8@XmlSchemaType 作用 :将 Java 类型映射到一个简单的模式内置类型(修饰 Field 或者 Getter/Setter 方法) 常用简单类型有:  xs:string  xs:decimal  xs:integer  xs:boolean  xs:date  xs:time  xs: dateTime 5.9 实战 利用 JAXB 的 Annotation 完成 XML 文件与 JavaBean 及其字段、属性的映射绑定 后,就可以对 JavaBean 进行操作,JAXB 自动完成与 XML 的同步工作。 定义 Employee 类: @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "employeeType", propOrder = { "name", "sex", "birthday" }) public class Employee { @XmlAttribute(name="id",required=true) private Integer id; @XmlElement(required=true) private String name; @XmlElement(required=true) private String sex; @XmlElement(required=true) @XmlSchemaType(name="date") private Date birthday; 使用字段绑定 映射为复杂元 素,子元素出现 的顺序 吴老师教学讲义 22 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 Employees 类,该类映射 xml 文档的根元素 编写 main 方法测试: id 为必须属性 Schema 内置类型 @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name="employeesType",propOrder={"employee"}) @XmlRootElement(name="employees") public class Employees { public Employees() { } @XmlElement(required=true) private List employee=new ArrayList(); public List getEmployee() { return employee; } public void setEmp(List employee) { this.employee = employee; } public void addEmployy(Employee employee){ this.employee.add(employee); } } public static void main(String[] args) throws JAXBException { JAXBContext context=JAXBContext.newInstance(Employees.class); Unmarshaller unmarshaller=context.createUnmarshaller(); Employees employees=(Employees) unmarshaller.unmarshal(Test.class.getResource("/employee.xml")); for (Employee emp :employees.getEmployee()) { System.out.println(emp); } } 吴老师教学讲义 23 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 获取 JAXB 上下文,用于对 JAXB 环境进行初始化。JAXBContext 类提供了 JAXB API 的客户端入口点。它提供了管理实现 JAXB 绑定操作所需的 XML/Java 绑定信息的抽象, 这些操作包括:解组(unmarshal)、编组(marshal [`ma:ʃəl] 整理,编排)和验证 (validate)。 1. 解组可以使客户端应用程序利用 Unmarshaller 类将 XML 数据转换为 Java 对象。 2. 编组使客户端应用程序利用 Marshaller 类将 Java 对象转换回 XML 数据。 JAXBContext 的 newInstance 方法可以传入包名(String 类型),也可以传入类名 (Class 类型)。  JAXBContext.newInstance( "包名 1:包名 2" ) JAXBContext 实例根据冒号分隔的 Java 包名称的列表进行初始化。每个 java 包 都包含 JAXB 映射类、用户注释类等。  JAXBContext.newInstance( Class… cls ) JAXBContext 实例使用作为参数传递的类以及可从这些类静态获得的类来实现初始 化。 添加一个元素,然后保存: public static void main(String[] args) throws JAXBException, UnsupportedEncodingException { JAXBContext context = JAXBContext.newInstance(Employees.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Employees employees = (Employees) unmarshaller.unmarshal(Test2.class.getResource("/employee.xml")); Employee employee=new Employee(); employee.setId(3); employee.setName("王五"); employee.setSex("男"); 吴老师教学讲义 24 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 5.10 自定义映射 如果要为 Employee 再添加一个爱好属性,对应的元素是音乐,足球, 书法,此时的 xml 文件为: 对应的 java 类为: 张三 1981-04-16T00:00:00+08:00 音乐,足球,书法 李四 1982-04-16T00:00:00+08:00 K歌,音乐,游戏 @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "employeeType", propOrder = { "name", "sex", "birthday",“favorite” }) public class Employee { @XmlAttribute(name="id",required=true) private Integer id; @XmlElement(required=true) private String name; @XmlElement(required=true) private String sex; 吴老师教学讲义 25 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有 FavoriteAdapter 是一个自定义的元素转换器,它必须继承 XmlAdapter 6. 总结 public class FavoriteAdapter extends XmlAdapter> { @Override public String marshal(List v) throws Exception { StringBuilder sb=new StringBuilder(); for (int i = 0; i <(v==null?0:v.size()); i++) { sb.append(v.get(i)); if(i unmarshal(String v) throws Exception { return v==null?new ArrayList():Arrays.asList(v.split(",")); } } 自定义元 素转换器 自定义元 素顺序 吴老师教学讲义 26 http://shop34513748.taobao.com/ Copyright©2010 吴青版权所有  目前有两种流行的 XML 解析技术,即 SAX 和 DOM。  JAXP 是使用 JavaAPI 对 XML 进行处理的一种方法,它提供接口来使用 SAX 和 DOM, 可以使用任何与 JAXP 兼容的 XML 解析器对 XML 进行操作。  JDOM 使用 Java 语言自身特性维护一棵 XML 节点树。并且提供了节点树的 XML 输出 功能。  XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素 和属性进行遍历。  JAXB 是一个业界的标准,可以根据 XML Schema 产生 Java 对象,也可以把 Java 对 象中的 Annotation 与 XML 文件绑定,通过操作 Java 对象,自动完成对 XML 的操作。
还剩25页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

liqinwyyx

贡献于2014-01-19

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf