要求:输出一个与某XML Schema相符合的XML文档
1. 开发环境
- jdk1.6-u-11 (jdk-6-windows-i586.exe)
- jaxb (JAXB2_20080829.jar)
- 开发工具:eclipse
2.执行流程
- 将某给定XML Schema 通过运行jaxb的xjc.bat 自动生成若干符合schema中定义java 类文件
- 将生成的若干java 类文件复制到eclipse的java 源代码目录中,并将解压后lib文件夹下的jar文件添加到到eclipse的lib中
- 操纵Java对象
- Java对象生成xml
其中操作Java对象:
ObjectFactory factory = new ObjectFactory();
//由该工厂类的实例来创建符合schema根元素的对象 如 RootC
RootC root = factory.createRootC();
将Java对象写入一个XML文件
JAXBContext jc = JAXBContext.newInstance("my.demo"); //my.demo为包名
Marshaller marshaller=jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal( root ,new FileOutputStream("test.xml")); //将java对象写入一个名为test的XML文件
还可以由一个XML来生成Java对象的实例,如下,由customer.xml来生成CustomerBo类的一个bo 实例
JAXBContext jc = JAXBContext.newInstance("mycompany.demo");
Unmarshaller u = jc.createUnmarshaller();
JAXBElement customerE = (JAXBElement) u.unmarshal(new FileInputStream( "customer.xml"));
CustomerBo bo = (CustomerBo) customerE.getValue();
参考:http://gjxcbbs.com.cn/thread-246-1-1.html
3.出现的问题:
a:exception is java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI needs 2.1 API.
字面意思就是现在使用的是JAXB 2.0的API,但是需要2.1的API。
解决办法:
首先在JDK的lib目录下新建endorsed目录(如果存在就不需要新建了)
然后把jaxws-api.jar 和jaxb-api.jar 拷贝endorsed目录下,问题解决。
若按上述做了之后确仍然报这个错误
是因为所使用的jdk版本低,把更新到jdk1.6u11即可。
参考:http://www.javaeye.com/wiki/topic/754039
b:unable to marshal type "lex.MessageType" as an element because it is missing an @XmlRootElement annotation
这是一个Unmarshaller.unmarshal方法返回实际对象的类型问题。它根据Schema的格式,可能有两种不同的返回结果。
- Example1.:
Schema定义如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="ISBN" type="xsd:int"/>
<xsd:element name="publisher" type="xsd:string"/>
<xsd:element name="edition" type="xsd:int"/>
<xsd:element type="xsd:double" name="price"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
这个例子解析后实际返回xml文档根元素类型的实例
- Example 2:
Schema定义如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="book" type="BookType"></xsd:element>
<xsd:complexType name="BookType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="ISBN" type="xsd:int"/>
<xsd:element name="publisher" type="xsd:string"/>
<xsd:element name="edition" type="xsd:int"/>
<xsd:element type="xsd:double" name="price"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="comment" type="xsd:string"/>
</xsd:schema>
这个例子解析后实际返回的是JAXBElement类型的一个实例。
分析后得出:在第一个例子中,JAXB框架可以根据xml schema确定出xml文档的根元素,因为在解析时可以直接返回根元素类型的实例。而在第二个例子中,JAXB框架无法确定xml文档的根元素,因此在解析时就只能返回JAXBElement类型的实例了。在第一个例子中,生成的java类中可以看到@XmlRootElement(name = "book") anonation,但是第二个例子就没有。
解决办法:若Schema定义与第一个例子相符,则在生成的根元素java类中的anonation区域里添加@XmlRootElement即可
参考: http://blog.csdn.net/zhigangsun/archive/2008/07/23/2698810.aspx
参考:http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html