从.XSD文件生成Java类。。。?

从.XSD文件生成Java类。。。?,java,xml,xsd,Java,Xml,Xsd,我有一个巨大的QuickBooks SDK.XSD模式文件,它定义了可以从QuickBooks发送/接收的XML请求/响应 我希望能够轻松地从这些.XSD文件生成Java类,然后使用这些文件将XML封送到Java对象,并将Java对象封送到XML 有没有一个简单的方法来做到这一点 理想情况下,它在运行时不需要基本Java发行版之外的任何库。但我很灵活 就可以了。特别是“scomp”命令 编辑:XMLBeans已经发布,请查看更多信息。完全按照您的要求执行。从1.6开始,它就内置在JRE/JDK中

我有一个巨大的QuickBooks SDK.XSD模式文件,它定义了可以从QuickBooks发送/接收的XML请求/响应

我希望能够轻松地从这些.XSD文件生成Java类,然后使用这些文件将XML封送到Java对象,并将Java对象封送到XML

有没有一个简单的方法来做到这一点

理想情况下,它在运行时不需要基本Java发行版之外的任何库。但我很灵活

就可以了。特别是“scomp”命令


编辑:XMLBeans已经发布,请查看更多信息。

完全按照您的要求执行。从1.6开始,它就内置在JRE/JDK中。如果您不介意使用外部库,我过去就经常这样做

在您想要的任何构建阶段,都有一个可以为您做到这一点的工具


您可以用两种方法来完成这项工作:xsd-Java

如果您想在不到5分钟的时间内开始将Java编码为XML和XML编码为Java,请尝试简单的XML序列化。不要花费数小时学习JAXB API

然而,如果您真的很想学习JAXB,这里有一个非常好的教程

教程内容:

用于简单Java XML序列化的JAXB

在Java中有很多方法可以实现XML序列化。如果您想要对解析和序列化进行细粒度控制,可以使用SAX、DOM或Stax来获得更好的性能。然而,我经常想做的是POJO和XML之间的简单映射。然而,创建Java类来手动进行XML事件解析并非易事。我最近发现JAXB是一种快速方便的JavaXML映射或序列化

JAXB包含许多有用的特性,您可以在这里查看参考实现。也是了解更多关于JAXB的好资源。在本博客中,我将向您展示如何使用JAXB进行简单的Java XML序列化

POJO到XML

假设我有一个项目Java对象。我想将项对象序列化为XML格式。我首先要做的是用javax.XML.bind.annotation.*包中的一些XML注释来注释这个POJO。参见Item.java的代码清单1

从代码

  • @XmlRootElement(name=“Item”)
    表示我想成为根元素
  • @XmlType(propOrder={“name”,“price”})
    指示我希望元素在XML输出中排列的顺序
  • @xmltattribute(name=“id”,…)
    表示id是根元素的属性
  • @xmlement(..)
    表示我希望价格和名称是项目中的元素
我的
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"));
有关完整的代码清单,请参见代码清单2
main.java
。创建了输出代码清单3item.xml文件。看起来是这样的:


福
200
简单,对吗?您也可以将输出XML作为文本字符串、流、编写器、ContentHandler等进行通道传输,只需更改marshal(…)方法的参数,如

...
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);
有关完整的代码清单,请参见代码清单2(main.java)。XML源可以以多种形式来自流和文件。唯一的区别还是方法参数:

...
unmarshaller.unmarshal(new File("Item.xml")); // reading from file
...
// inputStream is an instance of java.io.InputStream, reading from stream
unmarshaller.unmarshal(inputStream);
使用XML模式进行验证

我想在这里提到的最后一件事是在解组到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
...
当我尝试将XML数据解组到POJO时,如果输入XML与模式不一致,将捕获异常。有关完整的代码清单,请参见代码清单5(invalid_item.xml)

这里我将'id'属性改为string而不是integer


如果XML输入对模式有效,XML数据将被成功地解组到Item.java对象。

JAXB的XJC不是一个可能的答案吗?我正在努力实现同样的目标。但仍处于“尝试”阶段。遇到XJC,所以想到了共享。

JAXB限制

我研究过JAXB,我认为这是处理XML和Java对象之间数据的一种很好的方法。积极的一面是它在运行时的性能和对数据的控制方面得到了验证和改进。如果能够很好地使用构建工具或脚本,那么就可以省去大量的编码工作

我发现配置部分不是一项简单的任务,我花了数小时来设置开发环境

然而,由于我面临一个愚蠢的限制,我放弃了这个解决方案。我的XML模式定义(XSD)有一个名为“value”的属性/元素,我必须按原样使用XSD。这个很小的约束迫使我的绑定步骤XJC失败,错误为“Property'Value'已经使用”


这是由于JAXB实现的缘故,绑定过程试图通过向每个类添加几个属性(其中一个是值属性)来从XSD创建Java对象。当它处理我的XSD时,它抱怨已经有一个具有该名称的属性

谈到JAXB限制,当不同属性具有相同名称时,一个解决方案是向xsd添加内联JAXB定制:

+

. . 有约束力的声明 . .

或外部自定义

您可以查看以下方面的更多信息: 要扩展上面的“使用JAXB”注释

在窗户里
%java_home%\bin\xjc“-p[您的命名空间][xsd_文件].xsd

e、 g。,
%java\u home%\bin\xjc“-p com.mycompany.quickbooks.obj quickbooks.xsd


稍等一下,如果您有一个格式良好的XSD文件,您将得到一些格式良好的Java类

最好的选择是
%Java\u home%\bin\xjc-p[your namespa
...
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
.newSchema(new File("Item.xsd"));
unmarshaller.setSchema(schema); //register item.xsd shcema for validation
...
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'.]
xjc myFile.xsd.