3

我的应用程序正在调用 Web 服务,并且我已经使用 maven-jaxb2-plugin 从 WSDL/XSD 生成了 Java 类。网络服务调用在一段时间内运行良好,但最近我在将对象编组为 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;
    }

}

我花了一些时间和咖啡来找出真正的问题。我的错误是我BarId在列表中放了 100 多个元素。

所以这是我的问题:
如何将 XSD 中的 maxOccurs/minOccurs 值获取到我的 Java 代码中,以便在构建元素列表时将其用作最大/最小值?

4

2 回答 2

3

简短的回答:没有简单的方法。

模式派生类不再引用原始模式。即使您使用 XSOM 或其他任何东西来解析原始模式,您也无法找到相应的 XML 模式结构来检查。

解决这个问题的最好方法是编写一个自定义的XJC 插件(我写了很多)。

当 XJC 编译 schmema 时,它首先创建一个模型,然后是一个所谓的大纲(预渲染代码),然后再渲染代码。该模型仍然包含有关原始 XML Schema 结构的信息,因此您可以在那里找到所有相关的 min/maxOccurs 信息。

问题在于您并不总是在模式构造和模式派生类的属性之间拥有 1:1 的映射。有时多个元素映射到一个属性。有大量的例外和特殊情况。不过,您可以让它适用于简单的案例。无论如何,任务并不容易。

于 2014-03-19T20:20:51.790 回答
1

使用可以尝试JAXB-Facets

下面是为minoccursmaxoccurs设置特定值的示例:

@MinOccurs(value = 0)
@MaxOccurs(value = 100)
private List<String> test;
于 2015-08-07T09:16:34.287 回答