我的应用程序正在调用webservice,我已经使用maven-jaxb2-plugin从WSDL / XSD生成了Java类。 webservice调用工作正常一段时间,但最近我在将对象编组为XML时遇到了问题:
[org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'ns1:TheFooAndBarThing'.
No child element '{"http://www.myschemanamespace.xyz/v1":BarId}' is expected at this point.]
XSD部分如下所示:
<xs:complexType name="TheFooAndBarThing">
<xs:sequence>
<xs:element name="FooId" minOccurs="1" maxOccurs="1" type="nx:FooIdType"/>
<xs:element name="BarId" minOccurs="1" maxOccurs="100" type="nx:BarIdType"/>
</xs:sequence>
</xs:complexType>
生成的类TheFooAndBarThing
看起来像这样(删除了Javadoc):
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TheFooAndBarThing", propOrder = {
"fooId",
"barId"
})
public class TheFooAndBarThing {
@XmlElement(name = "FooId", required = true)
protected String fooId;
@XmlElement(name = "BarId", required = true)
protected List<String> barId;
public String getFooId() {
return fooId;
}
public void setFooId(String value) {
this.fooId = value;
}
public List<String> getBarId() {
if (barId == null) {
barId = new ArrayList<String>();
}
return this.barId;
}
}
我花了一些时间和咖啡来找出真正的问题。我的错误是我在列表中放了100多个BarId
个元素。
所以这是我的问题:
如何从XSD获取maxOccurs / minOccurs值到我的Java代码中,以便在构建元素列表时将其用作最大/最小值?
答案 0 :(得分:3)
简短的回答:没有简单的方法。
模式派生类不再引用原始模式。即使您使用XSOM或其他东西来解析原始模式,您也无法找到相应的XML Schema结构来进行检查。
解决问题的最佳方法是撰写自定义XJC plugin(我写了quite a few of them)。
当XJC编译schmema时,它首先创建一个模型,然后是所谓的轮廓(预渲染代码),然后渲染代码。该模型仍然包含有关原始XML Schema结构的信息,因此您可以在那里找到所有相关的min / maxOccurs信息。
问题在于,您不必总是在架构构造和架构派生类的属性之间进行1:1映射。有时几个元素映射到一个属性。有大量例外和特殊情况。不过,你可以让它适用于直截了当的案例。无论如何,这项任务并不容易。
答案 1 :(得分:1)
使用可以尝试JAXB-Facets。
以下是为 minoccurs 和 maxoccurs 设置特定值的示例:
@MinOccurs(value = 0)
@MaxOccurs(value = 100)
private List<String> test;