使用XJC的XML模式到Java类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用XJC的XML模式到Java类相关的知识,希望对你有一定的参考价值。
我正在使用xjc从XML模式生成Java类,以下是XSD的摘录。
<xs:element name="NameInfo">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element ref="UnstructuredName"/> <!-- This line -->
<xs:sequence>
<xs:element ref="StructuredName"/>
<xs:element ref="UnstructuredName" minOccurs="0"/> <!-- and this line! -->
</xs:sequence>
</xs:choice>
<xs:element ref="SomethingElse" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
在大多数情况下,生成的类很好,但对于上面的块,我会得到类似的东西:
public List<Object> getContent() {
if (content == null) {
content = new ArrayList<Object>();
}
return this.content;
}
以上评论如下:
* You are getting this "catch-all" property because of the following reason:
* The field name "UnstructuredName" is used by two different parts of a schema. See:
* line XXXX of file:FILE.xsd
* line XXXX of file:FILE.xsd
* To get rid of this property, apply a property customization to one
* of both of the following declarations to change their names:
* Gets the value of the content property.
我在两条线的末尾发表评论。
目前,我认为改变架构并不容易,因为这是由供应商决定的,我不想走这条路(如果可能的话),因为它会减慢进度。
我搜索并找到this page,外部定制我想做什么?我一直在使用生成的类,所以我不完全熟悉生成这些类的过程。 “财产定制”的一个简单例子会很棒!只要仍然可以使用模式,生成Java类的替代方法就可以了。
编辑:我应该澄清,两个UnstructuredName
确实是相同的元素。
这里的基本问题是你有一个由<xs:sequence>
组成的<xs:choice>
,它在Java中翻译为“List
of things”。 Java的类型结构不够灵活,无法更好地表示这一点。
绑定自定义可能对您有所帮助,但在这种情况下,我怀疑没有,因为我看不到更好的方式来表示此信息。
我过去使用的另一种技术是首先通过一个简单的XSLT转换传递模式,将组件重新安排到更友好的JAXB,同时仍然允许文档在现实中具有相同的结构。这样,您可以“更改”架构而无需更改原始架构。
您还可以使用名为<xjc:simple />
的绑定自定义:
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:version="2.0">
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
</jxb:bindings>
但请注意,这是特定于供应商的(虽然使用了除XJC以外的其他东西;))
更多信息here
我有同样的问题。我切换到xmlbeans和轴。 XMLBeans可以毫无问题地编译您的架构,而且没有头痛。 JaxB无法处理这个问题。为了使JaxB处理这个问题,您可以稍微更改一下架构。
<xs:sequence>
<xs:choice>
<!-- changed the following line -->
<xs:element name="UnstructuredTop" type="UnstructuredName"/>
<!-- end of change -->
<xs:sequence>
<xs:element ref="StructuredName"/>
<xs:element ref="UnstructuredName" minOccurs="0"/>
</xs:sequence>
</xs:choice>
<xs:element ref="SomethingElse" minOccurs="0"/>
</xs:sequence>
然后JaxB将区分这两者而不是翻出来。
但是你的情况就像我的情况。改变架构是不可能的。所以我选择了xmlBeans和axis(sux)。
我创建了一个包装类来解决问题:
List<JAXBElement<?>> contentList = address.getContent();
if (contentList != null && contentList.size() > 0) {
Address4JaxbMula address4JaxbMula = new Address4JaxbMula(contentList);
... }
...
public static class Address4JaxbMula {
public CountryCodeType countryCode;
public AddressFixType addressFix;
public String addressFree;
public Address4JaxbMula(List<JAXBElement<?>> contentList) {
if (contentList != null && contentList.size() > 0) {
for (JAXBElement<?> content : contentList) {
Object value = content.getValue();
if (value.getClass().isAssignableFrom(CountryCodeType.class)) {
countryCode = (CountryCodeType) content.getValue();
} else if (value.getClass().isAssignableFrom(AddressFixType.class)) {
addressFix = (AddressFixType) content.getValue();
} else {
addressFree = (String) value;
}
}
}
}
}
以上是关于使用XJC的XML模式到Java类的主要内容,如果未能解决你的问题,请参考以下文章
JAXB XJC 代码生成 - Marshaller 生成的 xml 中缺少“schemaLocation”
JDK Tools - xjc: 将 XML Schema 编译成 Java 类
如何修改Java 9的ANT build.xml中的xjc块?