从 .XSD 文件生成 Java 类...?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/686453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generate Java classes from .XSD files...?
提问by Keith Palmer Jr.
I have a gigantic QuickBooks SDK .XSD schema file which defines XML requests/responses that I can send/receive from QuickBooks.
我有一个巨大的 QuickBooks SDK .XSD 架构文件,它定义了我可以从 QuickBooks 发送/接收的 XML 请求/响应。
I'd like to be able to easily generate Java classes from these .XSD files, which I could then use to marshal XML to Java objects, and Java objects to XML.
我希望能够从这些 .XSD 文件轻松生成 Java 类,然后我可以使用这些类将 XML 编组为 Java 对象,并将 Java 对象编组为 XML。
Is there an easy way to do this...?
是否有捷径可寻...?
Ideally, it would not require any libraries external to the basic Java distro at run-time. But I'm flexible...
理想情况下,它在运行时不需要基本 Java 发行版之外的任何库。但我很灵活...
采纳答案by basszero
回答by TofuBeer
XMLBeanswill do it. Specifically the "scomp" command.
XMLBeans会做到这一点。特别是“scomp”命令。
EDIT: XMLBeans has been retired, check this stackoverflow postfor more info.
编辑:XMLBeans 已被淘汰,请查看此 stackoverflow 帖子以获取更多信息。
回答by Marc Novakowski
回答by Fran?ois Wauquier
The well-known JAXB
著名的JAXB
There is a maven pluginthat could do this for you at any build phase you want.
有一个Maven 插件可以在您想要的任何构建阶段为您执行此操作。
You could do this stuff in both ways: xsd <-> Java
你可以用两种方式做这些: xsd <-> Java
回答by Aries McRae
If you want to start coding Java to XML and XML to Java in less than 5 minutes, try Simple XML Serialization. Don't spend hours learning the JAXB API http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php
如果您想在 5 分钟内开始将 Java 编码为 XML 和 XML 编码为 Java,请尝试简单的 XML 序列化。不要花时间学习 JAXB API http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php
However, if you are really keen on learning JAXB, here's an excellent tutorial http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml
但是,如果您真的很想学习 JAXB,这里有一个很棒的教程 http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml
Contents of tutorial:
教程内容:
JAXB for simple Java-XML serialization
JAXB 用于简单的 Java-XML 序列化
There're a number of way to do XML serialization in Java. If you want fine-grained control over parsing and serialization you can go for SAX, DOM, or Stax for better performance. Yet, what I often want to do is a simple mapping between POJOs and XML. However, creating Java classes to do XML event parsing manually is not trivial. I recently found JAXB to be a quick and convenient Java-XML mapping or serialization.
在 Java 中有多种方法可以进行 XML 序列化。如果您想要对解析和序列化进行细粒度控制,您可以选择 SAX、DOM 或 Stax 以获得更好的性能。然而,我经常想做的是 POJO 和 XML 之间的简单映射。但是,创建 Java 类来手动进行 XML 事件解析并非易事。我最近发现 JAXB 是一种快速方便的 Java-XML 映射或序列化。
JAXB contains a lot of useful features, you can check out the reference implementation here. Kohsuke's Blogis also a good resource to learn more about JAXB. For this blog entry, I'll show you how to do a simple Java-XML serialization with JAXB.
JAXB 包含很多有用的功能,您可以在此处查看参考实现。Kohsuke 的博客也是了解有关 JAXB 的更多信息的好资源。在这篇博文中,我将向您展示如何使用 JAXB 进行简单的 Java-XML 序列化。
POJO to XML
POJO 到 XML
Let's say I have an Item Java object. I want to serialize an Item object to XML format. What I have to do first is to annotate this POJO with a few XML annotation from javax.xml.bind.annotation.* package. See code listing 1 for Item.java
假设我有一个 Item Java 对象。我想将 Item 对象序列化为 XML 格式。我首先要做的是用 javax.xml.bind.annotation.* 包中的一些 XML 注释来注释这个 POJO。请参阅 Item.java 的代码清单 1
From the code
从代码
@XmlRootElement(name="Item")
indicates that I want to be the root element.@XmlType(propOrder = {"name", "price"})
indicates the order that I want the element to be arranged in XML output.@XmlAttribute(name="id", ...)
indicates that id is an attribute to root element.@XmlElement(....)
indicates that I want price and name to be element within Item.
@XmlRootElement(name="Item")
表示我想成为根元素。@XmlType(propOrder = {"name", "price"})
指示我希望元素在 XML 输出中排列的顺序。@XmlAttribute(name="id", ...)
表示 id 是根元素的一个属性。@XmlElement(....)
表示我希望价格和名称成为项目中的元素。
My Item.java
is ready. I can then go ahead and create JAXB script for marshaling Item.
我Item.java
的准备好了。然后我可以继续创建用于封送项目的 JAXB 脚本。
//creating Item data object
Item item = new Item();
item.setId(2);
item.setName("Foo");
item.setPrice(200);
.....
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
//I want to save the output file to item.xml
marshaller.marshal(item, new FileWriter("item.xml"));
For complete code Listing please see Code Listing 2 main.java
. The output Code Listing 3 item.xml
file is created. It looks like this:
有关完整的代码清单,请参阅代码清单 2 main.java
。输出代码清单 3item.xml
文件已创建。它看起来像这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">
<ns1:itemName>Foo</ns1:itemName>
<ns1:price>200</ns1:price>
</ns1:item>
Easy right? You can alternatively channel the output XML as text String, Stream, Writer, ContentHandler, etc by simply change the parameter of the marshal(...) method like
容易吧?您也可以通过简单地更改 marshal(...) 方法的参数,将输出 XML 作为文本字符串、Stream、Writer、ContentHandler 等进行通道
...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
// save xml output to the OutputStream instance
marshaller.marshal(item, <java.io.OutputStream instance>);
...
JAXBContext context = JAXBContext.newInstance(item.getClass());
Marshaller marshaller = context.createMarshaller();
StringWriter sw = new StringWriter();
//save to StringWriter, you can then call sw.toString() to get java.lang.String
marshaller.marshal(item, sw);
XML to POJO
XML 到 POJO
Let's reverse the process. Assume that I now have a piece of XML string data and I want to turn it into Item.java object. XML data (Code listing 3) looks like
让我们颠倒这个过程。假设我现在有一段 XML 字符串数据,我想把它转换成 Item.java 对象。XML 数据(代码清单 3)看起来像
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item">
<ns1:itemName>Bar</ns1:itemName>
<ns1:price>80</ns1:price>
</ns1:item>
I can then unmarshal this xml code to Item object by
然后我可以将这个 xml 代码解组到 Item 对象
...
ByteArrayInputStream xmlContentBytes = new ByteArrayInputStream (xmlContent.getBytes());
JAXBContext context = JAXBContext.newInstance(Item.getClass());
Unmarshaller unmarshaller = context.createUnmarshaller();
//note: setting schema to null will turn validator off
unmarshaller.setSchema(null);
Object xmlObject = Item.getClass().cast(unmarshaller.unmarshal(xmlContentBytes));
return xmlObject;
...
For complete code Listing please see Code Listing 2 (main.java). The XML source can come in many forms both from Stream and file. The only difference, again, is the method parameter:
完整的代码清单请参见代码清单 2 (main.java)。XML 源可以来自 Stream 和文件的多种形式。同样,唯一的区别是方法参数:
...
unmarshaller.unmarshal(new File("Item.xml")); // reading from file
...
// inputStream is an instance of java.io.InputStream, reading from stream
unmarshaller.unmarshal(inputStream);
Validation with XML Schema
使用 XML 模式进行验证
Last thing I want to mention here is validating input XML with schema before unmarshalling to Java object. I create an XML schema file called item.xsd. For complete code Listing please see Code Listing 4 (Item.xsd). Now what I have to do is register this schema for validation.
我想在这里提到的最后一件事是在解组到 Java 对象之前使用模式验证输入 XML。我创建了一个名为 item.xsd 的 XML 模式文件。有关完整的代码清单,请参阅代码清单 4 (Item.xsd)。现在我要做的是注册这个架构进行验证。
...
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
.newSchema(new File("Item.xsd"));
unmarshaller.setSchema(schema); //register item.xsd shcema for validation
...
When I try to unmarshal XML data to POJO, if the input XML is not conformed to the schema, exception will be caught. For complete code Listing please see Code Listing 5 (invalid_item.xml).
当我尝试将 XML 数据解组到 POJO 时,如果输入的 XML 不符合架构,则会捕获异常。有关完整的代码清单,请参阅代码清单 5 (invalid_item.xml)。
javax.xml.bind.UnmarshalException
- with linked exception:
javax.xml.bind.JAXBException caught: null
[org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'item1' is
not a valid value for 'integer'.]
Here I change the 'id' attribute to string instead of integer.
在这里,我将 'id' 属性更改为字符串而不是整数。
If XML input is valid against the schema, the XML data will be unmarshalled to Item.java object successfully.
如果 XML 输入对模式有效,则 XML 数据将成功解组到 Item.java 对象。
回答by Niks
Isn't JAXB's XJC is a possible answer to this? I'm trying to achieve the same thing. Still in the "trying" phase though. Came across XJC, so thought of sharing.
JAXB 的 XJC 不是一个可能的答案吗?我正在努力实现同样的目标。但仍处于“尝试”阶段。遇到XJC,所以想到了分享。
回答by RAm
JAXB Limitation.
JAXB 限制。
I worked on JAXB, as per my opinion its a nice way of dealing with data between XML and Java objects. The Positive sides are its proven and better in performance and control over the data during runtime. With a good usage of built tools or scripts it will takes away lot of coding efforts.
我在 JAXB 上工作,据我所知,它是一种处理 XML 和 Java 对象之间数据的好方法。积极的一面是它在运行时的性能和对数据的控制方面得到了证明和更好。很好地使用内置工具或脚本,它将减少大量的编码工作。
I found the configuration part is not a straight away task, and spent hours in getting the development environment setup.
我发现配置部分不是一项直接的任务,并且花了几个小时来设置开发环境。
However I dropped this solution due to a silly limitation I faced. My XML Schema Definition ( XSD ) has a attribute/element with name "value" and that I have to use XSD as it is. This very little constraint forced the my binding step XJC failed with a Error "Property 'Value' already used."
然而,由于我面临的一个愚蠢的限制,我放弃了这个解决方案。我的 XML 架构定义 ( XSD ) 有一个名为“value”的属性/元素,我必须按原样使用 XSD。这个很小的约束迫使我的绑定步骤 XJC 失败,并出现错误“已使用的属性‘值’”。
This is due to the JAXB implementation, the binding process tries to create Java objects out of XSD by adding few attributes to each class and one of them being a value attribute. When it processed my XSD it complained that there is already a property with that name.
这是由于 JAXB 实现,绑定过程试图通过向每个类添加几个属性并且其中一个是值属性来从 XSD 创建 Java 对象。当它处理我的 XSD 时,它抱怨已经有一个具有该名称的属性。
回答by Nady
Talking about JAXB limitation, a solution when having the same name for different attributes is adding inline jaxb customizations to the xsd:
谈到 JAXB 限制,不同属性具有相同名称时的解决方案是向 xsd 添加内联 jaxb 自定义:
+
+
. . binding declarations . .
. . 绑定声明。.
or external customizations...
或外部定制...
You can see further informations on : http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html
您可以在以下位置查看更多信息:http: //jaxb.java.net/tutorial/section_5_3-Overriding-Names.html
回答by Ed Norris
To expand on the "use JAXB" comments above,
要扩展上面的“使用 JAXB”注释,
In Windows
"%java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd
在 Windows 中
"%java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd
e.g.,
"%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd
例如,
"%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd
Wait a bit, and if you had a well-formed XSD file, you will get some well-formed Java classes
稍等一下,如果您有一个格式良好的 XSD 文件,您将获得一些格式良好的 Java 类
回答by sree
Well best option is %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd
.
那么最好的选择是%java_home%\bin\xjc -p [your namespace] [xsd_file].xsd
。
I also have a question if we have an option to do reverse engineering here. if yes can we generate xsd from pojo class?
我也有一个问题,如果我们可以选择在这里进行逆向工程。如果是,我们可以从 pojo 类生成 xsd 吗?