How to get the minOccurs / maxOccurs values from t

2019-07-13 16:10发布

My application is calling a webservice and I have generated the Java classes from the WSDL/XSDs with the maven-jaxb2-plugin. The webservice calls worked fine for a while but recently I had a problem on marshalling an object into 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.]

The XSD part looks like this:

<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>

The generated class TheFooAndBarThing looks like this (Javadoc removed):

@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;
    }

}

It cost me some time and coffee to find out the real problem. My mistake was that I put more than 100 BarId elements in my list.

So here's my question:
How can I get the maxOccurs/minOccurs value from the XSD into my Java code so that I can use it as a max/min value while building my list of elements?

2条回答
Luminary・发光体
2楼-- · 2019-07-13 16:55

Short answer: there is no easy way.

Schema-derived classes have no reference to the original schema anymore. Even if you use something as XSOM or whatever to parse the original schema, you will not be able to find corresponding XML Schema constructs to check.

The best way to address the issue would be writing a custom XJC plugin (I wrote quite a few of them).

When XJC compiles the schmema it first creates a model, then a so-called outline (pre-rendered code) and then renders the code. The model still has information about the original XML Schema constructs, so you can find all the relevant min/maxOccurs information there.

The problem is just that you don't always have 1:1 mapping between schema constructs and properties of schema-derived classes. Sometimes several elements are mapped onto one property. There's a huge number of exceptions and special cases. You can get it working for the straightforward cases, though. Anyway, the task is not easy.

查看更多
地球回转人心会变
3楼-- · 2019-07-13 17:01

Use could try JAXB-Facets.

Here is an example of setting specific values for minoccurs and maxoccurs:

@MinOccurs(value = 0)
@MaxOccurs(value = 100)
private List<String> test;
查看更多
登录 后发表回答