JAXB的应用,及如何自定义namespace的prefix(前缀)
2012-11-06 21:52
302 查看
什么是JAXB? 不多解释,可以参见维基百科,亦或是百度百科。本文不会对基础部分进行讲解,因为我也没去细看,我只看了了他最简洁的应用方式(基于Annotaion),技术是项目服务,会用,能用好即可。本文主要给出一个Demo,并就JAXB生成xml文件的namespace的prefix不能自定义的问题进行解决。
直接来看代码,首先定义一个 Book类
然后我们定义了一个BookStore来存储Book. 在BookStore中,我们引入了命名空间(namespace)
接着,我们要写一个测试类,来完成Xml 和 BookStore对象的相互转换。
OK, 整个代码都很简单,很容易理解。相关API我也不解释,可以自己Goole,或是Baidu.
看下运行结果
我发现,在Bookstore在命名空间加了前缀,也就是ns2。 那么这个东西可以换成我自己想要的么? 笔者在网上搜索了这个问题很久,碰到这种问题的人相当的多,大多数都是说通过建package-info.java类来解决,笔者也按他们说的做了,但是丝毫没有反应。最后我在这找到了答案:http://stackoverflow.com/questions/2252028/jaxb-how-to-avoid-repeated-namespace-definition-for-xmlnsxsi
然后我查了相关资料,大致上好像是这样的:虽然JDK1.6虽然已经将JAXB做为一个标准和规范了,不过他提供的JAXB是1.0的。而在1.0中namespace的prefix问题是没办法解决的,因为我们要另外引入JAXB2.0.jar 并定义NamespacePrefixMapper,重写getPreferredPrefix()方法。 那么,我改动了一下代码,如入:
再看一下,输出结果:
It works! 所以,我们的问题也就随之解决了。。我将整个Project放到我的CSDN资源中,地址如下:
http://download.csdn.net/detail/zl3450341/4739970
直接来看代码,首先定义一个 Book类
package com.jaxb.first; import java.util.ArrayList; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(namespace="abc") public class Bookstore { // XmLElementWrapper generates a wrapper element around XML representation @XmlElementWrapper(name = "bookList") // XmlElement sets the name of the entities @XmlElement(name = "book") private ArrayList<Book> bookList; private String name; private String location; public void setBookList(ArrayList<Book> bookList) { this.bookList = bookList; } public ArrayList<Book> getBooksList() { return bookList; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
然后我们定义了一个BookStore来存储Book. 在BookStore中,我们引入了命名空间(namespace)
package com.jaxb.first; import java.util.ArrayList; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(namespace="abc") public class Bookstore { // XmLElementWrapper generates a wrapper element around XML representation @XmlElementWrapper(name = "bookList") // XmlElement sets the name of the entities @XmlElement(name = "book") private ArrayList<Book> bookList; private String name; private String location; public void setBookList(ArrayList<Book> bookList) { this.bookList = bookList; } public ArrayList<Book> getBooksList() { return bookList; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
接着,我们要写一个测试类,来完成Xml 和 BookStore对象的相互转换。
package com.jaxb.first; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; public class BookMain { private static final String BOOKSTORE_XML = "./bookstore-jaxb.xml"; public static void main(String[] args) throws JAXBException, IOException { ArrayList<Book> bookList = new ArrayList<Book>(); // create books Book book1 = new Book(); book1.setIsbn("978-0060554736"); book1.setName("The Game"); book1.setAuthor("Neil Strauss"); book1.setPublisher("Harpercollins"); bookList.add(book1); Book book2 = new Book(); book2.setIsbn("978-3832180577"); book2.setName("Feuchtgebiete"); book2.setAuthor("Charlotte Roche"); book2.setPublisher("Dumont Buchverlag"); bookList.add(book2); // create bookstore, assigning book Bookstore bookstore = new Bookstore(); bookstore.setName("Fraport Bookstore"); bookstore.setLocation("Frankfurt Airport"); bookstore.setBookList(bookList); // create JAXB context and instantiate marshaller JAXBContext context = JAXBContext.newInstance(Bookstore.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal(bookstore, System.out); Writer w = null; try { w = new FileWriter(BOOKSTORE_XML); m.marshal(bookstore, w); } finally { try { w.close(); } catch (Exception e) { } } // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um = context.createUnmarshaller(); Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader( BOOKSTORE_XML)); for (int i = 0; i < bookstore2.getBooksList().toArray().length; i++) { System.out.println("Book " + (i + 1) + ": " + bookstore2.getBooksList().get(i).getName() + " from " + bookstore2.getBooksList().get(i).getAuthor()); } } }
OK, 整个代码都很简单,很容易理解。相关API我也不解释,可以自己Goole,或是Baidu.
看下运行结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:bookstore xmlns:ns2="abc"> <bookList> <book> <author>Neil Strauss</author> <name>The Game</name> <publisher>Harpercollins</publisher> <isbn>978-0060554736</isbn> </book> <book> <author>Charlotte Roche</author> <name>Feuchtgebiete</name> <publisher>Dumont Buchverlag</publisher> <isbn>978-3832180577</isbn> </book> </bookList> <location>Frankfurt Airport</location> <name>Fraport Bookstore</name> </ns2:bookstore> Output from our XML File: Book 1: The Game from Neil Strauss Book 2: Feuchtgebiete from Charlotte Roche
我发现,在Bookstore在命名空间加了前缀,也就是ns2。 那么这个东西可以换成我自己想要的么? 笔者在网上搜索了这个问题很久,碰到这种问题的人相当的多,大多数都是说通过建package-info.java类来解决,笔者也按他们说的做了,但是丝毫没有反应。最后我在这找到了答案:http://stackoverflow.com/questions/2252028/jaxb-how-to-avoid-repeated-namespace-definition-for-xmlnsxsi
然后我查了相关资料,大致上好像是这样的:虽然JDK1.6虽然已经将JAXB做为一个标准和规范了,不过他提供的JAXB是1.0的。而在1.0中namespace的prefix问题是没办法解决的,因为我们要另外引入JAXB2.0.jar 并定义NamespacePrefixMapper,重写getPreferredPrefix()方法。 那么,我改动了一下代码,如入:
package com.jaxb.first; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; public class BookMain { private static final String BOOKSTORE_XML = "./bookstore-jaxb.xml"; public static void main(String[] args) throws JAXBException, IOException { ArrayList<Book> bookList = new ArrayList<Book>(); // create books Book book1 = new Book(); book1.setIsbn("978-0060554736"); book1.setName("The Game"); book1.setAuthor("Neil Strauss"); book1.setPublisher("Harpercollins"); bookList.add(book1); Book book2 = new Book(); book2.setIsbn("978-3832180577"); book2.setName("Feuchtgebiete"); book2.setAuthor("Charlotte Roche"); book2.setPublisher("Dumont Buchverlag"); bookList.add(book2); // create bookstore, assigning book Bookstore bookstore = new Bookstore(); bookstore.setName("Fraport Bookstore"); bookstore.setLocation("Frankfurt Airport"); bookstore.setBookList(bookList); // create JAXB context and instantiate marshaller JAXBContext context = JAXBContext.newInstance(Bookstore.class); Marshaller m = context.createMarshaller(); NamespacePrefixMapper mapper = new PreferredMapper(); m.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal(bookstore, System.out); Writer w = null; try { w = new FileWriter(BOOKSTORE_XML); m.marshal(bookstore, w); } finally { try { w.close(); } catch (Exception e) { } } // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um = context.createUnmarshaller(); Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader( BOOKSTORE_XML)); for (int i = 0; i < bookstore2.getBooksList().toArray().length; i++) { System.out.println("Book " + (i + 1) + ": " + bookstore2.getBooksList().get(i).getName() + " from " + bookstore2.getBooksList().get(i).getAuthor()); } } public static class PreferredMapper extends NamespacePrefixMapper { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { return "pre"; } } }
再看一下,输出结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <pre:bookstore xmlns:pre="abc"> <bookList> <book> <author>Neil Strauss</author> <name>The Game</name> <publisher>Harpercollins</publisher> <isbn>978-0060554736</isbn> </book> <book> <author>Charlotte Roche</author> <name>Feuchtgebiete</name> <publisher>Dumont Buchverlag</publisher> <isbn>978-3832180577</isbn> </book> </bookList> <location>Frankfurt Airport</location> <name>Fraport Bookstore</name> </pre:bookstore> Output from our XML File: Book 1: The Game from Neil Strauss Book 2: Feuchtgebiete from Charlotte Roche
It works! 所以,我们的问题也就随之解决了。。我将整个Project放到我的CSDN资源中,地址如下:
http://download.csdn.net/detail/zl3450341/4739970
相关文章推荐
- Jaxb解析xml(带命名空间)相关联的属性 "xsi:NamespaceSchemaLocation" 的前缀 "xsi" 未绑定。
- Attribute is missing the Android namespace prefix(属性是失踪的Android名称空间前缀)
- 如何在iOS应用中使用自定义字体
- 如何把ireport中自定义的主题应用到J2EE项目中简述
- iPhone开发:如何在iPhone应用中使用自定义字体
- 【WP 8.1开发】如何把自定义字体塞进应用里
- iOS如何添加应用自己的字体------lable设置自定义字体
- 如何编写和应用Java的自定义异常类
- 如何把自定义的字体添加到 iOS 应用中?
- 如何将自定义的方法应用到DataGrid的绑定列上
- 自定义应用如何影响客户信用额度
- 开发应用时如何利用C#自定义属性
- 如何自定义网站类别 - [MOSS 2007应用日记]
- 【数据绑定】如何在数据绑定表达式中应用自定义函数
- IOS中如何自定义web应用的图标
- golang如何自定义json序列化应用详解
- 如何使用Jquery自定义命名空间namespace
- 如何实现Docker应用的自定义弹性伸缩
- Tapestry 最新版5.1.0.5教程(十二):自定义前缀prefix
- 如何自定义Attribute class并将其应用到相应的class