繁体   English   中英

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

[英]Generate Java classes from .XSD files…?

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

我希望能够从这些 .XSD 文件轻松生成 Java 类,然后我可以使用这些类将 XML 编组为 Java 对象,并将 Java 对象编组为 XML。

是否有捷径可寻...?

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

JAXB完全符合您的要求。 从 1.6 开始,它内置于 JRE/JDK 中

要扩展上面的“使用 JAXB”注释,

在 Windows "%java_home%\\bin\\xjc" -p [your namespace] [xsd_file].xsd

例如, "%java_home%\\bin\\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

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

如果您想在 5 分钟内开始将 Java 编码为 XML 和 XML 编码为 Java,请尝试简单的 XML 序列化。 不要花时间学习 JAXB API http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

但是,如果您真的很想学习 JAXB,这里有一个很棒的教程http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

教程内容:

JAXB 用于简单的 Java-XML 序列化

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

JAXB 包含很多有用的功能,您可以在此处查看参考实现。 Kohsuke 的博客也是了解有关 JAXB 的更多信息的好资源。 在这篇博文中,我将向您展示如何使用 JAXB 进行简单的 Java-XML 序列化。

POJO 到 XML

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

从代码

  • @XmlRootElement(name="Item")表示我想成为根元素。
  • @XmlType(propOrder = {"name", "price"})表示我希望元素在 XML 输出中排列的顺序。
  • @XmlAttribute(name="id", ...)表示 id 是根元素的属性。
  • @XmlElement(....)表示我希望 price 和 name 成为 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"));

有关完整的代码清单,请参阅代码清单 2 main.java 创建了输出代码清单 3 item.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>

容易吧? 您也可以通过简单地更改 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 到 POJO

让我们颠倒这个过程。 假设我现在有一段 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>

然后我可以将这个 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;
...

完整的代码清单请参见代码清单 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);

使用 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)。

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'.]

在这里,我将 'id' 属性更改为字符串而不是整数。

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

使用 Eclipse IDE:-

  1. 将 xsd 复制到新/现有项目中。
  2. 确保您的类路径中有 JAXB 所需的 JAR。 你可以在这里下载一个。
  3. 右键单击 XSD 文件 -> 生成 -> JAXB 类。

最简单的方法是使用命令行。 只需输入 .xsd 文件的目录:

xjc myFile.xsd.

因此,java 将生成所有 Pojo。

XMLBeans会做到这一点。 特别是“scomp”命令。

编辑:XMLBeans 已被淘汰,请查看此 stackoverflow 帖子以获取更多信息。

Maven 可用于此目的,您需要添加一些依赖项并清理您的应用程序。 您将在目标文件夹中自动创建所有类。

只需将它们从目标复制到所需的位置,这是我用来从xsd文件创建分类的pom.xml

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxb2-maven-plugin</artifactId>

    <executions>
        <execution>
            <goals>
                <goal>xjc</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemaDirectory>src/main/webapp/schemas/</schemaDirectory>
    </configuration>
</plugin>

只需将您的 xsd 文件放在src/main/webapp/schemas/ ,maven 就会在编译时找到它们。

希望这对你有帮助,更多信息可以在http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html找到

最好的选择是%java_home%\\bin\\xjc -p [your namespace] [xsd_file].xsd

我也有一个问题,如果我们可以选择在这里进行逆向工程。 如果是,我们可以从 pojo 类生成 xsd 吗?

如果您不介意使用外部库,我过去曾使用Castor来执行此操作。

JAXB 限制。

我在 JAXB 上工作,据我所知,它是一种处理 XML 和 Java 对象之间数据的好方法。 积极的一面是它在运行时的性能和对数据的控制方面得到了证明和更好。 很好地使用内置工具或脚本,它将减少大量的编码工作。

我发现配置部分不是一项直接的任务,并且花了几个小时来设置开发环境。

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

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

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

著名的JAXB

有一个Maven 插件可以在您想要的任何构建阶段为您执行此操作。

你可以用两种方式做这些: xsd <-> Java

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

+

. . 绑定声明。 .

或外部定制...

您可以在以下位置查看更多信息:http ://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM