我有一个巨大的QuickBooks SDK .XSD架构文件,它定义了我可以从QuickBooks发送/接收的XML请求/响应。
我希望能够从这些.XSD文件轻松生成Java类,然后我可以使用它来将XML编组为Java对象,将Java对象编组为XML。
有一种简单的方法可以做到这一点......?
理想情况下,在运行时不需要基本Java发行版外部的任何库。但我很灵活......
答案 0 :(得分:118)
JAXB完全符合您的要求。它内置于JRE / JDK,从1.6开始。
答案 1 :(得分:116)
要扩展上面的“使用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类
答案 2 :(得分:37)
如果您想在不到5分钟的时间内开始将Java编码为XML并将XML编写为Java,请尝试使用Simple XML Serialization。不要花费数小时学习JAXB API http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php
但是,如果你真的热衷于学习JAXB,这是一个很好的教程 http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml
教程内容:
简单Java-XML序列化的JAXB
在Java中有很多方法可以进行XML序列化。如果您想要对解析和序列化进行细粒度控制,可以使用SAX,DOM或Stax来获得更好的性能。然而,我经常想要做的是POJO和XML之间的简单映射。但是,创建Java类以手动执行XML事件解析并非易事。我最近发现JAXB是一种快速方便的Java-XML映射或序列化。
JAXB包含许多有用的功能,您可以在这里查看参考实现。 Kohsuke's Blog也是了解JAXB的更多资源。对于本博客文章,我将向您展示如何使用JAXB进行简单的Java-XML序列化。
POJO to 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(....)
表示我希望价格和名称成为Item中的元素。我的Item.java
准备好了。然后我可以继续创建JAXB脚本来编组Item。
//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对象。
答案 3 :(得分:29)
使用Eclipse IDE: -
答案 4 :(得分:16)
最简单的方法是使用命令行。只需输入.xsd文件的目录:
xjc myFile.xsd.
因此,java将生成所有Pojos。
答案 5 :(得分:14)
XMLBeans会这样做。特别是“scomp”命令。
编辑:XMLBeans已retired,请查看this stackoverflow post了解详情。
答案 6 :(得分:12)
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
找到更多信息希望它会有所帮助:)
答案 7 :(得分:7)
如果您不介意使用外部库,我过去曾使用Castor来执行此操作。
答案 8 :(得分:7)
最好的选择是%java_home%\bin\xjc -p [your namespace] [xsd_file].xsd
。
如果我们可以选择在这里进行逆向工程,我也有一个问题。如果是,我们可以从pojo类生成xsd吗?
答案 9 :(得分:5)
JAXB限制。
我在JAXB上工作,根据我的观点,它是处理XML和Java对象之间数据的好方法。积极的一面是经过验证的,在运行期间性能和对数据的控制更好。通过很好地使用构建的工具或脚本,它将消耗大量的编码工作。
我发现配置部分不是一个直接的任务,花了几个小时来设置开发环境。
但是由于我面临的愚蠢限制,我放弃了这个解决方案。我的XML模式定义(XSD)有一个名为“value”的属性/元素,我必须按原样使用XSD。这个非常小的约束迫使我的绑定步骤XJC失败,错误“属性'值'已经使用过。”
这是由于JAXB实现,绑定过程尝试通过向每个类添加少量属性来创建XSD之外的Java对象,其中一个属性是值属性。当它处理我的XSD时,它抱怨已经有一个具有该名称的属性。
答案 10 :(得分:4)
JAXB的XJC不是可能的答案吗?我正在努力实现同样的目标。尽管如此,仍处于“尝试”阶段。来到XJC,想到分享。
答案 11 :(得分:2)
答案 12 :(得分:1)
谈到JAXB限制,对不同属性使用相同名称的解决方案是向xsd添加内联jaxb自定义:
+
。 。 绑定声明 。 。
或外部自定义......
您可以在以下方面看到更多信息: http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html