我有一个巨大的QuickBooks SDK .XSD模式文件,该文件定义了我可以从QuickBooks发送/接收的XML请求/响应。
我希望能够轻松地从这些.XSD文件生成Java类,然后将其用于将XML编组为Java对象,然后将Java对象编组为XML。
是否有捷径可寻...?
理想情况下,它在运行时不需要基本Java发行版外部的任何库。但是我很灵活
我有一个巨大的QuickBooks SDK .XSD模式文件,该文件定义了我可以从QuickBooks发送/接收的XML请求/响应。
我希望能够轻松地从这些.XSD文件生成Java类,然后将其用于将XML编组为Java对象,然后将Java对象编组为XML。
是否有捷径可寻...?
理想情况下,它在运行时不需要基本Java发行版外部的任何库。但是我很灵活
Answers:
JAXB确实可以满足您的需求。从1.6开始,它内置在JRE / JDK中
为了扩展上面的“ use 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的Blog也是了解JAXB的好资源。对于此博客文章,我将向您展示如何使用JAXB进行简单的Java-XML序列化。
POJO到XML
假设我有一个Item Java对象。我想将Item对象序列化为XML格式。我首先要做的是用来自javax.xml.bind.annotation。*包的一些XML注释对POJO进行注释。请参阅代码清单1中的Item.java
从代码
@XmlRootElement(name="Item")
表示我想成为根元素。@XmlType(propOrder = {"name", "price"})
指示我希望元素在XML输出中排列的顺序。@XmlAttribute(name="id", ...)
表示id是根元素的属性。@XmlElement(....)
表示我希望价格和名称成为Item中的元素。我Item.java
准备好了 然后,我可以继续创建用于封送Item的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转换为文本String,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和file两种形式。同样,唯一的区别是方法参数:
...
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:-
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>
</plugins>
</pluginManagement>
</build>
</project>
只需将您的xsd文件放在“ src / main / webapp / schemas /”下,maven就会在编译时找到它们。
希望这会对您有所帮助,有关更多信息,请访问http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html
希望它会有所帮助:)
No XSD files found. Please check your plugin configuration.
XMLBeans可以做到。特别是“ scomp”命令。
编辑:XMLBeans已经淘汰,请查看此stackoverflow帖子以获取更多信息。
如果您不介意使用外部库,那么我过去曾使用Castor进行此操作。
JAXB限制。
我认为JAXB是一种处理XML和Java对象之间的数据的好方法。积极的一面是其经过验证的性能,并且在运行时可以更好地控制数据。充分利用内置工具或脚本,将节省大量编码工作。
我发现配置部分不是一项直接的任务,并且花费了数小时来进行开发环境的设置。
但是,由于遇到愚蠢的限制,我放弃了此解决方案。我的XML模式定义(XSD)具有名称为“值”的属性/元素,我必须原样使用XSD。这个很小的约束迫使我的绑定步骤XJC失败,并显示错误“已使用属性'值'”。
这是由于JAXB的实现,绑定过程试图通过在XSD之外创建Java对象,方法是为每个类添加少量属性,其中一个属性为value属性。当它处理我的XSD时,它抱怨已经有一个具有该名称的属性。
在谈论JAXB限制时,一种解决方案,当对不同属性使用相同的名称时,是向xsd添加内联jaxb定制:
+
。。具有约束力的声明。。
或外部自定义...
您可以在以下位置查看更多信息:http : //jaxb.java.net/tutorial/section_5_3-Overriding-Names.html